在glassfish命名中找不到SerialInitContextFactory [英] SerialInitContextFactory not found in glassfish naming
问题描述
我想用Maven创建一个Glassfish客户端应用程序。
为此,我添加了需要的gf-client依赖项:
< dependency>
< groupId> org.glassfish.appclient< / groupId>
< artifactId> gf-client< / artifactId>
< version> 3.1< / version>
< type> pom< / type>
< scope>编译< / scope>
< /依赖关系>
然后,想要联系我的Glassfish服务器,运行在同一个应用程序上,我按照常规查找:
属性p = new Properties();
//可选。默认为localhost。仅当Web服务器在与应用程序服务器不同的主机上运行
//时才需要
p.setProperty(org.omg.CORBA.ORBInitialHost,localhost);
//可选。默认为3700.只有在目标orb端口不是
// 3700时才需要。
p.setProperty(org.omg.CORBA.ORBInitialPort,3700);
Context context = new InitialContext(p);
//存储可到达的EJB列表
return context.lookup(interfacesToNames.getProperty(className));
不幸的是,当我这样做时,我得到的只是
原因:javax.naming.NoInitialContextException:无法实例化类:com.sun.enterprise.naming.impl.SerialInitContextFactory [根异常是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
由java.lang.ClassNotFoundException引发:com / sun / enterprise / naming / impl / SerialInitContextFactory $ b在java.lang.Class.forName0上的b $(本地方法)$ b $ java.lang.Class。 forName(Class.java:264)
在com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper 12.java:63)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:671)
... 9 more
经过一些检查后,我发现我的 glassfish-naming-3.1.jar
存在于CLASSPATH中客户端应用程序。而且,根据Eclipse代码查找,这个jar应该包含 com.sun.enterprise.naming.impl.SerialInitContextFactory
。但是,如果在调试模式下,我执行 getClass()。getClassLoader()。getResource(com / sun / enterprise / naming / impl / SerialInitContextFactory)
,它清楚地表明找不到该类。
更多信息,使用此插件配置从本地maven存储库中复制JAR:
< plugin>
< artifactId> maven-dependency-plugin< / artifactId>
<执行次数>
<执行>
< id>包输出目录< / id>
<阶段>包< /阶段>
<目标>
<目标>复制依赖关系< / goal>
< /目标>
<配置>
< prependGroupId> true< / prependGroupId>
< includeScope>编译< / includeScope>
< outputDirectory> $ {dependencies.outputDir} / jars< / outputDirectory>
< prefix> $ {dependencies.outputDir}< / prefix>
< / configuration>
< /执行>
< /执行次数>
< / plugin>
此外,我必须承认,当使用相同的API运行简单测试来连接Glassfish服务器,这是绝对没有问题的,这引导我到ClassLoader问题。
当运行该客户端时,当前类加载器(如 getClass()。getClassLoader()。getClass()。getName()
) sun.misc.Launcher $ AppClassLoader
。不幸的是,与运行单元测试完全一样。
那么,我能做些什么来解决这个错误?
编辑类存在于
glassfish-naming-3.1.jar
中,但似乎无法通过标准类加载器找到。 编辑一个有趣的发现:
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
同时
getClass()。getClassLoader()。getResource(com / sun / enterprise / naming / impl / SerialInitContextFactory)= null
$因为我不完全理解的原因,在应用程序中运行时有一个配置的Context classloader。这个类加载器似乎使用了某种类型的OSGi命名限制。
因此,为了避免这个bug,我重置了上下文类加载器:
Thread.currentThread()。setContextClassLoader(getClass()。getClassLoader());
它的工作原理!
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 containcom.sun.enterprise.naming.impl.SerialInitContextFactory
. However, if in debug mode, I dogetClass().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
解决方案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 !
这篇关于在glassfish命名中找不到SerialInitContextFactory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!