Embedded Glassfish and weaving
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
On Tue, Feb 1, 2011 at 10:50 AM, Bhavanishankar 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
Hi Laird,
On 02/01/2011 09:31 PM, Laird Nelson wrote:
>
>
> OK. For now, it looks like I'll have to go with 3.
Thanks. In future we can give an option such that app does not have to
change (possibly a property something like
"eclipselink.weaving.enabled=false" to be set in the GlassFishProperties).
>
> 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.
I think the root cause is something else. I tried making the remote
interface explicitly extend java.rmi.Remote, but that didn't help.
However, when the embedded maven-plugin is used, it all works without
requiring to to extend java.rmi.Remote. The working test I am referring
to is this
_Bhavani.
>
> Thanks for your pointers.
>
> Best,
> Laird





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