users@glassfish.java.net

Re: Embedded Glassfish and weaving

From: Laird Nelson <ljnelson_at_gmail.com>
Date: Tue, 1 Feb 2011 11:01:37 -0500

On Tue, Feb 1, 2011 at 10:50 AM, Bhavanishankar <bshankar_at_sun.com> wrote:

> I believe you are using maven-surefire-plugin to run the tests, and in the
> test itself you are creating GlassFishRuntime/GlassFish, and then deploying
> a scattered archive using Deployer.deploy
>

Yes, with one variation, in case it matters. When I was using the
javax.ejb.embeddable.EJBContainer, I uncovered another bug (which I reported
ages ago and which is now, I believe, fixed) where the EJBContainer could
only deploy the module if every class it needed was present in the directory
that it was pointed to. So before running surefire, I copy all of my
dependencies that are under my control to this current project's
test-classes tree.


> If so, the surefire classloader is playing a role here. What is happening
> is, the surefire plugin runs the unit tests in a classloader which has
> following classpath in it : "target/test-classes:target/classes:..all other
> dependency jars (including glassfish-embedded-all.jar)....:"
>
> When the test bootstraps GlassFish, all your EJB classes and test classes
> would already be there in the GlassFish's laucher classloader.
>

Ah, OK. I think I know where you're going... :-)


> Now, when you deploy the scattered archive application, embedded GlassFish
> will create an application classloader for you app. But since the root
> classloader already has these classes in it, they will all be loaded from
> there, not from application's classloader.
>

Sure.


> Weaving is possible only if the classes are available *only* in the
> application's classloader. But it is not the case in this scenario.
>

OK.


> So, we have few cases/possible solutions here:
>
> (1) The intent to test the lazy loading behavior itself and the unit tests
> don't have dependencies on application classes
>
> >In the surefire plugin configuration, don't include target/classes in its
> classloader path.
>
> (2) The intent to test the lazy loading behavior itself but unit tests have
> dependencies on application classes (i.e., target/classes):
>
> > Add a tester servlet along with EJB code/persistent entities. While
> creating ScatteredArchive, use Type.WAR
> > In the unit test, invoke the tester servlet which does all the testing
> and returns the result.
> > In the surefire plugin configuration, don't include target/classes in its
> classloader path.
> (basically we are removing the dependency of unit tests from application's
> classes).
>
> (3) It is okay to disable weaving (like was the case with the the earlier
> version of embedded glassfish). For this to work, you have to modify
> persistence.xml like you said. Embedded GlassFish in 3.1 does not make any
> assumption about weaving.
>
> Please note that (1) and (2) would not have been possible in the earlier
> version of embedded glassfish because the weaving was always disabled in
> embedded mode and there was no way to enable it. But in
>

OK. For now, it looks like I'll have to go with 3.


> this version, embedded does not make such assumption, but is capable of
> doing the weaving iff the entity classes are available only in the app'
> classloader.
>
> Case/soln (2) might solve the remote EJB issue as well, because the tester
> servlet will be able to access the @Remote EJB without any NamingException.
>

You're referring to http://java.net/jira/browse/GLASSFISH-15775? But the
root issue there is that it thinks that the bean's business interface has to
extend java.rmi.Remote, which of course is not a requirement. I don't see
how a classloader rearchitecture is going to help that.

Thanks for your pointers.

Best,
Laird