2

I'm facing an issue where ServiceLoader does not find one provided service.

I have tested with regular project and the following sources:

// test/Tester.java
package test;

public interface Tester {
}

// test/TesterImpl.java
package test;

public class TesterImpl implements Tester {
}

// test/Runner.java
package test;

import java.util.ServiceLoader;

public class Runner {
    public static void main(String[] args) {
        var loader = ServiceLoader.load(Tester.class);
        for (var tester : loader) {
            System.out.println(tester);
        }
    }
}

// module-info.java
import test.Tester;
import test.TesterImpl;

module module {
    uses Tester;
    provides Tester with TesterImpl;
}

The above prints something akin to test.TesterImpl@1fb3ebeb, proving that it works as wanted.

The same fails to work when I try to use ServiceLoader.load(...) inside an AbstractProcessor that's run through maven-compiler-plugin. The processor returns an empty iterator instead. What is required to make it behave the same way in the annotation processor as it does in the case above?

Naman
  • 27,789
  • 26
  • 218
  • 353
user_4685247
  • 2,878
  • 2
  • 17
  • 43
  • hoping that you are using the latest version of the plugin, can you share when is it that you are expecting the compiler plugin to load the implementations (not sure why that would be required during compile time) and a debug output of when the plugin fails to load the class you expect. – Naman Feb 08 '22 at 01:45
  • I expect them to be available when an instance of the processor is available - it appears to be working fine if using META-INF/services approach – user_4685247 Feb 08 '22 at 07:49
  • 1
    Your annotation processor likely has not been loaded as a module. In case of `javac`, you’d have to use `--processor-module-path` instead of `--processor-path`, don’t know whether the maven compiler plugin has an equivalent option. When compiling with ecj, you’re out of luck, as far as I know, it didn’t catch up at all. – Holger Jun 02 '22 at 13:01

1 Answers1

1

THe solution to this issue was to specify a class loader - it appears that the annotation processor used a different classloader than the classes I was trying to load the services from. Solution is the following:

ServiceLoader.load(MyService.class, MyAnnotationProcessor.class.getClassLoader())
user_4685247
  • 2,878
  • 2
  • 17
  • 43