我有以下代码:
// 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();
}
现在输出显示,该类在类路径上,即:
/...some/path.../workspace/project/target/test-classes:/rest/of/the/classpath
java.lang.ClassNotFoundException: mypackage.MyClass
...here be stacktrace...
我也确定,类文件acutaly IS在给定位置,即此文件存在:
/...some/path.../workspace/project/target/test-classes/mypackage/MyClass.class
可能以下内容很重要:所显示的代码在附加到jUnit测试的javaagent中执行,我以程序方式启动(通过Runtime.execute(...)) - 所以可能会出现明显的问题在后台错了...但仍然:如果类路径包含该类的文件夹,为什么它无法加载?
答案 0 :(得分:4)
Java代理在启动JVM的早期加载(出于显而易见的原因)并且有自己的“类路径”,因此它实际上并没有被(历史上命名的)系统类加载器加载。这就是为什么你有一个'jarpath'作为命令行参数的一部分。
因此,根据您的情况,您需要System.getSystemClassLoader
,URLClassLoader.newInstance
(java.class.path
}或Thread.getContextClassLoader
等内容。
答案 1 :(得分:1)
对所有感兴趣的人: 我不知道问题是什么。
我对它进行了一些调整,结果发现Runtime.exec(...)执行的命令字符串在shell中执行时运行良好。
我摆弄了一点,但最终放弃了寻找“真正”的理由。而不是
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(command);
我现在使用apache exec:
CommandLine commandLine = CommandLine.parse(command);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(commandLine);
使用完全相同的命令字符串,突然间它就开始了!
答案 2 :(得分:0)
您假设如果目标字节码保留在类路径中,则相应的类可以由当前类的类加载器加载。但是,如果当前的类被棘手/错误的类加载器加载,情况就不是这样了。
我建议你做以下事情:
检查使用过的类加载器:
System.out.println(this.getClass().getClassLoader());
System.out.println(ClassLoader.getSystemClassLoader() == this.getClass().getClassLoader());
this.getClass().getClassLoader().loadClass("mypackage.MyClass");
提供最小但完整的可重现的测试用例,以说明问题