Reputation:
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
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
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