0

We've got the following small system:

  • One Java-Project containing an annotation processor to generate java-code. Let's call it "A"
  • A second Java-Project that depends on "A" and uses its annotation processor. Let's call it "B"
  • using gradle

We now want to feed "A" a specific configuration file. E.g. for telling it that the generated classes should have a specific suffix or some given annotations. But since "A" is supposed to be a dependency for several other projects, this configuration file MUST be given in "B". Best case: in the resources folder. So this is the flow we were thinking about:

  1. "B" gets built
  2. This triggers annotation processing of "A"
  3. "A" reads a configuration file that lays in "B"
  4. The generated classes are in the build-folder of "B"

Everything works totally fine, except that "A" is not able to read the configuration file.

So the question is: How do I give any information from "B" to "A" so that "A" uses it in the build-process of "B"? A path to a configuration file would be already sufficient. Or is there any other way to configure an annotation processor from a depending project?

Edit:

This is an example annotation processor that lays in "A"

@SupportedAnnotationTypes("...")
public class BlocklyAnnotationProcessor extends AbstractProcessor {


    @SneakyThrows
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        // <-- THIS IS WHERE I NEED TO ACCESS THE CONFIG FILE
        
        this.do.fancyStuff();
    }

A configuration file might be a yaml. Pretty similar to application.yml as it is used in spring boot

processor:
  suffix: Impl

This is the project structure

project_A
  L src
    L java
      L AnnotationProcessor.java
project_B
  L src
    L java
      L ClassToBeProcessedByA.java
    L resources
      L my_config_to_be_read_by_A.yml
    
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
FeXseven
  • 77
  • 6
  • 1
    One option: use the Java SPI to create a service interface in A and the implementation in B. Then A would look up the implementation and get the configuration from there. The implementation could read the configuration from a resource inside B if you want to bundle it that way. - That's just a quick idea though and I'm not sure it would work during compile time which is when A would be used, right? – Thomas Jul 21 '22 at 08:01
  • would you mind providing some code snippets? At first glance `java.util.ServiceLoader` is what you actually need. – Andrey B. Panfilov Jul 21 '22 at 08:01
  • @AndreyB.Panfilov i'll take a look at the service loader. Not sure if code snippets might help you, but i'll edit the post in a second – FeXseven Jul 21 '22 at 09:34
  • yep, `java.util.ServiceLoader` akin Java SPI is what you need – Andrey B. Panfilov Jul 21 '22 at 09:40
  • @AndreyB.Panfilov I took a look into the `ServiceLoader`. Do I understand it correctly that in my case "A" would have an interface that is supposed to provide the configuration and "B" must implement that interface by loading the file? This would mean that every single project that uses "A" needs to implement this interface. Or do you see a chance that the only thing i need to do in "B" is creating the config file? – FeXseven Jul 21 '22 at 12:35
  • @AndreyB.Panfilov so i gave it a try and got the following result: The service loader is able to load implementations of a given interface within project "A". So the processor (in "A") can read a file that is in "A". However, it does NOT find implementations in project B. This might be because it uses a classLoader to find implementations. By default the current thread's class loader or a custom one. But "A" cannot have knowledge about "B" so it cannot use it's classLoader. See [this](https://stackoverflow.com/questions/45061170/using-serviceloader-within-an-annotation-processor) – FeXseven Jul 21 '22 at 13:52
  • @FeXseven works in my case, please check demo: https://github.com/andreybpanfilov/apspi. Why are you trying to do something in `javax.annotation.processing.AbstractProcessor#init`? That does not make sense – Andrey B. Panfilov Jul 21 '22 at 15:08

0 Answers0