Search code examples
javaclassnotfoundexceptionmax-msp-jitter

ClassNotFoundError when I run the class outside of eclipse


I currently try to run java code in Maxmsp using a mxj object, and I want to load some classes inside of the code. But I always get the errors, although the code runs properly in eclipse.

What is the problem?

This is my code. If I bang in Maxmsp, call() will be called.

package Load;

import com.cycling74.max.*;

public class Loaded extends MaxObject{
    public static void main(String[] args) {
        //This works properly in eclipse
        call();
    }

    public void bang() {
        //This should work in Maxmsp, but get errors
        call();
    }

    public static void call() {
        try {
             //this is just a example
             //I want to load some classes which locate the same directory as this class
            Thread.currentThread().getContextClassLoader().loadClass("Load.Loaded");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

And this is the error message:

java.lang.ClassNotFoundException: Load.Loaded
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at Load.Loaded.call(Loaded.java:21)
    at Load.Loaded.bang(Loaded.java:16)

MXJ System class path is:

/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/commons-codec-1.11.jar:
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/core.jar:
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/gluegen-rt-natives-macosx-universal.jar:
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/gluegen-rt.jar:
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/jitter.jar:
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/jode-1.1.2-pre-embedded.jar: 
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/jogl-all-natives-macosx-universal.jar: 
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/jogl-all.jar: 
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/max.jar: 
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/lib/sadamLib.jar

MXJ Classloader CLASSPATH is:

/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/classes/
/Applications/Max.app/Contents/Resources/C74/packages/max-mxj/java-classes/
/Users/MyName/Documents/ecllipse-workspace/009_Processing/bin

Loaded.class is in /Users/MyName/Documents/ecllipse-workspace/009_Processing/bin


Solution

  • The problem was what Max cannot load class properly. So I created class loader method.

    public static ClassLoader createClassLoader(String dirname) throws java.io.IOException {
        java.net.URL[] url = new java.net.URL[1];
        java.io.File file;
        if (dirname.endsWith("/")) {
            file = new java.io.File(dirname);
        }
        else {
            file = new java.io.File(dirname + "/");
        }
        url[0]= file.toURI().toURL();
    
        ClassLoader parent = ClassLoader.getSystemClassLoader();
        java.net.URLClassLoader loader = new java.net.URLClassLoader(url, parent);
        return loader
    }
    

    And call

    ClassLoader loader = createClassLoader("ClassPath");
    Class<?> c = Class.forName("Classname", true, loader);