开发者

ClassNotFoundException for class file on classpath

I have the following code:

    // Test TODO remove
    try {
        System.out.println(System.getProperties().getProperty("java.class.path"));
        this.getClass().getClassLoader().loadClass("mypackage.MyClass");
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }开发者_Go百科

Now the output shows me, that the class is on the classpath, i.e.:

/...some/path.../workspace/project/target/test-classes:/rest/of/the/classpath
java.lang.ClassNotFoundException: mypackage.MyClass
        ...here be stacktrace...

I also made sure, that the class-file acutaly IS in the given location, i.e. this file exists:

/...some/path.../workspace/project/target/test-classes/mypackage/MyClass.class

Maybe the following is important: the shown code is executed in a javaagent attached to a jUnit test, that I start programtically (via Runtime.execute(...)) - so there is probably something beyond the obvious that can go wrong in the background... but still: if the classpath contains the folder with the class, how come it cannot be loaded?


The Java agent is loaded early in starting the JVM (for obvious reasons) and has its own "classpath", so it isn't actually loaded by the (historically named) system class loader. That is why you have a 'jarpath' as part of the command line argument.

SO you will need something like System.getSystemClassLoader, URLClassLoader.newInstance (with java.class.path) or Thread.getContextClassLoader depending upon your circumstances.


For all who are interested: I have no idea what the problem was.

I fiddled a bit with it, and it turned out that the command string that was executed by Runtime.exec(...) worked well if executed in the shell.

I fiddled a bit more, but finally gave up searching for the "real" reason. Instead of

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(command);

I now use apache exec:

CommandLine commandLine = CommandLine.parse(command);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(commandLine);

with the exact same command String, and all of a sudden it woks!


You assume that if the target bytecode remains at classpath corresponding class can be loaded by the current class's class loader. However, that is not the case if current class is loaded by tricky/buggy class loader.

I'd suggest to do the following:

  1. Check the used class loader:

    System.out.println(this.getClass().getClassLoader());
    System.out.println(ClassLoader.getSystemClassLoader() == this.getClass().getClassLoader());
    this.getClass().getClassLoader().loadClass("mypackage.MyClass");
    
  2. Provide minimal but complete reproducible test-case that illustrates the problem

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