JavaCTAPL的NoClassDefFoundError

JavaCTAPL的NoClassDefFoundError,java,Java,我正在尝试编写一个程序,该程序将利用树API(请参阅)。基本思想是创建一个,并使用它来获得一个。返回的CompilationTask实际上是javactasquimpl的一个实例(请参见下面的代码)。但是当我尝试将返回的编译任务强制转换为javactasquimpl时,我得到了一个NoClassDefFoundError import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import

我正在尝试编写一个程序,该程序将利用树API(请参阅)。基本思想是创建一个,并使用它来获得一个。返回的
CompilationTask
实际上是
javactasquimpl
的一个实例(请参见下面的代码)。但是当我尝试将返回的
编译任务
强制转换为
javactasquimpl
时,我得到了一个
NoClassDefFoundError

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/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

如何消除此错误?

您必须在
JavaCompiler.getTask
中设置选项(请参阅)。最简单的方法是使用系统属性:

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;
    }
}
import com.sun.tools.javac.api.javactapl;
导入java.util.array;
导入javax.tools.JavaCompiler;
导入javax.tools.JavaCompiler.CompilationTask;
导入javax.tools.JavaFileObject;
导入javax.tools.StandardJavaFileManager;
导入javax.tools.ToolProvider;
公共班机{
公共静态void main(字符串[]args){
JavaCompiler=ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager=compiler.getStandardFileManager(null,null,null);
可迭代的
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;
    }
}