Java 컴파일러 API를 사용하여 일부 Java 클래스를 컴파일하려고합니다. 그 클래스는, 문맥 ClassLoader에 의해로드 할 수있는 jar 파일로부터 몇개의 패키지를 임포트합니다. 시스템 클래스 로더가 아닌 X를 X라고 부르 자. 컴파일을 실행하면 컴파일러에서 가져 오기를 인식하지 못한다고 불평합니다. classloader를 전달하기 위해 fileManager를 지정하려했지만 도움이되지 않습니다.Java 컴파일러 API ClassLoader
컴파일 메소드가 호출되면, 먼저 "CLASS LOADED"를 인쇄하므로 컨텍스트 ClassLoader가 종속성 클래스를 찾을 수 있습니다. 그러나 컴파일 자체가 실패하고 ("컴파일 실패"메시지가 표시됨) 컴파일 중에 다음과 같은 오류가 발생합니다.
/path/to/my/Source.java:3 : 패키지 my.dependency가 존재하지 않습니다. import my.dependency.MyClass; ^
내가 뭘 잘못하고 있니? 커스텀 클래스 로더를 compilationTask에 전달하는 올바른 방법은 무엇입니까? URLClassLoader가 아니기 때문에 ClassLoader에서 URL을 추출 할 수 없습니다.
내 방법은 여기에 있습니다 :
public void compile(List<File> filesToCompile) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager stdFileManager =
compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> fileObjects = stdFileManager
.getJavaFileObjectsFromFiles(filesToCompile);
FileManagerImpl fileManager = new FileManagerImpl(stdFileManager);
CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects);
Boolean result = task.call();
if (result == true) {
System.out.println("Compilation has succeeded");
} else {
System.out.println("Compilation FAILED");
}
}
private final class FileManagerImpl extends ForwardingJavaFileManager<JavaFileManager> {
public FileManagerImpl(JavaFileManager fileManager) {
super(fileManager);
}
@Override
public ClassLoader getClassLoader(JavaFileManager.Location location) {
ClassLoader def = getContextClassLoader();
try {
def.loadClass("my.dependency.MyClass");
System.out.println("CLASS LOADED");
} catch (ClassNotFoundException ex) {
System.out.println("NOT LOADED");
}
return def;
}
}
고마워, 내가 조사해 볼게. 그러나 기존의 classLoader를 설정할 방법이 없습니까? –
@Pavel S. - 컴파일러 도구에 실제 응용 프로그램 클래스 경로와 별개의 클래스 경로를 제공하는 것이 좋습니다. 클래스의 한 버전을로드했지만 클래스를 컴파일하기 위해 다른 버전을 사용하려고한다고 가정 해보십시오. * * 클래스 분리가 필요합니다. –