ClassNotFoundException for class file on classpath

喜欢而已 提交于 2019-12-14 03:52:04

问题


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();
    }

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?


回答1:


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.




回答2:


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!




回答3:


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



来源:https://stackoverflow.com/questions/1565804/classnotfoundexception-for-class-file-on-classpath

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!