1

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.

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

15 Comments

If I inject it with java.system.class.loader, are other classes still loaded with the default ClassLoader?
You'll have to make sure that your own class loader delegates to its parent for any non-swt class.
Alright, I found some more information here: coderanch.com/t/384068/java/java/Adding-JAR-file-Classpath-at . How do I set that property (java.system.class.loader) before the program starts?
You can set a system property by adding the following command line argument: -Djava.system.class.loader=com.mycompany.MyClassLoader . Note that this argument has to be set before your own program arguments (if any) but after the Xmx/Xms stuff.
Can I set it in the MANIFEST? If so, how?
|
0

As part of the constructor for your custom ClassLoader, call definePackage with the appropriate information, with the URL pointing to the desired jar file.

This example shows that the custom class loader is called when I try to instantiate a class from swing, because I defined my class loader as the loader of that package.

import java.net.URL;

public class junk extends ClassLoader {

  byte[] dummy = new byte[0];

  public static void main(String[] args) throws Exception {
    new junk();

    new javax.swing.JPanel();

  }

  public junk() throws Exception {
    definePackage("javax.swing","","","","","","",new URL("file://junk.class"));
  }

  public Class<?> findClass(String s) throws java.lang.ClassNotFoundException{
    Class<?> retVal = super.findClass(s);

    System.out.println("delegated responsibility for "+s+" to superclass");

    return retVal;
  }

  public Package getPackage(String s) {
    Package retVal = super.getPackage(s);

    System.out.println("delegated responsibility for "+s+" to superclass");

    return retVal;
  }

}

Result:

delegated responsibility for javax.swing to superclass

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.