3

I am building an annotation processor plugin for eclipse, what i would like to do is to examine several files inside the project folder during the processing.

I would like to know how can I get the project path from within my processor. I believe this can be done because the project source path is provided to the processor - but I cannot find a way to reach it.

I tried looking at the System.properties and at the processingEnv.getOptions() but there is no useful information there..

eventually I would like to use this annotation processor on Netbeans too so if there is a public API that can provide this information it will be the best - but any help will be appreciated..

user861594
  • 5,733
  • 3
  • 29
  • 45
bennyl
  • 2,886
  • 2
  • 29
  • 43

2 Answers2

5

The processing environment provides you with a Filer that can be used to load (known) resources. If you need absolute paths to discover files or directories, you can use a JavaFileManager and a StandardLocation:

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null);

Iterable<? extends File> locations = fm.getLocation(StandardLocation.SOURCE_PATH);

If you are using Eclipse, you need to configure it to use the JDK as runtime as bennyl pointed out in the comments.


It seems that there is no API that is obligated to return the source location, so the solution above won't work reliably and only with some environments. The Filer for example is only required to support CLASS_OUTPUT and SOURCE_OUTPUT.

The easiest workaround is probably to assume/require a specific project structure, where the source directories and compiled classes are in a specific subdirectories of the project (e.g. the src and bin directories for most IDEs or src/main/java and target/classes for Maven). If you do that, you can get the source path by creating a temporary resource with the Filer at the SOURCE_OUTPUT location and get the source path relative from that file's location.

Filer filer = processingEnv.getFiler();
FileObject resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "", "tmp", (Element[]) null);
Path projectPath = Paths.get(resource.toUri()).getParent().getParent();
resource.delete();
Path sourcePath = projectPath.resolve("src")
kapex
  • 28,903
  • 6
  • 107
  • 121
  • This does not work for me under eclipse - ToolProvider.getSystemJavaCompiler() return null when executed from eclipse (i think that eclipse uses its own compiler that does not respect this API) – bennyl Mar 19 '14 at 11:52
  • 1
    Finally found a solution - the null compiler issue can be fixed by following instructions from this thread: http://stackoverflow.com/questions/9107099/null-javacompiler-in-eclipse -thank you! – bennyl Mar 21 '14 at 12:52
  • For me this still doesn't work. the `fm.getLocation(StandardLocation.SOURCE_PATH)` returns null.. I'm calling this from the init method in an extension of `AbstractProcessor`. Any hints? – Jurgen Vinju Apr 16 '15 at 19:01
  • Not working either for me using maven-processor-plugin:2.2.4. `fm.getLocation(StandardLocation.SOURCE_PATH)` returns null. Only StandardLocations returning not null are useless: CLASS_PATH contains location /opt/buildmanagement/hudson/slaves/slave_1/maven3-agent.jar and /opt/buildmanagement/hudson/tools/apache-maven-3.0.5/boot/plexus-classworlds-2.4.jar; PLATFORM_CLASS_PATH contains some JARs. The rest is null – JRA_TLL Nov 11 '15 at 11:47
5

I am getting the source path from ProsessingEnv by generating a source file:

String fetchSourcePath() {
    try {
        JavaFileObject generationForPath = processingEnv.getFiler().createSourceFile("PathFor" + getClass().getSimpleName());
        Writer writer = generationForPath.openWriter();
        String sourcePath = generationForPath.toUri().getPath();
        writer.close();
        generationForPath.delete();

        return sourcePath;
    } catch (IOException e) {
        processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "Unable to determine source file path!");
    }

    return "";
}
jactor-rises
  • 2,395
  • 2
  • 22
  • 44
  • This works for me while the accepted answer does not. (But I'm not sure you need to do any writing/opening/closing of the file) – Matt Jul 01 '19 at 13:56