Search code examples
javaclassloaderurlclassloader

Java: Automatic Custom ClassLoader


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.


Solution

  • 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.