在glassfish命名中找不到SerialInitContextFactory

这个开始让我完全疯了……

我想使用Maven创建一个Glassfish客户端应用程序。

为此,我添加了需要的gf-client依赖项:

 org.glassfish.appclient gf-client 3.1 pom compile  

然后,想要联系我的Glassfish服务器,在同一个应用程序上运行,我会进行常规查找:

 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)); 

不幸的是,当我这样做时,我得到的只是

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

经过一些检查后,我注意到我的glassfish-naming-3.1.jar存在于该客户端应用程序的CLASSPATH中。 而且,根据Eclipse代码查找,这个jar应该包含com.sun.enterprise.naming.impl.SerialInitContextFactory 。 但是,如果在调试模式下,我执行getClass().getClassLoader().getResource("com/sun/enterprise/naming/impl/SerialInitContextFactory")它返回null,这清楚地表明无法找到该类。

有关更多信息,使用此插件配置从我的本地maven存储库复制JAR:

   maven-dependency-plugin   package output directory package  copy-dependencies   true compile ${dependencies.outputDir}/jars ${dependencies.outputDir}     

此外,我必须承认,当使用相同的API运行一个简单的测试来连接到Glassfish服务器时,绝对没有问题,这导致我遇到ClassLoader问题。

运行该客户端时,当前的类加载器(由getClass().getClassLoader().getClass().getName()表示getClass().getClassLoader().getClass().getName()sun.misc.Launcher$AppClassLoader 。 不幸的是,与运行unit testing时完全相同。

那么,我该怎么做才能解决这个bug呢?

编辑类存在于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类加载器。 这个类加载器似乎使用了某种OSGi命名限制。

因此,为了避免这个bug,我重置了上下文类加载器:

 Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); 

它奏效了!

你试过使用ACC吗? 你的解决方案似乎是人为的