RemoteServiceServlet's & EJB3, HOW?

27 views
Skip to first unread message

ahhughes

unread,
Oct 16, 2007, 10:46:22 PM10/16/07
to Google Web Toolkit
Hi,

Firstly I would encourage people to read this carefully and help with
a concise answer, one that I can not presently find in any discussion,
this is mainly for future reference to other readers and not for
myself. Thanks.

I am working on an example application for the gwt-maven group, as
part of this I want to introduce a simple EJB3/GWT example (code will
be available sometime somewhere soon!).

I currently have:
* GWT client.* code is seperated to a Java1.4 target JVM
* GWT server.* code is seperated to a Java1.5+ target JVM
* GWT RPC between client and server is working correctly (hence
overcomding the Java1.4 limitation on the server side)
* EJB's (@Remote/@Stateless) that I can access and get an instance of
from a standard HttpServlet (important, because there is no problem
with the EJB's or the appserver/container, or the way I am referencing
them)


This code inside a standard HttpServlet works!!!!
=============================
package com.gwt.maven.example.server;

import java.io.IOException;

import javax.ejb.EJB;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.gwt.maven.example.ejb.RandomCompliment;

public class HttpServlet extends javax.servlet.http.HttpServlet {

@EJB
private static RandomCompliment bean;

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse
resp)
throws ServletException, IOException {
try {
InitialContext ic = new InitialContext();
bean = (RandomCompliment)
ic.lookup(RandomCompliment.class.getName());
resp.getWriter().println(bean.getCompliment());
} catch (Exception e) {
e.printStackTrace(resp.getWriter());
}
}
}


Identical code inside a GWT RemoteServiceServlet Does NOT work
========================================
package com.gwt.maven.example.server;

import javax.ejb.EJB;
import javax.naming.InitialContext;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.gwt.maven.example.client.ExampleRemoteService;
import com.gwt.maven.example.ejb.RandomCompliment;

public class ExampleRemoteServiceImpl extends RemoteServiceServlet
implements
ExampleRemoteService {

@EJB
private static RandomCompliment bean;

public String doComplimentMe() {
String response = "ERROR: NEVER EXECUTED!!!!";
try {
InitialContext ic = new InitialContext();
bean = (RandomCompliment)
ic.lookup(RandomCompliment.class.getName());
response = bean.getCompliment();
} catch (Exception e) {
response = e.toString();
}
return response;
}
}

The ERROR
=======
The error I am receiving indicates that while creating an instance of
ExampleRemoteServiceImpl, it bombs out... because it can't find the
@EJB I have declared. It can not create a ExampleRemoteServiceImpl
object, let alone call the doComplimentMe() method from an object that
does not exist. This indicates that the ExampleRemoteServiceImpl does
not have access to the same resources as what a standard (and
successfully working) javax.servlet.http.HttpServlet has.

[#|2007-10-17T11:44:09.992+0930|SEVERE|sun-appserver9.1|
javax.enterprise.system.container.web|
_ThreadID=21;_ThreadName=httpSSLWorkerThread-8080-1;_RequestID=65457517-
b0c8-4416-9e29-64d900c86ba1;|
StandardWrapperValve[com.gwt.maven.example.server.ExampleRemoteServiceImpl/
com.gwt.maven.example.Application/exampleRemoteService]: PWC1382:
Allocate exception for servlet
com.gwt.maven.example.server.ExampleRemoteServiceImpl/
com.gwt.maven.example.Application/exampleRemoteService
java.lang.NoClassDefFoundError: com/gwt/maven/example/client/
ExampleRemoteService
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at
com.sun.enterprise.loader.EJBClassLoader.findClass(EJBClassLoader.java:
687)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:
1402)
......

I don't know what is going on here... but I'm sure there are plenty of
people smarter than me who have already worked this out.

Thanks in advance :)

Ian Petersen

unread,
Oct 16, 2007, 11:33:03 PM10/16/07
to Google-We...@googlegroups.com
What's your test environment? The Tomcat server that's shipped with
the hosted mode browser is not a full J2EE container--it's just
Tomcat. You might have more success if you searched the forum for
-noserver and followed the advice there.

