2011-01-21 83 views
3

有一個麻煩的問題,我找不到任何統一的方法來解決它在互聯網上。我正在開發一個使用Java EE,Glassfish和Netbeans的企業應用程序。從另一個Glassfish實例訪問一個無狀態的EJB

我有兩個Glassfish設置的實例,我正在構建一個企業應用程序拆分這兩個實例。我有一個網頁(有幾個JSP和幾個HttpServlet)在一個Glassfish實例上運行。另一方面,我想實現應用程序的業務邏輯。也就是說,我有一些Java Entity Beans,並且還有一個使用這些實體bean的遠程接口的EJB。

我的目標是能夠從glassfish的第一個實例的servlet遠程訪問EJB。我遵循了this post中的說明,但未成功。我提供的代碼片段,以獲得更具體的...

在Glassfish,EJB遠程接口的一個實例:

@Remote 
public interface MyEjbRemote { 
    //... 
} 

和無狀態的bean:

@Stateless(name="ejb/MyEjb") 
public class MyEjb implements MyEjbRemote { 
    //... 
} 

在其他實例:

public class MyServlet extends HttpServlet { 

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
     MyEjbRemote = lookupEjb(); 
     //... 
    } 

    private MyEjbRemote lookupEjb() { 
     Properties props = new Properties(); 
     props.setProperty("java.naming.factory.initial", 
      "com.sun.enterprise.naming.SerialInitContextFactory"); 
     props.setProperty("java.naming.factory.url.pkgs", 
      "com.sun.enterprise.naming"); 
     props.setProperty("java.naming.factory.state", 
      "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl"); 

     //default: localhost 
     props.setProperty("org.omg.CORBA.ORBInitialHost", 
      "localhost"); 
     //default: 3700 
     props.setProperty("org.omg.CORBA.ORBInitialPort", "2037"); 

     InitialContext ic = new InitialContext(props); 
     return (MyEjbRemote) ic.lookup("ejb/MyEjb"); 
    } 
} 

不幸的是,當我啓動我的網站,並嘗試查找遠程ej b我收到以下例外情況:

WARNING: Internal error flushing the buffer in release() 
WARNING: StandardWrapperValve[jsp]: PWC1406: Servlet.service() for servlet jsp threw exception 
java.io.IOException: Stream closed 
    at org.apache.jasper.runtime.JspWriterImpl.ensureOpen(JspWriterImpl.java:277) 
    at org.apache.jasper.runtime.JspWriterImpl.clearBuffer(JspWriterImpl.java:222) 
    at org.apache.jsp.home_jsp._jspService(home_jsp.java from :76) 
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) 
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:406) 
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:483) 
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:373) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641) 
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97) 
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165) 
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791) 
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693) 
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954) 
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170) 
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) 
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76) 
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) 
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) 
    at com.sun.grizzly.ContextTask.run(ContextTask.java:69) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309) 
    at java.lang.Thread.run(Thread.java:662) 

我的實現中缺少什麼?任何建議/想法?請詢問我的問題描述是否有遺漏,這是我第一次在本網站上發佈。我感謝你的時間!

Ilias

+0

