Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » Howto add an external jar dynamically to an eclipse plugin's classpath during runtime
Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #637459] Fri, 05 November 2010 15:22 Go to next message
No real name is currently offline No real name
Messages: 1
Registered: November 2010
Junior Member
Hello,

one of my eclipse plugin (eclipse version 3.6.2) depends on an
external jar file which I may not include in my package because it's
proprietary third party software. The location of this file may vary
depending on where the user installs the 3dparty software in his
windows installation. During runtime I'm able find the location of the
jar file, but I don't know how to add it to the plugin's classpath. It
is not used outside of my plugin and therefore has not to be visible
to the outside.

I tried to use my own class loader (URLClassLoader) but couldn't
figure out how to make that approach working. I could load each single
Java class explicitly, but that does not resolve the loading problems
inside of the external jar file. Automatic loading was not working
because always the DefaultClassLoader was used, not the new one. I
tried to set the contextClassLoader, too, without success.

I also tried to stop the plugin from the outside (another plugin),
modify its Manifest by adding the jar file as "external:" to the
Bundle-Classpath and start it again. That approach didn't work either.
The new Manifest simply was not read.

Yet another approach was to use reflection to get access to the
private "addUrl" method of the ClassLoader as written in some
tutorials. But this method is only available in the URLClassloader not
in the DefaultClassLoader of eclipse.

Another thing I thought about was to copy the jar file during startup
to the eclipse plugin dir. I think that would not violate the license
restrictions because I would not deliver the file.

But I still wonder if there is no simple way to achieve my rather
simple task?

Can anybody help?

Thanks a lot!
Eike
Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #637480 is a reply to message #637459] Fri, 05 November 2010 16:54 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

eike.thaden@web.de wrote:
> Hello,
>
> I also tried to stop the plugin from the outside (another plugin),
> modify its Manifest by adding the jar file as "external:" to the
> Bundle-Classpath and start it again. That approach didn't work either.
> The new Manifest simply was not read.

What you need to do is provide it as a separate existing plugin that
represents your 3rd party plugin, and have *that* contain the
"external:" entry. Then it will be correctly read into the system (I
don't believe you can effect the change in the existing bundle while the
system is running).

external: can take a property that can be passed in through
-Dprop=/location to handle the install location of the 3rd party jar on
the user system

PW



--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Platform_Expression_Framework
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


icon5.gif  Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #640995 is a reply to message #637480] Tue, 23 November 2010 19:25 Go to previous messageGo to next message
Dan  is currently offline Dan
Messages: 9
Registered: November 2010
Junior Member
I have a similar requirement for my plugin so I tried the recommended technique. Both the primary plugin and the library plugin build and deploy appropriately, but I still get a NoClassDefFoundError at runtime.

I'm using Eclipse version 3.5.2.

My primary plugin references the library plugin in the manifest and the library plugin references the external jars via entries such as this:

external:D:/dev/tools/JBoss/jboss-5.1.0.GA/client/jboss-syst em-client.jar,

(one for each jar in the jboss client library)

The plugin works fine if all the jars are copied to lib folder in primary plugin, but not when referenced externally.

Any help would be greatly appreciated!

[Updated on: Tue, 23 November 2010 19:27]

Report message to a moderator

Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #641001 is a reply to message #640995] Tue, 23 November 2010 19:57 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

I'd add a breakpoint in
org.eclipse.core.runtime.internal.adaptor.EclipseClassLoadin gHook.addClassPathEntry(ArrayList <ClasspathEntry>,
String, ClasspathManager, BaseData, ProtectionDomain) in the
org.eclipse.osgi plugin to see that your external: setting are being
recognized.

PW

--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Platform_Expression_Framework
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #641035 is a reply to message #641001] Wed, 24 November 2010 01:11 Go to previous messageGo to next message
Dan  is currently offline Dan
Messages: 9
Registered: November 2010
Junior Member
Thanks for the clue.

After debugging into addClassPathEntry, I found that the library plugin was not being loaded. So I forced it to load by calling it's Activator and then saw the external entries getting added to cpEntries.

However, I still get the NoClassDefFoundError. Any idea where I should look next?

What might be setup wrong that's causing me to force load the library bundle? Shouldn't this load automatically?
Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #641262 is a reply to message #641035] Wed, 24 November 2010 16:09 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Dan wrote:
> Thanks for the clue.
> After debugging into addClassPathEntry, I found that the library plugin
> was not being loaded. So I forced it to load by calling it's Activator
> and then saw the external entries getting added to cpEntries.

