2008-11-08 8 views
6

JDK 6에서 제공하는 ToolProvider 및 JavaCompiler 클래스를 사용하여 Java 프로그램에서 생성 된 소스 파일을 컴파일하는 경우가 있습니다. 소스 파일에는 컨텍스트 클래스 로더 (J2EE 컨테이너에서 실행)의 클래스에 대한 참조가 포함되어 있지만 시스템에는 포함되어 있지 않습니다 클래스 로더. 나의 이해는 기본적으로 ToolProvider가 시스템 클래스 로더로 JavaCompiler 인스턴스를 생성한다는 것이다.JDK6 ToolProvider 및 JavaCompiler를 컨텍스트 클래스 로더와 함께 사용하려면 어떻게해야합니까?

JavaCompiler에 사용할 클래스 로더를 지정하는 방법이 있습니까? 로 정의 FileManagerImpl와

FileManagerImpl fm = 
    new FileManagerImpl(compiler.getStandardFileManager(null, null, null);); 

:

static final class FileManagerImpl 
    extends ForwardingJavaFileManager<JavaFileManager> { 

    public FileManagerImpl(JavaFileManager fileManager) { 
     super(fileManager); 
    } 

    @Override 
    public ClassLoader getClassLoader(JavaFileManager.Location location) { 
     new Exception().printStackTrace(); 
     return Thread.currentThread().getContextClassLoader(); 
    } 

} 

스택 트레이스는 만 ​​주석 처리시 한 번이라고 표시

나는 IBM developerWorks에서 뭔가에서 수정이 방법을 시도했다. 컴파일 할 소스 파일에서 참조 된 클래스가 시스템 클래스 경로에 있지 않지만 컨텍스트 클래스 로더에서 사용할 수 있는지 확인했습니다.

답변

1

또 다른 옵션은 Commons JCI입니다. 당신이 contextclassloader에 알려진 파일에 대한 클래스 경로를 알고있는 경우

+0

JCI는 JDK6 지원에서 허용하는 것처럼 경로 만 클래스 로더를 전달할 수있는 것으로 보이지 않습니다. – Phil

+0

어디에서 찾고 계셨습니까? 물론 그렇습니다. – tcurdt

8

당신은 컴파일러에게 전달할 수 있습니다

StandardJavaFileManager fileManager = compiler.getStandardFileManager(this /* diagnosticlistener */, null, null); 
// get compilationunits from somewhere, for instance via fileManager.getJavaFileObjectsFromFiles(List<file> files) 
List<String> options = new ArrayList<String>(); 
options.add("-classpath"); 
StringBuilder sb = new StringBuilder(); 
URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader(); 
for (URL url : urlClassLoader.getURLs()) 
    sb.append(url.getFile()).append(File.pathSeparator); 
options.add(sb.toString()); 
CompilationTask task = compiler.getTask(null, fileManager, this /* diagnosticlistener */, options, null, compilationUnits); 
task.call(); 

을이 예제는 당신이 클래스 경로를 검색 할 수있는 URLClassLoader의을 (사용하고있는 가정)하지만 원하는 경우 클래스 경로를 삽입 할 수 있습니다.

0

여기에 두 가지 질문을하고 있습니다.

하나는 시스템 클래스 경로에없는 클래스를 컴파일하는 방법입니다. 이는 컴파일러에 "-classpath"명령 줄 인수를 전달하면 쉽게 해결할 수 있습니다 (Leihca에서 처음 언급 한 것처럼).

둘째는 스레드 컨텍스트 클래스 로더에서 ToolProvider 및 JavaCompiler를 인스턴스화하는 방법입니다. 이 글을 쓰는 시점에서 이것은 미해결 질문입니다. Using javax.tools.ToolProvider from a custom classloader?