My EAR has the following structure :
lib/
helper.jar (Helper classes used both by war1.war and war2.war)
war1.war
WEB-INF/
lib/
entities1.jar
war2.war
WEB-INF/
lib/
entities2.jar
When war1 calls a class in helper.jar that itself calls Class.forName("a class in war1"), it throws a ClassNotFoundException.
Notice that people usually have ClassNotFoundException when a war class loads a ear/lib class. My case is the reverse situation.
My EAR is deployed in Glassfish 3.1.2.
I've seen a similar case, but in JBoss, "EAR lib's class throwing a ClassNotFoundException for a WAR member", but the answers say it's a "cyclic dependency" problem. However, I don't see any "cyclic dependency" problem here. In java, any ClassX can refer to ClassY even if ClassY refers to ClassX....
In helper.jar
you can't simply load a class situated in your war1.war
using Class.forName
.
The limitation comes from the default classloader used by the Class.forName
method, which is the enterprise app's classloader (the one which loads helper.jar
), which knows only its parents, not its children (war1.war
and war2.war
classloaders).
The solution for your problem is to use explicitely the context classloader, which scans in order:
war -> ear -> system -> extension -> bootstrap
This can be done using:
Class.forName("war1Class.class",true,Thread.currentThread().getContextClassLoader())