以前のバージョンの Java では、ブート クラスローダーにクラスを提供するために、システム バンドルのホストを持つフラグメントを使用できました。
私の特定のケースでは、これは Eclipse での Jacorb の使用をサポートするためのものでした。Java 7u55 より前では、これはすべて正常に機能していました。
Jacorb のすべての jar を含む osgi フラグメントを作成しました。マニフェストは次のようになります。
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.init() を正常に呼び出すことができました。
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 クラスの作成方法が変更されました。Thread コンテキスト クラス ローダーを使用する代わりに、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;
+ }
+ }
この問題について Orcale にチケットを記録しようとしました。それまでの間、何らかのフラグメントを介して JVM に付属する ORB.java をオーバーライドする方法はありますか?