Adding jars from file system to runtime classpath [message #334112] |
Wed, 21 January 2009 06:08  |
Eclipse User |
|
|
|
Hi,
we have developed an IDE using eclipse 3.4 and dltkS1.0M3.
we are using a jar containing xml files at runtime.
For that we include jars in Manifest.MF/runtime classpath of the plugin,so
that at runtime the xml files will be loaded from the classpath.
Now our requirement is, instead of keeping the jar inside the plugin ,we
want
to keep the jars in a file system and add them to the classpath at
runtime.So that user can place jars into that directory.
How do we achieve it?
Regards,
Sheela
|
|
|
|
|
|
Re: Adding jars from file system to runtime classpath [message #334165 is a reply to message #334164] |
Thu, 22 January 2009 15:57  |
Eclipse User |
|
|
|
I've this nasty part of code. Two classed that combined allow you to load
every jar includes in one directory. You have to put your application code
inside the execute() methos of thr AbstractSystemClassLoader. In my case
every jar inside a plugin is getting added. but this can changed easily ...
The abstract class you may used nested:
AbstractSystemClassLoaderExecutable executable = new
AbstractSystemClassLoaderExecutable(){
@Override
protected boolean execute() {
// do thomething (best done using Display.asyncExec())..
}
});
The classes:
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.FileLocator;
import swl.lib.util.ClassPathHacker;
/**
* This class enables executing code in eclipse using the java standard
class loader.
* As default the "lib" directory within the plugin is added to the
classpath.
* @author jko
*
*/
public abstract class AbstractSystemClassLoaderExecutable {
private static boolean CLASSPATH_LOADED = false;
private boolean executionSuccessfull = true;
public AbstractSystemClassLoaderExecutable() {
Thread current = Thread.currentThread();
ClassLoader oldLoader = current.getContextClassLoader();
try {
// Standard classloader setzten.
current.setContextClassLoader(ClassLoader.getSystemClassLoad er());
// Der Klassenpfad wird nur einmal geladen
if (!CLASSPATH_LOADED){
loadClasspath();
}
// Ausführen des Codes
execute();
} catch (IOException e) {
e.printStackTrace();
}finally {
// Eclipse classloader wieder aktivieren.
current.setContextClassLoader(oldLoader);
}
}
private void loadClasspath() throws IOException{
// Pluginlocation.
URL pluginURL =
FileLocator.toFileURL(XslProcessorPlugin.getDefault().getBun dle().getEntry( "/"));
// Alle Datein im lib Verzeichnis auflisten
Enumeration<String> jars =
XslProcessorPlugin.getDefault().getBundle().getEntryPaths("lib ");
// Pattern für "jar" Datein.
Pattern p = Pattern.compile( "(.*\\.jar$)", Pattern.CASE_INSENSITIVE );
while (jars.hasMoreElements()){
String jar = jars.nextElement();
if (p.matcher(jar).matches()){
// Die tatsächliche Position nocheinmal auflösen
String fileString = FileLocator.resolve(new
URL(pluginURL.toExternalForm() + jar)).getFile();
File file = new File(fileString);
// und hinzufügen.
ClassPathHacker.addFile(file);
}
}
CLASSPATH_LOADED = true;
}
abstract protected boolean execute();
public boolean isExecutionSuccessfull() {
return executionSuccessfull;
}
}
You'll need this class as well (its from somewehere in the internet and
overrides the system classloader using java reflection):
import java.lang.reflect.*;
import java.io.*;
import java.net.*;
public class ClassPathHacker {
private static final Class[] parameters = new Class[] { URL.class };
public static void addFile(String s) throws IOException {
File f = new File(s);
addFile(f);
}// end method
public static void addFile(File f) throws IOException {
addURL(f.toURL());
}// end method
public static void addURL(URL u) throws IOException {
URLClassLoader sysloader = (URLClassLoader) ClassLoader
.getSystemClassLoader();
Class sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(sysloader, new Object[] { u });
} catch (Throwable t) {
t.printStackTrace();
throw new IOException(
"Error, could not add URL to system classloader");
}// end try catch
}// end method
}// end class
take in minde, that this solution may not work with future java versions
since the API used in ClassPathHacker is private and may change.
Have fun.
Jan
|
|
|
Powered by
FUDForum. Page generated in 0.03029 seconds