在Java的早期版本中,我能够使用一个具有系统捆绑主机的片段,以便向引导类加载器提供类。
在我的特殊情况下,这是为了支持在Eclipse中使用Jacob。这一切在Java 7u55之前都运行良好。
我创建了一个osgi片段,其中包含Jacob的所有jar。清单如下:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: org.jacorb.systemFragment
Bundle-SymbolicName: org.jacorb.systemFragment
Bundle-Version: 3.3.0.20140422-1108
Bundle-ClassPath: jars/slf4j-jdk14-1.6.4.jar,
jars/slf4j-api-1.6.4.jar,
jars/jacorb-3.3.jar
Fragment-Host: system.bundle; extension:=framework
Export-Package: org.jacorb.config;version="3.3.0", ....
我还将以下内容指定为vm参数:
-Dorg.omg.CORBA.ORBClass=org.jacorb.orb.ORB
-Dorg.omg.CORBA.ORBSingletonClass=org.jacorb.orb.ORBSingleton
-Dorg.omg.PortableInterceptor.ORBInitializerClass.standard_init=org.jacorb.orb.standardInterceptors.IORInterceptorInitializer
当我在Java 7u51中运行Eclipse应用程序时,我能够成功地调用ORB.int()。
当我在Java 7u55中运行相同的应用程序时,我会得到以下信息:
Caused by: java.lang.ClassNotFoundException: org.jacorb.orb.ORBSingleton
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at org.omg.CORBA.ORB.create_impl_with_systemclassloader(ORB.java:306)
如果我将以下内容添加为vmargs,它就会起作用。
-Djava.endorsed.dirs=${jacorb/lib}
我确认这会影响Java 7u55、Java 6u30和Java 8u5
我以前不需要这么做。有什么想法吗?
---编辑04/30---
我做了更多的挖掘,发现了一个对ORB.java的提交导致了这个问题。
changeset: 817:a8d27c3fc4e4
tag: jdk7u55-b05
user: msheppar
date: Tue Jan 21 12:46:58 2014 +0000
summary: 8025005: Enhance CORBA initializations
这个提交改变了ORB类的创建方式。现在不再使用线程上下文类加载器,而是硬编码为使用SystemClassLoader。
- singleton = create_impl(className);
+ singleton = create_impl_with_systemclassloader(className);
}
}
return singleton;
}
+ private static ORB create_impl_with_systemclassloader(String className) {
+
+ try {
+ ReflectUtil.checkPackageAccess(className);
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
+ Class<org.omg.CORBA.ORB> orbBaseClass = org.omg.CORBA.ORB.class;
+ Class<?> singletonOrbClass = Class.forName(className, true, cl).asSubclass(orbBaseClass);
+ return (ORB)singletonOrbClass.newInstance();
+ } catch (Throwable ex) {
+ SystemException systemException = new INITIALIZE(
+ "can't instantiate default ORB implementation " + className);
+ systemException.initCause(ex);
+ throw systemException;
+ }
+ }
我已经试着为这个问题登录了一张去奥卡尔的机票。同时,有没有一种方法可以通过某种片段覆盖JVM附带的ORB.java?
我也有同样的问题(我看到很多其他人也有),但使用了基于CORBA的Webstart应用程序。
这个变化的问题是由于u55的变化而被迫使用的SystemClassLoader不知道如何加载ORB&ORBSingleton类是通过上述属性指定的,因为它们是应用程序类路径的一部分——在我的例子中是由JNLPClassloader加载的。
我想你的情况也有类似的情况。
替换您已经使用过的JDK版本orb.omg.CORBA的一种方法是指定-Djava.endorsed.dirs=${jacorb/lib/}
。这将JDK的org.omg.CORBA包版本替换为JacORB提供的版本,JacORB使用当前线程的ContextClassLoader(与u55之前的代码相同)。
另一种选择是使用例如-Xbootclasspath/p:${jacorb/lib/jar-containing-omg-api.jar}
,或者将包含JacORB版本org.omg.CORBA的JAR复制到<jre-home>/lib/endorsed
。
不幸的是,这对我的Webstart应用程序问题没有帮助。
是否需要系统范围/单例ORB作为Jacob ORB?如果没有,那么这里最简单的解决方案可能是从命令行中删除-Dorg.omg.ORBA.ORBSingletonClass。请记住,单例ORB只是TypeCode工厂,您对2-arg ORG.init的调用仍然会给出Jacob ORB,因为您设置了ORG.omg.ORBA.ORBClass来选择它。
user3054250提到的发布说明(最近更新了,因为以前没有这些信息)(感谢您)指出了另一种可能的解决方法。在我的CORBA/Webstart应用程序和JacORB3.4中,只指定ORB属性而省略ORBSingleton是有效的(短期测试)。
它不适用于OpenORB(因为OpenORB检查ORBSingleton的"正确"实例),所以我必须将我的应用程序升级到JacORB,但这是一个解决方案。