• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

EJB3.0 & calling remote interface.

 
Ranch Hand
Posts: 362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys, me again!

After several attempts at using deployment descriptors for my sample EJB3.0 app I have decided to go the other route (as recommended to me by someone here a few days ago) and chosen Annotations!

From what I have found I think I've done it correct. The only problem is the presentation level (JSPs / Servlets for now) can not see the EJB Module classes. I can import them in the Servlet, but when executing the app I get a:-

Exception: javax.naming.NamingException: ejb ref resolution error for remote business interfacecom.myproject.sample1.SampleRemote [Root exception is java.lang.ClassNotFoundException: com.myproject.sample1.SampleRemote]

Ideally I want to deploy the WAR and EJB Jar as separate apps, because long term I'm thinking of having them on separate machines.

I have deployed this to a Sun Java WebApp 9.0 Server

So basically I need to know how to call a EJB (using Remote Interface) from a Servlet within a separate App?



Once again, many thanks for any help.
[ October 15, 2007: Message edited by: Keith Seller ]
 
Ranch Hand
Posts: 153
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Keith,

You should be able to get the remote reference to your EJB in the servlet using @EJB annotation. Please refer to this link below.

web page
 
Kevin P Smith
Ranch Hand
Posts: 362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Nope, sorry.

I think it's because as I say, I am running the EJB in a separate JAR file to the Client WAR file.

ejb_client.war - JSP, Servlets
ejb_module.jar - EJBs

 
Kevin P Smith
Ranch Hand
Posts: 362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just to add to this, I read in TheServerSide forums a thread with someone having the same problem as me and it was usggested that WAR files can not call EJBs from separate JARS!

Is this true? I find it very hard to believe because that surely defeats the entire point of the Remote Interface!!!

They suggested copying the EJB jar (ejb_module.jar in my case) or at least it's interfaces into a new JAR file which is then copied into the lib folder of the WAR file. This seems like madness! Surely if I do that, I might as well have all the classes under the same WAR/JAR and forget Remote Interfacing?

Taken from theserverside.com
-----------------------------

So a WAR in the same EAR of an EJB-jar can see automatically the EJB-jar classes/interfaces (this is also common behaviour since EJB 2.0). WARs in different EARs can't.

There are several workarounds. But first of all, you need to package the EJB "client" classes (interfaces, VOs etc.) into a separate JAR (let's call it "ejb-client.jar"). The possibilities are:

1. (I dislike this) You can put this ejb-client.jar in the server classpath, by editing the "startWebLogic.bat" file (curiously, there is no "lib/ext" folder in WLS8);

2. You can copy this ejb-client.jar into the WEB-INF/lib folder of each web application (I think BEA recommends this procedure);

3. You can try to fiddle with the application manifest file Class-Path entry, inserting a path like "../EJBEAR.ear/ejb-jar.jar"), therefore putting the EJBs original JAR in the client application classloader (there is no need of an ejb-client.jar then). This is a bit too low level, and it is hard to figure out the correct Class-Path entry;

[ October 16, 2007: Message edited by: Keith Seller ]
 
Kevin P Smith
Ranch Hand
Posts: 362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
just to add some more to this (again).

i have tried what I think the above was suggesting, which is create another JAR file fir the EJB Interfaces and imported this into the Client WAR WEB-INF/lib folder.

I have deployed both the EJB jar and Client war files again and tried running the app.

The problem is,as soon as I make a call to a Remote Iterface Method i get the following error:

[#|2007-10-16T14:07:36.173+0100|SEVERE|sun-appserver-pe9.0|javax.enterprise.system.container.web|_ThreadID=12;_ThreadName=httpWorkerThread-8080-0;_RequestID=27abee96-8da0-487d-81a1-26788c38a6b7;|StandardWrapperValve[SampleServlet]: Servlet.service() for servlet SampleServlet threw exception
java.lang.NullPointerException
at com.myproject.servlets.SampleServlet.doPost(SampleServlet.java:23)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:397)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:278)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:179)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:73)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
at com.sun.enterprise.web.VirtualServerPipeline.invoke(VirtualServerPipeline.java:120)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:137)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.invokeAdapter(ProcessorTask.java:667)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.processNonBlocked(ProcessorTask.java:574)
at com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.java:844)
at com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask.java:287)
at com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:212)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:252)
at com.sun.enterprise.web.connector.grizzly.WorkerThread.run(WorkerThread.java:75)


So something is still obviously wrong.

Also how would the remote Interface on the WAR know where the EJB Bean is under the JAR?

Cheers
 
Shailesh Kini
Ranch Hand
Posts: 153
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Keith,

Please refer to this link -> Remote EJB
 
Kevin P Smith
Ranch Hand
Posts: 362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Got it working, I now have a war file calling EJBs from a jar file (for now on the same WebApp) but looking at the properties I just change the hostname/port if it's on a different machine. It was this bit of code under GlassFish EJB FAQs that sorted it.

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", "localhost");

// optional. Defaults to 3700. Only needed if target orb port is not 3700.
props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
 
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you want to deploy the WAR and EJB Jar as separate apps separate machines, then all EJB call will be Remote Call , in this case @EJB annotaction will not work.Write Jndi lookup call for remote interface in WAR application which will act as delegare , will gave you remote object , by this object you can call EJb Bean methods in your servlet.



Bean CODE:
-----------------
@Stateless
@RemoteBinding(jndiBinding = "MeterInfoDAORemote")
@LocalBinding(jndiBinding = "MeterInfoDAOLocal")
public class MeterInfoDAOEJB implements MeterInfoDAORemote, MeterInfoDAOLocal {
------
---
-
}

Client CODE:
-------------------

public class MeterInfoDelegatet{

public MeterInfoDAOLocal meterInfoLocal;

public static MeterInfoDAOLocal getMeterInfoDAO(){
try {
Properties properties = new Properties();
properties.put("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs",
"=org.jboss.naming:org.jnp.interfaces");
properties.put("java.naming.provider.url", "jnp://localhost:1099");

Context ctx = new InitialContext(properties);
meterInfoLocal= (MeterInfoDAOLocal) ctx.lookup("MeterInfoDAOLocal");

// call business method using meterInfoLocal object

} catch (NamingException ne) {
// log.error("Naming Exception Encountered : "+ne);
}

return meterInfoLocal;

}
 
reply
    Bookmark Topic Watch Topic
  • New Topic