Access to stateless EJB from another Glassfish instance

There is a problem that bothers me, and I cannot find any single way to solve it on the Internet. I am developing an enterprise application using Java EE, Glassfish, and Netbeans.

I have two instances of Glassfish, and I am creating an enterprise application shared between them. I have a webpage (with multiple JSPs and multiple HttpServlets) running on a single Glassfish instance. In another case, I want to implement the business logic of the application. That is, I have Java Entity Beans, as well as an EJB with a remote interface that uses this beans entity.

My goal is to access EJB remotely from servlets in the first instance of glass fish. I followed the instructions found in this post , but to no avail. I provide code snippets to clarify ...

In one instance of Glassfish, the remote EJB interface:

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

and standless bean:

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

Otherwise:

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

Unfortunately, when I start my site and try to find the remote ejb, I get the following exception:

 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) 

What is missing in my implementation? Any suggestions / ideas? Please ask if any of the descriptions of my problem are missing, this is my first post on this site. I appreciate your time!

Elias

+3
source share
4 answers

I see a few errors here.

The most practical is probably the exception to the JSP page and apparently has nothing to do with the servlet or access to the EJB. Both of them do not appear in the stack trace. You probably have a JSP called home.jsp. He tries to write an answer, but the thread that represents him is already closed. Somewhere you are doing something unpleasant, but it is probably not related to EJB.

A more theoretical mistake is that your design looks like a big anti-template. Using remote EJB calls solely to "split the business logic" is EXTREMELY's bad idea. If you want to separate your business logic, just put your EJBs in the EJB module, your servlets and JSPs in the WEB (war) module, and combine them together in an EAR. Use local interfaces. Creating a project that supports this usually takes just a few clicks in an IDE such as Netbeans or Eclipse, and the performance and reasonableness of your design is much better.

Note that remote EJBs most definitely use them, but they should be used very sparingly. Use them to manage coarse-grained jobs, or so on a remote server, where a specific instance of that server has a specific meaning. For instance. you can have one gateway server in your cluster, where messages (through JMS) are queued and processed in a packet to be sent to the external network. Use remote EJBs to manage this remote server.

From your description of the problem, I try that you want to use this second instance of Glassfish for β€œregular” fine-grained business logic. If you are 100% not sure of your actions, and you are 100% sure that your specific problem is absolutely necessary for remote communication, I strongly recommend that you abandon this idea.

+2
source

Complete Glassfish 3.1 + Eclipse Helios + EJB 3.1 Example

Simple Main.java (SIMPLE client PROJECT, DO NOT NEED TO DO)

 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 module - YOU SHOULD DEPLOY EVERYTHING BELOW THREE AS ​​A JAR FILE (just run as a server in Eclipse) - DEPLOEDED

 @Stateless public class GlassfishSessionBean implements GlassfishSessionBeanRemote, GlassfishSessionBeanLocal { @Override public void sayHello() { System.out.println("First Glassfish App!"); } 

REMOTE AND LOCAL INTERFACES BELOW.

 @Remote public interface GlassfishSessionBeanRemote { public void sayHello(); } @Local public interface GlassfishSessionBeanLocal { public void sayHello(); } 

MOST IMPORTANT THINGS:

  • MUST ADD gf-client.jar from GLASSFISH 3.1 LIB FOLDER to Main. java class path. (First)
  • ADD EJB PROJECT for the class path Main.java.
+2
source

I think you need to deploy an EJB project; After that, add the code to the client project:

 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 is the name of the EJB project.

0
source

The corresponding answer, which the standalone client considers, rather than the deployed one, can be found in this answer .

0
source

All Articles