users@glassfish.java.net

Re: Embedded Glassfish and weaving

From: Bhavanishankar <bshankar_at_sun.com>
Date: Tue, 01 Feb 2011 21:20:11 +0530

Hi Laird,

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

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.

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.

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

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 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.

Just a few tips if it helps you...you might have known some of these
already.

_Bhavani.

On 02/01/2011 03:03 AM, Laird Nelson wrote:
> It looks like perhaps EclipseLink weaving (dynamic weaving) is borked
> when you're running the latest version (b39, notably not b40, which
> doesn't exist) of embedded Glassfish.
>
> As a result I get this bizarre error:
>
> Exception Description: A NullPointerException would have occurred
> accessing a non-existent weaved _vh_ method
> [_persistence_get_person_vh]. The class was not weaved properly - for
> EE deployments, check the module order in the application.xml
> deployment descriptor and verify that the module containing the
> persistence unit is ahead of any other module that uses it.
>
> Of course I am not deploying an .ear file, so there is no
> application.xml deployment descriptor. I am deploying a
> ScatteredArchive of type ScatteredArchive.Type.JAR, which contains my
> EJB code as well as persistent entities, and a
> META-INF/persistence.xml file.
>
> So it looks like EclipseLink is attempting to weave my file, but for
> some reason is failing. If I disable weaving, which I really don't
> want to do, by setting the eclipselink.weaving persistence property to
> "false", then I get past this problem, but of course none of my lazy
> loading behavior and whatnot is actually tested.
>
> So how can I obey the error message when I don't have any other
> modules deployed to embeddable Glassfish?
>
> Thanks,
> Laird