If you're already doing that, then I'm not sure what the problem is.
I'm also using EJB3s, and it works fine. The two biggest pains are
that Hibernate doesn't use "standard" containers and GWT doesn't
support annotations, so I have to map my beans from a server-side
implementation to a client-side implementation. The mapping's not a
huge deal, though--I wrote a little object-graph walker that uses the
tools in java.beans.* to wander over the source bean and create a
copy. There might even be an existing tool to do that for me because
I've seen mention of something called "Dozer" on this forum.

Ian

--
Tired of pop-ups, security holes, and spyware?
Try Firefox: http://www.getfirefox.com

Ian Petersen

unread,
Oct 16, 2007, 11:34:48 PM10/16/07
to Google-We...@googlegroups.com
Sorry for the double post, but I just noticed a detail in your stack
trace--it's a java.lang.NoClassDefFoundError, which means your class
path is probably wrong. The way you fix your class path depends on
how you're launching the server.

ahhughes

unread,
Oct 17, 2007, 12:21:15 AM10/17/07
to Google Web Toolkit
The environment is a full J2EE container [I dont want to name it
because this *should* be agnostic and only clouds the real issue,
whatever it is ;) ]

To clarify, I CAN access EJB's from a standard HttpServlet running
alongside my GWT RemoteServiceServlet. But the GWT
RemoteServiceServlet can NOT access the EJB's classes despite having
identical EJB code/references to that in the HttpServlet which I have
created and tested sucessfully.

This does not involve Hibernate, Spring, JPA, JSF, Struts, JSP....
only EJB3.

ahhughes

unread,
Oct 17, 2007, 12:28:59 AM10/17/07
to Google Web Toolkit
Hi Ian,

correct... this is indeed a NoClassDefFoundError. When creating the
"ExampleRemoteServiceImpl" (see start of thread)... it can not
successfully resolve the following..

@EJB
private static RandomCompliment bean;

So this fails when inside my...


public class ExampleRemoteServiceImpl extends
RemoteServiceServlet

But works perfect inside my...


public class HttpServlet extends
javax.servlet.http.HttpServlet {

????

I suspect your classpath issue is correct, but why? Both classes are
in the same package, same compiler, same imported jar...

Ian Petersen

unread,
Oct 17, 2007, 12:36:08 AM10/17/07
to Google-We...@googlegroups.com
On 10/17/07, ahhughes <ahhu...@gmail.com> wrote:
> correct... this is indeed a NoClassDefFoundError. When creating the
> "ExampleRemoteServiceImpl" (see start of thread)... it can not
> successfully resolve the following..
>
> @EJB
> private static RandomCompliment bean;

I could be wrong, but the NoClassDefFoundError in your stack trace
seems to be referring to ExampleRemoteService, not RandomCompliment.
If that's true, then it's having trouble resolving the interface that
your service extends, not the bean it's trying to use, which might
make more sense because that's one of very few things that's different
between a standard servlet and a RemoteServiceServlet.

Your stack trace was truncated (I assume for space reasons). Did the
full trace include anything in the com.google namespace? Could you
post the top-most few com.google frames?

As I said before, I'm using EJBs with no trouble (inside JBoss 4.0.5,
in case it matters), and the existence of hibernate4gwt suggests
others are doing the same. I don't think it's the EJBs in particular
that are a problem for you, unless there's something _really_ weird in
your setup.

ahhughes

unread,
Oct 17, 2007, 12:38:31 AM10/17/07
to Google Web Toolkit
Ian, Thanks for the insight... Complete Stacktrace...

[#|2007-10-17T11:44:09.992+0930|SEVERE|sun-appserver9.1|
javax.enterprise.system.container.web|
_ThreadID=21;_ThreadName=httpSSLWorkerThread-8080-1;_RequestID=65457517-
b0c8-4416-9e29-64d900c86ba1;|
StandardWrapperValve[com.gwt.maven.example.server.ExampleRemoteServiceImpl/
com.gwt.maven.example.Application/exampleRemoteService]: PWC1382:
Allocate exception for servlet
com.gwt.maven.example.server.ExampleRemoteServiceImpl/
com.gwt.maven.example.Application/exampleRemoteService
java.lang.NoClassDefFoundError: com/gwt/maven/example/client/
ExampleRemoteService
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at
com.sun.enterprise.loader.EJBClassLoader.findClass(EJBClassLoader.java:
687)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:
1402)

