My application uses the Standard Widget Toolkit (SWT) for it's GUI. My problem is that the 32-bit SWT library does not work on a 64-bit JVM. But I don't want to make people select the correct architecture when getting the software. So, I want to bundle both the 32-bit and 64-bit libraries, and auto-detect the architecture during runtime. I found out I can get the correct architecture of the JVM like so:
if (System.getProperty("os.arch").contains("64")) {
// ...
}
Now all that's left is to load the jar. But the problem is, all the examples I found require that you manually load the class before using it.
Class.forName("MyClass", false, myClassLoader);
So my question is, is it possible to "register" my class loader, so that I don't have to load classes beforehand?
Update: I created my own child class of URLClassLoader
and set it as the default class loader with the command line argument -Djava.system.class.loader
; but I get this error:
Error occurred during initialization of VM
java.lang.Error: java.lang.NoSuchMethodException: com.program.LibraryLoader.<init>(java.lang.ClassLoader)
at java.lang.ClassLoader.initSystemClassLoader(Unknown Source)
at java.lang.ClassLoader.getSystemClassLoader(Unknown Source)
I think LibraryLoader.<init>
refers to the constructor... but it's there (public LibraryLoader(URI[] urls)
).
Update 2: Almost there, the JVM runs now. I added this constructor to make it work:
public LibraryLoader(ClassLoader classLoader) {
super(new URL[0], classLoader);
}
But after adding the jars with addPath()
(file:lib/jars/swt.jar
), it only produces a NoClassDefFoundError
. Yes, I double-checked that the file exists.
You could try to inject your custom class loader by means of the "java.system.class.loader" property (see ClassLoader#getSystemClassLoader). However, I'd recommend to use OSGi and let the framework do the complicated stuff.