这个开始让我完全疯了......
我想使用Maven创建一个Glassfish客户端应用程序。
为此,我添加了所需的gf-client依赖:
<dependency>
<groupId>org.glassfish.appclient</groupId>
<artifactId>gf-client</artifactId>
<version>3.1</version>
<type>pom</type>
<scope>compile</scope>
</dependency>
然后,想要联系我的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.<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
经过一些检查后,我注意到我的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:
<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>
此外,我必须承认,当使用相同的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
答案 0 :(得分:2)
由于我不完全理解的原因,在应用程序中运行时有一个配置的Context类加载器。这个类加载器似乎使用了某种OSGi命名限制。
因此,为了避免这个错误,我重置了上下文类加载器:
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
它有效!
答案 1 :(得分:2)
您是否尝试过使用ACC?你的解决方案似乎是人为的。