Search code examples
javacompilationjavacompiler

Why doesn't this compile? (JavaCompiler works fine, but says annotation processing needs to be requested)


This is the error;

error: Class names, 'Hello.java', are only accepted if annotation processing is explicitly requested 1 error

This is the JavaCompiler code;

public static void main(String[] args) {
    PrintWriter writer = new PrintWriter( System.out);
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager( null, null, null);
    ArrayList<String> classes = new ArrayList<>();
    classes.add( "Hello.java");

    JavaCompiler.CompilationTask task = compiler.getTask( writer, fileManager, null, null, classes, null);
    task.call();
}

This is the Hello class;

public class Hello {
    public static void main(String[] args) {
        System.out.println( "Hi");
    }
}

I know this question was asked near a million times, but all of the answers are this = "You forgot to add .java at the end of your class name", but I did that, as you can see. Why doesn't this work? Is it different when using a JavaCompiler? Are my parameters in the constructor wrong? Thanks for the help.


Solution

  • You're misusing compiler object:

    1. Classes parameter is used to pass annotations
    2. CompilationUnits parameter is what you should use

    You should call it like this (note: you have to provide valid path to file):

    PrintWriter writer = new PrintWriter(System.out);
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    
    Iterable<? extends JavaFileObject> units =
        fileManager.getJavaFileObjectsFromFiles(
            Arrays.asList(new File("Hello.java"))); // put absolute path here
    
    JavaCompiler.CompilationTask task = compiler.getTask(
        writer, fileManager, null, null, null, units); // provide units, not classes
    task.call();
    
    fileManager.close();