I am trying to generate a config file for my sourcecode via compiletime annotation processing in Java 8.
As far as I understand for each Annotation listed in the getSupportedAnnotationTypes
class, the processor gets called once.
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> set = new LinkedHashSet<>();
set.add(MCPlugin.class.getCanonicalName());
set.add(MCAPIVersion.class.getCanonicalName());
set.add(MCAuthor.class.getCanonicalName());
set.add(MCAPIVersion.class.getCanonicalName());
set.add(MCDepend.class.getCanonicalName());
set.add(MCLoad.class.getCanonicalName());
set.add(MCLoadBefore.class.getCanonicalName());
set.add(MCSoftDepend.class.getCanonicalName());
set.add(MCCommand.class.getCanonicalName());
return set;
}
Actually I don't want to process all those annotations with one annotation processer (Would this be the right way?) because it causes problems with the MCCommand
annotation.
So my plan was to create another annotation processer, which only processes the MCCommand
annotations.
My problem is, that the output of both processers should go into the same output file. (Is that even possible?)
I have already tried to reopen the resource file like this (this is also how I open it in the first place):
FileObject file = filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "config.yml");
which will only create an error or override the existing file.
TlDr: How can I make my annotation processer edit a file generated by another annotation processor?
Okay, after hours of going through the sourcecode of the Filer
and the FileObject
I found a solution / workaround.
To be able to get access to the JavacFiler
you need to have com.sun.tools as dependency.
Downcast the Filer
to a JavacFiler
to get access to more methods.
The filer has a createResource(...)
and a getResource(...)
method, which seem to do the same but the difference is that createResource(...)
opens a FileObject
for writing only and the getResource(...)
for reading only.
So to be able to edit a file from another Annotation Processor you have to do:
FileObject jfo = filer.getResource(StandardLocation.SOURCE_OUTPUT, "", "test.txt");
String msg = TUtils.JFOToString(jfo); // Reads FileObject as String
jfo.delete();
jfo = filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "test.txt");
TUtils.writeJFO(jfo, msg + "Hallo ich bin Processor 2"); // Writes String to FileObject
filer.close();
This feels like a hack, but I seems to work.