Java 7u55 Eclipse System Fragment Classloader

В предыдущих версиях Java я мог использовать фрагмент, который имел множество системных пакетов, чтобы предоставить классы загрузчику загрузчиков классов.

В моем конкретном случае это было для поддержки использования Jacorb в Eclipse. Это все работало нормально до Java 7u55.

Я создал фрагмент osgi, который содержал все банки для Jacorb. Манифест выглядит так:

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 args:

-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

Когда я запустил свое приложение Eclipse в Java 7u51, я смог успешно вызвать 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 об этой проблеме. В то же время, есть ли способ переопределить ORB.java, который поставляется с JVM через какой-то фрагмент?

3 ответа

Вам нужен ORB для всей системы / Singleton, чтобы быть ORB Jacorb? Если нет, то самое простое решение здесь - просто удалить -Dorg.omg.CORBA.ORBSingletonClass из командной строки. Помните, что одноэлементный ORB - это просто фабрика TypeCode, ваш вызов 2-аргументного ORG.init все равно выдаст Jacorb ORB, потому что у вас есть org.omg.CORBA.ORBClass, чтобы выбрать его.

У меня та же проблема (и я видел, что у многих других она тоже есть), но с приложением на основе CORBA.

Проблема этого изменения состоит в том, что SystemClassLoader, который принудительно используется из-за изменения в u55, не знает, как загрузить классы ORB & ORBSingleton, указанные через упомянутые свойства, поскольку они являются частью пути к классу приложения - в моем случае загружается JNLPClassloader.

Я полагаю, что в вашем случае есть аналогичное обоснование.

Один из способов заменить версию JDK orb.omg.CORBA, которую вы уже использовали, указав -Djava.endorsed.dirs=${jacorb/lib/}, Это заменяет версию пакета JDK org.omg.CORBA на версию, предоставляемую JacORB, которая вместо этого использует ContextClassLoader текущего потока (так же, как это делал код до u55).

Другой вариант заключается в использовании, например, -Xbootclasspath/p:${jacorb/lib/jar-containing-omg-api.jar} или скопируйте JAR-файлы, содержащие версию org.omg.CORBA JacORB, в <jre-home>/lib/endorsed,

К сожалению, это не помогло для моей проблемы с приложением Webstart.

Примечания к выпуску (недавно обновленные, поскольку этой информации раньше не было), упомянутые пользователем 3054250 (спасибо за это), указывают на другой возможный обходной путь. Указание только свойства ORB, но без ORBSingleton работает (краткий тест) в моем приложении CORBA/Webstart вместе с JacORB 3.4.

Он не работает с OpenORB (так как OpenORB проверяет "правильный" экземпляр ORBSingleton), поэтому я должен обновить свое приложение до JacORB, но это решение.

Другие вопросы по тегам