You need to have this in your manifest:
Bundle-ActivationPolicy: lazy

Then the first time another bundle tries to access one of your classes,
your bundle will be activated and loaded correctly.

Are there any errors or exceptions thrown during activation? An
exception during bundle activation would kill that bundle, and from then
on nothing could load classes for it. If you run with -consoleLog they
should appear on stdout.

PW

--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Platform_Expression_Framework
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #641312 is a reply to message #641262] Wed, 24 November 2010 21:07 Go to previous messageGo to next message
Dan  is currently offline Dan
Messages: 9
Registered: November 2010
Junior Member
Ok, I verified that both plugins have the following line in MANIFEST.MF:

Bundle-ActivationPolicy: lazy

Also, I don't see any errors or exceptions during activation. I checked the loaded bundles via use of the ss command in the osgi console and found the primary bundle was loaded with the ACTIVE state and the library bundle was in the <<LAZY>> state. After running code that uses JBoss classes (which are externally referenced in the library bundle), the library bundle is still in the <<LAZY>> state, and of course I still get the ClassNotFoundException.

NOTE: I was getting a NoClassDefFoundError exception when I was attempting to use a custom ClassLoader. When I stopped trying that approach, the exception changed to ClassNotFoundException.
Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #641431 is a reply to message #641312] Thu, 25 November 2010 12:53 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

When you check the bundles from the OSGi console, can you see the link
between your bundle that uses JBoss classes and your library (external:)
plugin?

Something else you can try is to run with OSGi debugging information.
ex, for a runtime:

$ jar xvf
/isntallDir/eclipse/plugins/org.eclipse.osgi_3.7.0.v20101119 .jar .options
$ mv .options debug.osgi
# vi debug.osgi
$ eclipse -debug debug.osgi >osgi_log.txt 2>&1

Then turn on
org.eclipse.osgi/debug=true
and any other options that seem to indicate classloading or package access.

Warning, it will print out *a lot* of information, that's why you need
to save it to a log and look through it later :-)


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Platform_Expression_Framework
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #642080 is a reply to message #641431] Mon, 29 November 2010 18:29 Go to previous messageGo to next message
Dan  is currently offline Dan
Messages: 9
Registered: November 2010
Junior Member
Thanks for the pointers.
In the OSGI console, I used the headers command and found the library plugin as a required bundle for the primary plugin. Also, I see the JBoss library jars on the classpath of the library plugin.

When I setup the debug configuration in the manner you recommended, I get a nice big (23 MB) log file. Scanning through the log file, I can see the library bundle get wired to the primary bundle, but the library bundle's classloader doesn't get used when trying to load org.jboss.naming.NamingContextFactory. I get the following messages in the log:

BundleClassLoader[primary.bundle_1.0.0].loadClass(org.jboss. naming.NamingContextFactory)
BundleLoader[primary.bundle_1.0.0].loadBundleClass(org.jboss .naming.NamingContextFactory)
BundleLoader[primary.bundle_1.0.0].findLocalClass(org.jboss. naming.NamingContextFactory)
BundleClassLoader[D:\dev\tools\Eclipse\eclipse-jee-galileo-S R1-win32\eclipse\plugins\primary.bundle_1.0.0].findClass(org .jboss.naming.NamingContextFactory)
BundleClassLoader[primary.bundle_1.0.0].loadClass(org.jboss. naming.NamingContextFactory) failed.

Is there anything else that should be in the log file that may be helpful in the analysis?
Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #642116 is a reply to message #641431] Mon, 29 November 2010 22:00 Go to previous messageGo to next message
Dan  is currently offline Dan
Messages: 9
Registered: November 2010
Junior Member
So... could the issue be something simple? Is there a way to make my library "dependent" on the JBoss client library jars instead of just putting them on the classpath? It appears the classloader doesn't know that it should be getting the class from the library bundle's classpath, and maybe having a dependency would resolve the issue?
icon7.gif  Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #642131 is a reply to message #641431] Tue, 30 November 2010 01:31 Go to previous messageGo to next message
Dan  is currently offline Dan
Messages: 9
Registered: November 2010
Junior Member
Ok, I found the folly of my ways. Export-Package in the manifest must contain all of the jboss packages.

