2011-01-21 81 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中可找到一个相关答案,它说明了独立客户端而非部署客户端。

相关问题