问题
This one starts to drive me completely nuts ...
I want to create a Glassfish client application using Maven.
For that, I've added the requried gf-client dependency :
<dependency>
<groupId>org.glassfish.appclient</groupId>
<artifactId>gf-client</artifactId>
<version>3.1</version>
<type>pom</type>
<scope>compile</scope>
</dependency>
Then, wanting to contact my Glassfish server, running on the same application, I do the usual lookup :
Properties p = new Properties();
// optional. Defaults to localhost. Only needed if web server is running
// on a different host than the appserver
p.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
// optional. Defaults to 3700. Only needed if target orb port is not
// 3700.
p.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
Context context = new InitialContext(p);
// Stores the list of reachable EJBs
return context.lookup(interfacesToNames.getProperty(className));
Unfortunatly, when doing so, all I get is
Caused by: javax.naming.NoInitialContextException: Cannot instantiate class: com.sun.enterprise.naming.impl.SerialInitContextFactory [Root exception is java.lang.ClassNotFoundException: com/sun/enterprise/naming/impl/SerialInitContextFactory]
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:674)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
at javax.naming.InitialContext.init(InitialContext.java:242)
at javax.naming.InitialContext.<init>(InitialContext.java:216)
... 6 more
Caused by: java.lang.ClassNotFoundException: com/sun/enterprise/naming/impl/SerialInitContextFactory
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:63)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:671)
... 9 more
After some checks, I've noticed that my glassfish-naming-3.1.jar
is present in CLASSPATH for that client application. And, according to Eclipse code lookup, it is this jar that should contain com.sun.enterprise.naming.impl.SerialInitContextFactory
. However, if in debug mode, I do getClass().getClassLoader().getResource("com/sun/enterprise/naming/impl/SerialInitContextFactory")
it returns me null, which clearly indicates that the class can't be found.
For more infos, the JAR is copied from my local maven repository using this plugin configuration :
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>package output directory</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<prependGroupId>true</prependGroupId>
<includeScope>compile</includeScope>
<outputDirectory>${dependencies.outputDir}/jars</outputDirectory>
<prefix>${dependencies.outputDir}</prefix>
</configuration>
</execution>
</executions>
</plugin>
Furthermore, I have to confess that, when running a simple test using the same API to connect to Glassfish server, there is absolutely no problem, which directs me to a ClassLoader issue.
When running that client, the current class loader is (as denoted by getClass().getClassLoader().getClass().getName()
) sun.misc.Launcher$AppClassLoader
. Which unfortunatly is exactly the same than when running unit test.
So, what can I do to solve that bug ?
EDIT Class exists in glassfish-naming-3.1.jar
, but does not seems to be findable by standard classloader.
EDIT An interesting discovery :
getClass().getClassLoader().getResource("com/sun/enterprise/naming/impl") = jar:file:/C:/Users/pouet/pouet/target/jars/glassfish-naming-3.1.jar!/com/sun/enterprise/naming/impl
while
getClass().getClassLoader().getResource("com/sun/enterprise/naming/impl/SerialInitContextFactory") = null
回答1:
For a reason I not totally understand, there is a configured Context classloader when run in application. This classloader seems to use some kind of OSGi naming restriction.
As a consequence, to avoid the bug, I reset the context class loader :
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
And it worked !
回答2:
Have you tried using the ACC? Your solution seems contrived.
来源:https://stackoverflow.com/questions/7804357/serialinitcontextfactory-not-found-in-glassfish-naming