user1191027
user1191027

Reputation:

Simple Singleton EJB Example

I'm learning EJB's and have written an example program using GlassFish 4 but for some reason it's not working.

index.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ page import="javax.ejb.EJB" %>
<%@ page import="ejbtest.utility.Utility" %>
<%@ page import="ejbtest.action.*" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>EJB Test</title>
    </head>
    <body>
        <%
            try {
                Utility utility = new Utility();
                out.println("count: " + utility.getCount() + "<br/><br/>");
                Trigger1 trigger1 = new Trigger1();
                out.println("trigger1 count: " + trigger1.getTriggerCount());
            } catch (NullPointerException npe) {
                out.println("Nullpointer caught");
            }
        %>
    </body>
</html>

Utility.java:

package ejbtest.utility;

import javax.ejb.Singleton;
import javax.ejb.Startup;

@Startup
@Singleton
public class Utility {

    int count;

    public Utility() throws NullPointerException {
        count = 0;
        count++;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

Trigger1.java:

package ejbtest.action;

import ejbtest.utility.Utility;
import javax.faces.bean.ApplicationScoped;
import javax.inject.Inject;

@ApplicationScoped
public class Trigger1 {

    @Inject
    Utility utility;

    public Integer getTriggerCount() {
        return utility.getCount();
    }

}

Undesired Output:

count: 1

Nullpointer caught

Upvotes: 2

Views: 7249

Answers (2)

Fireworks
Fireworks

Reputation: 515

First of all you start yours EJB in standart JVM. But EJB can live only inside EJB Container. When you start your application just using main method all EJB annotations ignored. You need application server like glassfish or JBoss to test your application.
Here your improved example:

Trigger1.java

package ejbtest.action;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import ejbtest.utility.Utility;

@Stateless
public class Trigger1 {

    @EJB
    private Utility utility;

    public Integer getTriggerCount() {
        return utility.getCount();
    }
}

Utility.java

package ejbtest.utility;

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;

@Singleton
public class Utility {
    int count = 0;

    @PostConstruct
    public void init() {
        count++;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

index.jsp

<%@page import="ejbtest.action.Trigger1"%>
<%@page import="ejbtest.utility.Utility"%>
<%@page import="javax.naming.InitialContext"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>EJB Test</title>
    </head>
    <body>
    <%
        InitialContext ic = new InitialContext();
        Utility utility = (Utility) ic.lookup("java:module/Utility");
        out.println("count: " + utility.getCount() + "<br/><br/>");
        Trigger1 trigger1 = (Trigger1) ic.lookup("java:module/Trigger1");
        out.println("trigger1 count: " + trigger1.getTriggerCount());
    %>
    </body>
</html>

Upvotes: 4

arjacsoh
arjacsoh

Reputation: 9232

I think you can inject EJB only in other Session Beans or Message-Driven Beans. In your Code you try to inject them into simple java classes. You can reference them in java classes with JNDI lookup.

If your classes Trigger1 and Trigger2 are not in the same (Java EE) application as your Utility Bean , then you need Remote access and therefore an interface view. You can then access the Singleton Bean as follows: https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project.

If your Trigger1 and Trigger2 classes are in the same apllication as your Utility Bean, then the Local no interface view which you already provide is sufficient. You can access the Singleton Bean through Injection as you do, but you have to make your classes Session Beans (preferably Stateless). Then you should again through JNDI lookup to access them from your main method.

Upvotes: 1

Related Questions