I decided to recreate the library plugin by using New->Other->Plug-in Development->Plug-in from Existing JAR Archives. I selected all of the JBoss client jars and created the project. This process setup the manifest file with all of the (~1500) JBoss packages. Then I removed the jars from the project, and changed the Bundle-ClassPath to refer to the external location for each jar instead of the plugin location (ie external:D/jboss/client/jboss-commons-core.jar).

This worked perfectly during runtime!

However, I now have a couple of new issues:

1) The manifest.mf file shows an error for each entry in Export-Package: "Package xxx does not exist in the plugin". Though the plugin builds and deploys without error, the red X's are disconcerting. Any ideas on how to eliminate these?

2) I tried using a variable for the location of the jars as was suggested in a previous post in this thread. The variable seems to work fine at build time, but not at runtime. I added it to the eclipse.ini file after -vmargs.
-vmargs
-DJBOSS_HOME=D:/dev/tools/JBoss/jboss-5.1.0.GA

Any thoughts on what might be wrong here?

Thanks much for your help,
Dan
Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #642236 is a reply to message #642131] Tue, 30 November 2010 14:06 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Dan wrote:
> However, I now have a couple of new issues:
>
> 1) The manifest.mf file shows an error for each entry in Export-Package:
> "Package xxx does not exist in the plugin". Though the plugin builds and
> deploys without error, the red X's are disconcerting. Any ideas on how
> to eliminate these?

You might be able to set project settings. Select the project and bring
up Properties. Go to Plug-in Development>Plug-in Manifest Compiler. If
you make them project specific settings, can you ignore missing exported
packages?

>
> 2) I tried using a variable for the location of the jars as was
> suggested in a previous post in this thread. The variable seems to work
> fine at build time, but not at runtime. I added it to the eclipse.ini
> file after -vmargs.
> -vmargs
> -DJBOSS_HOME=D:/dev/tools/JBoss/jboss-5.1.0.GA

that should be OK, if you have external:$JBOSS_HOME$/lib/their.jar

PW


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Platform_Expression_Framework
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


icon14.gif  Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #642338 is a reply to message #642236] Tue, 30 November 2010 20:34 Go to previous messageGo to next message
Dan  is currently offline Dan
Messages: 9
Registered: November 2010
Junior Member
Most Excellent. Thanks for your help!

Eclipse 3.5.1 doesn't have settings for a Plug-in Manifest Compiler, but it does have Plug-in Development->Compilers->Usage->Unresolved dependencies. I changed this to ignore for my library plugin and it eliminated the errors.

Also, Eclipse 3.5.1 has an issue with the script that builds the plugins via File->Export->Deployable plug-ins and fragments. The script interprets variables in this form ${variable}, but the runtime needs the variable in the form $variable$. So after I exported the plugin, I manually edited the manifest.mf file and it worked.

Have these issues been resolved in more current versions of eclipse (or the PDE plugin)?

Note: another tweak I added was to set the java system property to the environment variable in the library's Bundle-Activator (start method):

System.setProperty("JBOSS_HOME", System.getenv("JBOSS_HOME"));

This eliminates the need to mess with eclipse.ini for developers who only need to use the plugin. Still need to set it in eclipse.ini to build the library plugin.
Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #642451 is a reply to message #642338] Wed, 01 December 2010 12:32 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Dan wrote:
>
> Also, Eclipse 3.5.1 has an issue with the script that builds the plugins
> via File->Export->Deployable plug-ins and fragments. The script
> interprets variables in this form ${variable}, but the runtime needs the
> variable in the form $variable$. So after I exported the plugin, I
> manually edited the manifest.mf file and it worked.

I'll just point out they're 2 different things. The variable used in
the external: URI is $VAR$ and it expects to find VAR as an eclipse
system property.

In development you can run eclipse with -DVAR=... to make it available
for development (and add -DVAR= to launch configs for testing).


Another option might be to fiddle with the Build tab of your manifest,
add them as "Extra Classpath Entries" needed for compiling ... maybe
that'll work?

> Note: another tweak I added was to set the java system property to the
> environment variable in the library's Bundle-Activator (start method):
>
> System.setProperty("JBOSS_HOME", System.getenv("JBOSS_HOME"));

