2013-12-19 4 views
2

Я изучаю EJB и написал пример программы, используя GlassFish 4, но по какой-то причине он не работает.Simple Singleton EJB Пример

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(); 
    } 

} 

Нежелательная Выход:

Количество: 1

NullPointer пойманы

ответ

4

Прежде всего, вы начинаете свой EJB в стандартном JVM. Но EJB может жить только внутри EJB Container. Когда вы запускаете приложение только с помощью основного метода, все аннотации EJB игнорируются. Для проверки вашего приложения вам нужен сервер приложений, например, Glassfish или JBoss.
Вот ваш улучшенный пример:

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> 
+0

Я попробовал его в Tomcat 7 и GlassFish 4 как скриптовый сценарий JSP вместо основного класса, но у меня получилось то же самое. .. – ThreaT

+0

Показать код сценария. Если вы сделали это так же, как здесь, новый Trigger1(), значит, это неправильно.Объект, созданный вами, создает внешний контейнер EJB, а аннотации EJB игнорируются. Ваш объект Trigger1 должен быть создан контейнером EJB. – Fireworks

+0

Код обновлен, все еще получая исключение NullPointerException через JSP – ThreaT

0

Я думаю, что вы можете вводить EJB только в другой Session Beans или Message-Driven Beans. В своем коде вы пытаетесь ввести их в простые классы Java. Вы можете ссылаться на них в классах Java с помощью JNDI lookup.

Если ваши классы Trigger1 и Trigger2 не в том же (Java EE) приложения, как ваш Utility Bean, то вам нужно Remote доступ и, следовательно, вид интерфейса. Затем вы можете получить доступ к бобу Singleton следующим образом: https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project.

Если Trigger1 и Trigger2 классы находятся в одной и той же apllication, как ваш Utility Bean, то локальный не вид интерфейса, который вы уже предоставляют не достаточно. Вы можете получить доступ к бонусу Singleton до Injection так же, как и вы, но вы должны сделать свои классы Session Бобы (предпочтительно без гражданства). Затем вы должны снова пройти через JNDI lookup, чтобы получить доступ к ним из основного метода.

+0

могли бы вы показать мне, что код для ча nge, так как я до сих пор довольно новичок во всей этой терминологии, когда дело доходит до ее практического применения. – ThreaT