at
org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:
1109)
at
org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:
832)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:
197)
at
org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:
271)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:
202)
at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
632)
at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
577)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:
94)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
206)
at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
632)
at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
577)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:
571)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:
150)
at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
632)
at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
577)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:
571)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
at
org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:
270)
at
com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:
637)
at
com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:
568)
at
com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:
813)
at
com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:
339)
at
com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:
261)
at
com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:
212)
at com.sun.enterprise.web.portunif.PortUnificationPipeline
$PUTask.doTask(PortUnificationPipeline.java:361)
at
com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:
265)
at
com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:
106)
|#]


On Oct 17, 1:36 pm, "Ian Petersen" <ispet...@gmail.com> wrote:

Ian Petersen

unread,
Oct 17, 2007, 12:43:20 AM10/17/07
to Google-We...@googlegroups.com
On 10/17/07, ahhughes <ahhu...@gmail.com> wrote:
> Ian, Thanks for the insight...

No problem :)

> Complete Stacktrace...

Well, I didn't learn anything from the trace, so I'm not sure where
else to go. Good luck.

Sanjiv Jivan

unread,
Oct 17, 2007, 10:51:03 AM10/17/07
to Google-We...@googlegroups.com
The NoClassDefFoundError indicates that the class ExampleRemoteServiceImpl is actually found in the CLASSPATH but there was a problem loading its class definition. This usually happens when it cant find a static member or there is a problem in the classes static initializer but could also happen due to ClassLoader visibility issues. It your case it is possible that the static member declaration RandomCompliment is unable to be found by the EJBClassLoader (com.sun.enterprise.loader.EJBClassLoader). It might be best to set a break point in your debugger before the exception is raised and evaluate expressions to see where the class is found and in which classloader. In some cases due to the presence of certain classes in the app servers bootclasspath causes the parent classloader to not be able to see subclasses.


Sanjiv

GWT-Ext Widget Library :   http://code.google.com/p/gwt-ext/


On 10/17/07, ahhughes <ahhu...@gmail.com> wrote:
org.apache.catalina.core.ContainerBase.invoke (ContainerBase.java:1080)

        at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:
150)
        at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
632)
        at
org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
577)
        at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:
571)
        at
org.apache.catalina.core.ContainerBase.invoke (ContainerBase.java:1080)

        at
org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:
270)
        at
com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java :
637)
        at
com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:
568)
        at
com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process ( DefaultProcessorTask.java:
813)
        at
com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:
339)
        at
com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask (DefaultReadTask.java:
261)
        at
com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:
212)
        at com.sun.enterprise.web.portunif.PortUnificationPipeline
$PUTask.doTask( PortUnificationPipeline.java:361)

ahhughes

unread,
Oct 17, 2007, 7:26:15 PM10/17/07
to Google Web Toolkit
Thanks Sanjiv and Ian...

Sanjiv you are correct, looking at the RemoteServiceServlet source,
(with some a big help from my colleague) we found there is some funny
threading going on in there.

This threading blocks direct access to the appropriate classloader,
and what you describe below occurs.

The following resolves the appropraite classloader that can resolve
the EJB issue....

ClassLoader cl = Thread.currentThread().getContextClassLoader();
RandomComplimentBean rcb = (RandomComplimentBean)
java.beans.Beans.instantiate(cl,
RandomComplimentBean.class.getName());


I suspect there is still a better way of doing this.... and I will
post back when/if I find this out.


Cheers.


On Oct 17, 11:51 pm, "Sanjiv Jivan" <sanjiv.ji...@gmail.com> wrote:
> The NoClassDefFoundError indicates that the class ExampleRemoteServiceImpl
> is actually found in the CLASSPATH but there was a problem loading its class
> definition. This usually happens when it cant find a static member or there
> is a problem in the classes static initializer but could also happen due to
> ClassLoader visibility issues. It your case it is possible that the static
> member declaration RandomCompliment is unable to be found by the EJBClassLoader
> (com.sun.enterprise.loader.EJBClassLoader). It might be best to set a break
> point in your debugger before the exception is raised and evaluate
> expressions to see where the class is found and in which classloader. In
> some cases due to the presence of certain classes in the app servers
> bootclasspath causes the parent classloader to not be able to see
> subclasses.
>
> Sanjiv
>
> GWT-Ext Widget Library : http://code.google.com/p/gwt-ext/
>

