我正在尝试使用Class.forName()
加载类,但它给了我异常java.lang.ClassNotFoundException: Test
。
实际上Test
是在eclipse工作目录here is the image中创建的,但它是在bin文件夹之外创建的。
如果我尝试使用命令提示符运行它正常工作。
:
public class CompileString {
public static void main(String arges[]) throws Exception{
JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();
String program = " class Test{" + " public static void main (String [] args){"
+ " System.out.println (\"Hello, World\");"
+ " System.out.println (args.length);" + " }" + "}"
+"interface demo{}"
;
Iterable<? extends JavaFileObject> fileObjects;
fileObjects = getJavaSourceFromString(program);
Boolean result=compiler.getTask(null, null, null, null, null, fileObjects).call();
System.out.println(result);
Class<?> clazz=null;
try {
clazz = Class.forName("Test");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println(clazz);
e.printStackTrace();
}
Method m = clazz.getMethod("main", new Class[] { String[].class });
Object[] _args = new Object[] { new String[0] };
m.invoke(null, _args);
}
static Iterable<JavaSourceFromString> getJavaSourceFromString(String code) {
final JavaSourceFromString jsfs;
jsfs = new JavaSourceFromString("demo", code);
return new Iterable<JavaSourceFromString>() {
public Iterator<JavaSourceFromString> iterator() {
return new Iterator<JavaSourceFromString>() {
boolean isNext = true;
public boolean hasNext() {
return isNext;
}
public JavaSourceFromString next() {
if (!isNext)
throw new NoSuchElementException();
isNext = false;
return jsfs;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
}
另一类:
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
它给了我运行时异常
java.lang.ClassNotFoundException:Test
所有正常工作的编译器JavaCompiler compiler=ToolProvider.getSystemJavaCompiler()
都会true
,但为什么我找不到Test.class
。
答案 0 :(得分:1)
Eclipse在与程序运行的目录不同的目录中生成类文件,而当您从命令行运行它时,您使用相同的值。
解决此问题的最简单方法是使用URLClassLoader加载类,以便指定用于查找类文件的目录。
import java.io.File;
import java.io.IOException;
import java.lang.reflect.*;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URLClassLoader;
import java.util.*;
import java.util.logging.Logger;
import javax.tools.*;
public final class CompileString {
static class JavaSourceFromString extends SimpleJavaFileObject {
private final String code;
JavaSourceFromString(final String name, final String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(final boolean ignoreEncodingErrors) {
return code;
}
}
private CompileString() {}
private static final Logger LOG = Logger.getLogger(CompileString.class.getCanonicalName());
private static final JavaCompiler COMPILER = ToolProvider.getSystemJavaCompiler();
public static void main(final String...args) {
final String program =
"public class Test{" +
" public static void main (String [] args) {" +
" System.out.println (\"Hello, World\");" +
" System.out.println (args.length);" +
" }" +
"}";
final List <JavaSourceFromString> fileObjects = List.of(new JavaSourceFromString("Test", program));
final boolean result = COMPILER.getTask(null, null, null, null, null, fileObjects).call();
LOG.info("Compilation result was: " + result);
final URL url;
try {
url = new File("./").toURI().toURL();
} catch (final MalformedURLException ex) {
throw new AssertionError("Bad URL? (Really shouldn't happen)", ex);
}
try (URLClassLoader loader = new URLClassLoader(new URL[] {url})) {
final Class<?> clazz = loader.loadClass("Test");
final Method main = clazz.getMethod("main", String[].class);
final Object[] invocationArguments = {new String[] {}};
main.invoke(null, invocationArguments);
} catch (final ClassNotFoundException ex) {
throw new AssertionError("Bad class name", ex);
} catch (final IOException ex) {
throw new AssertionError("IO Error", ex);
} catch (final NoSuchMethodException ex) {
throw new AssertionError("Missing main method", ex);
} catch (final IllegalAccessException ex) {
throw new AssertionError("Class or main method not public", ex);
} catch (final InvocationTargetException ex) {
throw new AssertionError("Exception thrown by main method", ex);
}
}
}