This won't work in 1.4.x (although that's becoming less and less of a
problem :-) but there is the issue that it must be done before the first
access by the OSGi framework that will try and resolve JBOSS_HOME in the
bundle classpath. I wouldn't bet on it working in the field :-)

Later,
PW


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Platform_Expression_Framework
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #642619 is a reply to message #642451] Thu, 02 December 2010 02:10 Go to previous messageGo to next message
Dan  is currently offline Dan
Messages: 9
Registered: November 2010
Junior Member
Ok, that makes alot of sense, though it seems a bit strange that the build even works when the external:${variable} form is used. So, I tried using the following:

extra.. = ${env.JBOSS_HOME}/client/commons-logging.jar,\
${env.JBOSS_HOME}/client/jboss-common-core.jar,\
etc...

No go. Appears that I need to set:
<property environment="env"/>
in build.xml for this to work. But, build.xml is generated as part of the export process, so I don't know where to set it. Am I doing this correctly? Is there something else I should be modifying?

In regards to my tweak, wouldn't the Activator be called, and thus the variable set, before OSGI tries to resolve a class contained in the bundle? Theoretically, is there anytime this wouldn't occur?

Thanks again for all of your thoughts and help.
Dan
Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #643317 is a reply to message #642619] Mon, 06 December 2010 13:26 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

AFAIK you have to deal with the 3 issues separately.

1) get it compiling in your workspace. For that, the extra "libs" you
need to compile should work.

2) to get it running, you can add -DJBOSS_HOME to your launch config so
that the bundle manifest can find the libs when using $JBOSS_HOME$

3) For building, I use PDE headless build. That probably means
specifying extra libs in the pde build.properties somewhere.

I'm not sure what "export" you are using. Deploying a product from a
..product file? To get that to work, you'd probably have to reconcile
steps 1 and 2 somehow.

PW



--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Platform_Expression_Framework
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #643432 is a reply to message #643317] Mon, 06 December 2010 20:09 Go to previous messageGo to next message
Dan  is currently offline Dan
Messages: 9
Registered: November 2010
Junior Member
Thanks Paul, but I'm still having problems. Sorry to be such a problem child. Embarrassed


> 1) get it compiling in your workspace. For that, the extra "libs" you
> need to compile should work.

I'm not sure what you mean here. How do I refer to the extra libs?
Should putting the following in my build.properties file of the library plugin do it?

extra.. = ${env.JBOSS_HOME}/client/commons-logging.jar,\
${env.JBOSS_HOME}/client/jboss-common-core.jar,\
etc...

Currently, I get the main plugin to compile by putting the JBoss libraries on the Java Build Path.

> 2) to get it running, you can add -DJBOSS_HOME to your launch config so
> that the bundle manifest can find the libs when using $JBOSS_HOME$

Yes, this works fine.

> 3) For building, I use PDE headless build. That probably means
> specifying extra libs in the pde build.properties somewhere.

I haven't tried the PDE headless build before. Any recommended reading for instructions? I'd rather build from the eclipse UI if possible.

> I'm not sure what "export" you are using. Deploying a product from a
> ..product file? To get that to work, you'd probably have to reconcile
> steps 1 and 2 somehow.

I've been using File->Export->Deployable plug-ins and fragments to build and deploy my plugins. Seems to work fine except for interpreting the variable for the library location in extra.. = ${env.JBOSS_HOME}/...

Any help in clarifying these issues would be greatly appreciated.
Re: Howto add an external jar dynamically to an eclipse plugin's classpath during runtime [message #643558 is a reply to message #643432] Tue, 07 December 2010 12:30 Go to previous message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Dan wrote:
>
> I've been using File->Export->Deployable plug-ins and fragments to build
> and deploy my plugins. Seems to work fine except for interpreting the
> variable for the library location in extra.. = ${env.JBOSS_HOME}/...
>
> Any help in clarifying these issues would be greatly appreciated.

Unfortunately this has exhausted my knowledge of what PDE UI should be
doing :-) I would try posting your question to the eclipse.pde newsgroup.

Later,
PW

--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Platform_Expression_Framework
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Previous Topic:Helios: Can't terminate application, then can't exit Eclipse
Next Topic:Eclipse Closed automatically
Goto Forum:
  


Current Time: Sat Oct 25 22:08:43 GMT 2014

Powered by FUDForum. Page generated in 0.02674 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software