简体   繁体   中英

Java 7u55 Eclipse System Fragment Classloader

In previous versions of Java I was able to use a fragment that had a host of system-bundle in order to provide classes to the boot classloader.

In my particular case this was to support using Jacorb in Eclipse. This all worked fine prior to Java 7u55.

I created an osgi fragment that contained all the jars for Jacorb. The manifest looks like this:

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", ....

I also specify the following as 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

When I ran my Eclipse application in Java 7u51 I am able to call ORB.init() successfully.

When I run the same application in Java 7u55 I get the following:

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)

If I add the following as vmargs it works.

 -Djava.endorsed.dirs=${jacorb/lib}

I confirmed that this effects Java 7u55 Java 6u30 and Java 8u5

I didn't need to do this before. Any ideas why?

--- EDIT 04/30 ---

Did some more digging and I found a commit to ORB.java that is causing the issue.

changeset:   817:a8d27c3fc4e4
tag:         jdk7u55-b05
user:        msheppar
date:        Tue Jan 21 12:46:58 2014 +0000
summary:     8025005: Enhance CORBA initializations

This commit changed the way the ORB class was created. Instead of using the Thread context class loader it is now hard coded to use the 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;
+        }
+    }

I've tried to log a ticket to Orcale about this problem. In the mean time, is there a way to override the ORB.java that comes with the JVM via some sort of fragment?

I have the same problem (and I saw many others having it too) but with a CORBA based Webstart application.

The problem of this change is that the SystemClassLoader which is forced to be used due to the change in u55 doesn't know how to load the ORB & ORBSingleton classes specified through the mentioned properties as they are part of the application classpath - in my case loaded by JNLPClassloader.

I guess there is a similar constalation in your case.

One way to replace the JDK version of orb.omg.CORBA you've used already by specifying -Djava.endorsed.dirs=${jacorb/lib/} . This replaces JDK's org.omg.CORBA package version with the one provided by JacORB which uses the ContextClassLoader of the current Thread instead (the same as the pre u55 code has done).

Another option is to use eg -Xbootclasspath/p:${jacorb/lib/jar-containing-omg-api.jar} or copy the JARs containing JacORB's version of org.omg.CORBA to <jre-home>/lib/endorsed .

Unfortuantelly this doesn't helped for my Webstart application problem.

Do you need the system-wide/singleton ORB to be the Jacorb ORB? If not then the simplest solution here might be to just drop -Dorg.omg.CORBA.ORBSingletonClass from the command line. Remember the singleton ORB is just the TypeCode factory, your call to the 2-arg ORG.init will still give a Jacorb ORB because you have org.omg.CORBA.ORBClass set to select it.

The (recently updated, as this information wasn' there before) release notes mentioned by user3054250 (thank you for this) point to another possible workaround. Specifying only the ORB property but omiting ORBSingleton works (short test) in my CORBA/Webstart application together with JacORB 3.4.

It doesn't work with OpenORB (as OpenORB checks for the "right" instance of ORBSingleton) so I have to upgrade my application to JacORB but it is a solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM