2013-12-19 270 views
2

我正在學習EJB並編寫了一個使用GlassFish 4的示例程序,但由於某些原因,它無法正常工作。簡單單例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

空指針抓住

回答

4

首先,你在標準JVM中啓動你的EJB。但是EJB只能存在於EJB容器中。當您使用main方法啓動應用程序時,所有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 scriptlet而不是主要類嘗試了它,但我得到了同樣的結果。 .. – ThreaT

+0

顯示scriplet代碼。如果你這樣做新的Trigger1(),所以它是錯誤的。由您自己創建的對象會創建外部EJB容器並忽略EJB註釋。您的Trigger1對象必須由EJB容器創建。 – Fireworks

+0

代碼已更新,仍然通過JSP獲得NullPointerException – ThreaT

0

我想你只能在其他Session BeansMessage-Driven Beans注入EJB。在你的代碼中,你嘗試將它們注入簡單的java類。你可以在JNDI lookup的java類中引用它們。

如果你的類Trigger1Trigger2不在同一(Java EE)應用程序作爲Utility的Bean,那麼你需要Remote訪問,因此接口視圖。然後,您可以按如下方式訪問Singleton Bean:https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project

如果您的Trigger1Trigger2類與您的Utility Bean具有相同的屬性,那麼您已經提供的本地無界面視圖就足夠了。像你一樣,你可以通過Injection訪問Singleton Bean,但是你必須讓你的類Session Beans(最好是無狀態的)。然後你應該再次通過JNDI lookup從你的主要方法訪問它們。

+0

您能不能告訴我什麼代碼去查因爲我對這個術語還是比較陌生的,所以我把它付諸實踐 – ThreaT