2013-05-07 3 views
0

Я пытаюсь написать программу, которая воспользуется Tree API (см. https://weblogs.java.net/blog/2006/09/16/hacking-javac). Основная идея заключается в том, что вы создаете JavaCompiler и используете это для получения JavaCompiler.CompilationTask. Возвращаемый CompilationTask фактически является экземпляром JavacTaskImpl (см. Код ниже). Но когда я пытаюсь вернуть возвращенный CompilationTask в JavacTaskImpl, я получаю NoClassDefFoundError.NoClassDefFoundError для JavacTaskImpl

import javax.tools.JavaCompiler; 
import javax.tools.JavaCompiler.CompilationTask; 
import javax.tools.JavaFileObject; 
import javax.tools.StandardJavaFileManager; 
import javax.tools.ToolProvider; 

import com.sun.tools.javac.api.JavacTaskImpl; 

public class Main { 
    public static void main(String[] args) { 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); 
     Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects("Test.java"); 
     CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects); 

     // Prove that this is indeed an instance of JavacTaskImpl. 
     System.out.println("Task.getClass(): " + task.getClass()); 

     JavacTaskImpl javacTask = (JavacTaskImpl) task; 
    } 
} 

Вы можете скомпилировать этот код с

$JAVA_HOME/bin/javac Main.java -cp $JAVA_HOME/lib/tools.jar 

Но запуск кода с помощью

$JAVA_HOME/bin/java Main -cp $JAVA_HOME/lib/tools.jar 

производит следующий вывод:

Task.getClass(): class com.sun.tools.javac.api.JavacTaskImpl 
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/javac/api/JavacTaskImpl 
    at Main.main(Main.java:19) 
Caused by: java.lang.ClassNotFoundException: com.sun.tools.javac.api.JavacTaskImpl 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266) 
    ... 1 more 

Как избавиться от эта ошибка?

ответ

0

Вы должны установить параметры в JavaCompiler.getTask (см. JavaCompiler javadoc). Самый простой способ - использовать свойство System:

import com.sun.tools.javac.api.JavacTaskImpl; 
import java.util.Arrays; 
import javax.tools.JavaCompiler; 
import javax.tools.JavaCompiler.CompilationTask; 
import javax.tools.JavaFileObject; 
import javax.tools.StandardJavaFileManager; 
import javax.tools.ToolProvider; 

public class Main { 
    public static void main(String[] args) { 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); 
     Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects("Test.java"); 
     String classPath = System.getProperty("java.class.path"); 
     CompilationTask task = compiler.getTask(null, fileManager, null, 
       Arrays.asList("-classpath", classPath), 
       null, fileObjects); 

     // Prove that this is indeed an instance of JavacTaskImpl. 
     System.out.println("Task.getClass(): " + task.getClass()); 

     JavacTaskImpl javacTask = (JavacTaskImpl) task; 
    } 
}