나는 즉시 생성하는 클래스를 컴파일하기 위해 JavaCompiler
을 사용했습니다. 컴파일 태스크가 성공합니다. 그런 다음 Class.forName("MyClass")
을 사용하여 컴파일 된 클래스를로드하려고합니다. ClassNotFoundException로 실패합니다. 이 작업과 관련하여 알려진 문제점이 있습니까? 사용하여 컴파일 한 후 클래스를로드JavaCompiler 컴파일 된 클래스를 찾을 수 없습니다.
package com.amir.method;
import java.io.*;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import javax.tools.*;
public class MethodGenerator {
private final static MethodGenerator INSTANCE = new MethodGenerator();
private MethodGenerator() {
}
public static MethodGenerator get() {
return INSTANCE;
}
public static void main(String[] args) {
final Class<?> clz = MethodGenerator.get().compile("Foo", "doIt"); //<- args ignored for now
}
public Class compile(final String className,
final String methodName) {
try {
return doCompile(className, methodName);
} catch(final Exception e) {
throw new RuntimeException(this.toString(), e);
}
}
private Class doCompile(final String className,
final String methodName) throws IOException, ClassNotFoundException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StringWriter writer = new StringWriter();
PrintWriter out = new PrintWriter(writer);
out.println("public class HelloWorld {");
out.println(" public static void main(String args[]) {");
out.println(" System.out.println(\"This is in another java file\");");
out.println(" }");
out.println("}");
out.close();
final JavaFileObject file = new JavaSourceFromString("HelloWorld", writer.toString());
final Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
final String classPath = System.getProperty("java.class.path") + File.pathSeparator;
final String bootClassPath = System.getProperty("sun.boot.class.path") + File.pathSeparator;
final List<String> options = new ArrayList<String>();
options.add("-classpath");
final StringBuilder builder = new StringBuilder();
builder.append(classPath);
builder.append(bootClassPath);
final URLClassLoader urlClassLoader = (URLClassLoader) ClassLoaderResolver.getClassLoader();
for (final URL url : urlClassLoader.getURLs()) {
builder.append(url.getFile()).append(File.pathSeparator);
}
final int lastIndexOfColon = builder.lastIndexOf(File.pathSeparator);
builder.replace(lastIndexOfColon, lastIndexOfColon + 1, "");
options.add(builder.toString());
final JavaCompiler.CompilationTask task = compiler.getTask(null, null, diagnostics, options, null, compilationUnits);
boolean success = task.call();
if(success) {
final Class<?> cls = Class.forName("HelloWorld", true, urlClassLoader);
return cls;
}
return null;
}
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;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
}
해당 클래스를 내보내거나 가져 오는 경우 매니페스트를 확인 했습니까? 어떻게하면 프로젝트를 구축 할 수 있습니다. 매니페스트 파일을 다시 생성하십시오. – StackFlowed
Manifest? 나는 비행 중에 수업을 편성하고있다. 매니페스트 파일이 무엇을하는지 이해할 수 있습니까? –
클래스를 컴파일해도 클래스 로더에 자동으로 추가되지 않습니다. 너 스스로 그렇게해야 해. – Paul