Classloading differences between eclipse and standalone Equinox [message #98271] |
Tue, 25 September 2007 18:56 |
Michael Furtak Messages: 5 Registered: July 2009 |
Junior Member |
|
|
I have been developing some Equinox powered code using Eclipse. This code uses Swing heavily. Recently, I've been putting together an external deployment shell so that the application can be run without Eclipse. I am running into some problems with code that works when run through Eclipse, but not when run standalone with Equinox.
Just to clarify, when running standalone with Equinox, I mean invoking <i>java -jar org.eclipse.osgi_3.3.0.v20070530.jar</i> with the appropriate <i>config.ini</i> on hand.
Here's a short example that illustrates my problems:
First, I have some third party library that does some Swing specific stuff. This is packaged into a standard Java JAR called <b>third-party.jar</b>.
package com.cra.example;
import javax.swing.UIManager;
import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
public class ThirdPartyLib
{
public static boolean isWindowsLAF()
{
return UIManager.getLookAndFeel() instanceof WindowsLookAndFeel;
}
}
I also have an Eclipse plug-in project targeted for Equinox with the following activator and manifest file:
package com.cra.example;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator
{
public void start(BundleContext context) throws Exception
{
System.out.println(ThirdPartyLib.isWindowsLAF());
}
public void stop(BundleContext context) throws Exception
{
}
}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Problem_plug_in Plug-in
Bundle-SymbolicName: problem_plug_in
Bundle-Version: 1.0.0
Bundle-ClassPath: lib/third-party.jar,
.
Bundle-Activator: com.cra.example.Activator
Import-Package: org.osgi.framework;version="1.4.0"
Eclipse will run this plugin with no problem and print <b>false</b> on the console. When run with Equinox from the command line, it will die with the following cause:
Caused by: java.lang.NoClassDefFoundError: javax/swing/UIManager
at com.cra.example.ThirdPartyLib.isWindowsLAF(ThirdPartyLib.java:17)
at com.cra.example.Activator.start(Activator.java:17)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
... 10 more
Ok, so that package can't be found. When I add javax.swing to the imports, the Eclipse run still works, but the command line method fails again with a different class - this time over the WindowsLookAndFeel.
Caused by: java.lang.NoClassDefFoundError: com/sun/java/swing/plaf/windows/WindowsLookAndFeel
at com.cra.example.ThirdPartyLib.isWindowsLAF(ThirdPartyLib.java:17)
at com.cra.example.Activator.start(Activator.java:17)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
... 10 more
Hmm.. now I've hit a snag, because I can't import that package through the Eclipse PDE. I try adding DynamicImport-Package: * to the manifest file, but that does not help. What does seem to help, though, is adding the following to my config.ini file:
org.osgi.framework.bootdelegation=*
From the Eclipse documentation:
"To revert back to the behavior in 3.2 the configuration property "org.osgi.framework.bootdelegation=*" can be added to the config.ini file."
"In 3.2 the boot (parent) class loader is always delegated to first. This provides no isolation from the classes provided by the VM. It also affects performance because the boot class loader must be delegated to for every load even though it is known that the class or resource is located in a bundle."
So, my question is this: What is Eclipse doing differently than the standalone Equinox? Both are running from the same copy of the framework JAR file (that ships with Eclipse 3.3). The bootdelegation trick fixes my problem, but I don't like the idea of introducing the performance penalty if it's not necessary.
Any help would be appreciated. Thanks,
-Mike
|
|
|
|
Re: Classloading differences between eclipse and standalone Equinox [message #98333 is a reply to message #98289] |
Wed, 26 September 2007 19:33 |
Michael Furtak Messages: 5 Registered: July 2009 |
Junior Member |
|
|
Hi Tom,
Thank you very much for your explanation of the differences in the boot classloading processes. That made things much clearer.
I have tried the various options you mentioned...
osgi.compatibility.bootdelegation=true in my config.ini does not seem to work (where org.osgi.framework.bootdelegation=* did), but including it as a VM arg at launch (-Dosgi.compatibility.bootdelegation=true) worked as stated.
Since I expect developers to be creating and debugging plugins for my system through Eclipse for Equinox, I will probably leave it at that, so that they have a consistent experience in development and deployment. Just to be 100% clear, though, that flag is Equinox only (not part of the OSGi spec,) right?
Still, I checked out the other solution as well...
The Fragment approach worked, but requires some extra work, because it seems that the Eclipse PDE will not allow you to specify Export-Package for packages not on the bundle classpath. (e.g. com.sun.java.swing.plaf.windows) Since it's treated as an error, you can't build the JAR with the Export utility, making for some manual JAR construction. Is this known/intended behavior?
Thanks,
-Mike
|
|
|
Powered by
FUDForum. Page generated in 0.03743 seconds