Miguel Méndez

unread,
Oct 19, 2007, 11:13:54 AM10/19/07
to Google-We...@googlegroups.com
Could you enter an issue for this?

Thanks,

On 10/17/07, ahhughes <ahhu...@gmail.com> wrote:
> >         at java.lang.ClassLoader.loadClass (ClassLoader.java:306)
> > org.apache.catalina.core.StandardPipeline.invoke (StandardPipeline.java:

> > 571)
> >         at
> > org.apache.catalina.core.ContainerBase.invoke (ContainerBase.java:1080)
> >         at
> > org.apache.coyote.tomcat5.CoyoteAdapter.service (CoyoteAdapter.java:



--
Miguel

Fushion

unread,
Oct 19, 2007, 8:57:44 PM10/19/07
to Google Web Toolkit
Hi there,

There is something else you should have a look at.
You first inject (!!) the bean with the @EJB annotation:

>> @EJB
>> private static RandomCompliment bean;

Later on you reassign the bean with the JNDI lookup of the bean:

>> InitialContext ic = new InitialContext();
>> bean = (RandomCompliment)ic.lookup(RandomCompliment.class.getName());

If you have a look at the samples of Jboss, you should have known that
@EJB injection is not functional yet in the Tomcat http stack that
Jboss uses. That's why you have to reassign the bean with the JNDO
lookup.

I think the @EJB injection code, together with the Maven framework, is
messing up the initialization of the servlet (hence the exception in
StandardWrapper.loadServlet() ).
Try to comment out the @EJB line and see if it makes a difference.

Greetz,
Menno.


On 17 okt, 06:38, ahhughes <ahhug...@gmail.com> wrote:
> Ian, Thanks for the insight... Complete Stacktrace...
>
> [#|2007-10-17T11:44:09.992+0930|SEVERE|sun-appserver9.1|
> javax.enterprise.system.container.web|
> _ThreadID=21;_ThreadName=httpSSLWorkerThread-8080-1;_RequestID=65457517-
> b0c8-4416-9e29-64d900c86ba1;|
> StandardWrapperValve[com.gwt.maven.example.server.ExampleRemoteServiceImpl/
> com.gwt.maven.example.Application/exampleRemoteService]: PWC1382:
> Allocate exception for servlet
> com.gwt.maven.example.server.ExampleRemoteServiceImpl/
> com.gwt.maven.example.Application/exampleRemoteService
> java.lang.NoClassDefFoundError: com/gwt/maven/example/client/
> ExampleRemoteService
> at java.lang.ClassLoader.defineClass1(Native Method)
> at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
> at
> com.sun.enterprise.loader.EJBClassLoader.findClass(EJBClassLoader.java:
> 687)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
> at

> org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.ja­va:


> 1402)
> at
> org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:
> 1109)
> at
> org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:
> 832)
> at

> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.j­ava:


> 197)
> at
> org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContex­tValve.java:
> 271)
> at

> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.j­ava:


> 202)
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
> 632)
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
> 577)
> at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:
> 94)
> at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
> 206)
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
> 632)
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
> 577)
> at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:
> 571)
> at
> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
> at

> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.jav­a:


> 150)
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
> 632)
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
> 577)
> at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:
> 571)
> at
> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
> at
> org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:
> 270)
> at

> com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter­(DefaultProcessorTask.java:


> 637)
> at
> com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(Def­aultProcessorTask.java:
> 568)
> at

> com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(Defau­ltProcessorTask.java:


> 813)
> at
> com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTa­sk(DefaultReadTask.java:
> 339)
> at

> com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultRead­Task.java:
> 261)
> at
> com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultRead­Task.java:


> 212)
> at com.sun.enterprise.web.portunif.PortUnificationPipeline
> $PUTask.doTask(PortUnificationPipeline.java:361)
> at
> com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:
> 265)
> at

> com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerT­hread.java:

> > Try Firefox:http://www.getfirefox.com- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

Reply all
Reply to author
Forward
0 new messages