我已經改變了我的實現,按照指示[這裏](http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#cross-appserverremoteref),但沒有運氣whatsoever.Exceptions狀態注入失敗,並且還有CORBA壞參數(org.omg.CORBA.BAD_PARAM)... – Ilias 2011-01-21 23:37:41

回答

2

我在這裏看到一些錯誤。

最實際的可能是,這個異常來自JSP頁面,看起來與Servlet無關,也不是EJB訪問。這兩個都不會出現在堆棧跟蹤中。您可能有一個名爲的home.jsp,其中包含home.jsp。它試圖寫入響應,但表示它的流已經關閉。某處你正在做一些令人討厭的事情,但這很可能與EJB無關。

一個更理論上的錯誤是,你的設計看起來像一個很大的反模式。僅僅爲了「分離業務邏輯」而使用遠程EJB調用是一個不好的主意。如果要分離業務邏輯,只需將EJB放入EJB模塊中,將Servlet和JSP放入WEB(war)模塊中,然後將兩者合併到一個EAR中。使用本地接口。創建一個支持這個項目的項目通常只需在Netbeans或Eclipse等IDE中進行幾次點擊,並且設計的性能和完整性要好得多。

請注意,遠程EJB絕對有其用處,但應謹慎使用非常。使用它們來控制遠程服務器上的粗粒度作業等,其中該服務器的特定實例具有特定含義。例如。您的羣集中可能只有一個網關服務器,其中消息(通過JMS)排隊並批量處理以發送到外部網絡。在這裏使用遠程EJB來管理該遠程服務器。

從您的問題描述中,我嚐到了想要使用這個第二個Glassfish實例進行「常規」細粒度業務邏輯。除非您100%確定自己在做什麼,並且100%確信您的具體問題絕對需要遠程通信,否則我強烈建議您放棄此想法。

+0

謝謝你的啓發答案arjan!我必須同意你所說的一切,但我想添加一些東西。最初,我的應用和你描述的完全一樣,ejbs和jsps/servlet在一個EAR中。它工作正常:)事情是,我必須以一種有點分散的方式轉換我的實現,而我在這篇文章中要做的是朝着這個方向。所以我試圖爲我的應用程序實現一個遠程服務來訪問,我的想法是構建一個ejb,在另一個服務器中執行某些操作!雖然對於例外情況您是正確的,但查找仍然無效。 – Ilias 2011-01-21 23:25:47

2

完整Glassfish的3.1 +的Eclipse太陽神+ EJB 3.1實施例

簡單Main.java(SIMPLE客戶項目無需部署)

Properties props = new Properties(); 
props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory"); 
props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming"); 
props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl"); 

// optional. Defaults to localhost. Only needed if web server is running 
// on a different host than the appserver 
props.setProperty("org.omg.CORBA.ORBInitialHost", "127.0.0.1"); 
// optional. Defaults to 3700. Only needed if target orb port is not 3700. 
props.setProperty("org.omg.CORBA.ORBInitialPort", "3700"); 

InitialContext ic = new InitialContext(props); 
GlassfishSessionBeanRemote gRemote = (GlassfishSessionBeanRemote)ic.lookup("java:global/EJBGFish/GlassfishSessionBean!com.example.GlassfishSessionBeanRemote"); 
gRemote.sayHello(); 

EJB模塊 - 必須在所有DEPLOY下面是一個JAR文件(在Eclipse中作爲服務器運行) - 已部署

@Stateless 
public class GlassfishSessionBean implements GlassfishSessionBeanRemote, GlassfishSessionBeanLocal { 

    @Override 
    public void sayHello() { 
     System.out.println("First Glassfish App!"); 
    } 

遠程和本地接口如下。

@Remote 
public interface GlassfishSessionBeanRemote { 

    public void sayHello(); 
} 

@Local 
public interface GlassfishSessionBeanLocal { 

    public void sayHello(); 
} 

最重要的事情要做:

  1. 必須從GLASSFISH 3.1 LIB FOLDER主ADD GF-client.jar中。 java的類路徑(第一個)
  2. 將EJB PROJECT添加到Main.java的類路徑。
+0

對於` IIOP`工作,你不需要在`ORB`上配置一個監聽器嗎? – Thufir 2015-03-12 14:05:01

0

我認爲你需要部署EJB項目;之後,將如下代碼插入到客戶端項目中:

try { 
    Context c = new InitialContext(); 
    HelloRemote z = (HelloRemote) c.lookup("java:global/Pro_EJBModule1/Hello!newpackage.HelloRemote"); 
    System.out.println(z.sayHello("NGA")); 
} catch (NamingException ne) { 
    System.out.println(ne); 
    throw new RuntimeException(ne); 
} 

Pro_EJBModule1是EJB項目的名稱。

0

this answer as well中可找到一個相關答案,它說明了獨立客戶端而非部署客戶端。

相關問題