From robin.bygrave at gmail.com Fri Mar 18 03:00:03 2022 From: robin.bygrave at gmail.com (Rob Bygrave) Date: Fri, 18 Mar 2022 16:00:03 +1300 Subject: No --add-provides patch option for test services ... case when APT generates test service Message-ID: Looking at https://stackoverflow.com/questions/54087050/java-9-serviceloader-doesnt-load-test-implementation-from-test-sources-module It talks about the case of using ServiceLoader in tests where the services themselves are in src/test . In this SO question Alan has the comment: *To test TestService1 and TestService2 would require putting them into their own test module with the appropriate provides clause. The JDK doesn't have a --add-provides option to augment the set of services that a module provides. There are chicken 'n egg with such an option because service binding is part of resolution and is done long before command line options to augment the module graph are handled.* So my interpretation of that comment from Alan is that there is not going to be a * --add-provides* patch option anytime soon or ever. Is that a correct interpretation? ------- Now for myself, I have the case where I have: - A junit extension that uses ServiceLoader (avaje-inject-test) - A annotation processor that will generate services for both main and test (avaje-inject-generator) So the Java annotation processor generates the service and so for case of test code the service is generated into generated-test-sources. This annotation processor supports classpath so it will also generate a META-INF/services file and for test this file ends up in test-classes/META-INF/services/. The junit extension (avaje-inject-test / ONLY expected to run in test) uses ServiceLoader and that works for classpath but not for module-path as there is no provides clause for the generated service (so it doesn't load the service when run in module-path). Currently I believe that there is no way to "patch" module-path with a "--add-provides" and if I read Alan's comment correctly there isn't likely to be such a --add-provides option forthcoming. For this APT case these are generated services and not expected or intended to be pulled out into another module. Noting that this junit extension ONLY runs in test and will only EVER try to load a service that was generated into generated-test-sources ... my "interesting workaround" for this test specific service loading code (junit extension), is that when the code that uses ServiceLoader finds no services to then perform a fallback of: read the META-INF services resources like: Enumeration resources = ClassLoader.getSystemResources("META-INF/services/io.avaje.inject.test.TestModule") ... read the class names of the services from the resource content and then use reflection to create the service instances. So for this junit extension this works and is maybe a decent enough approach in that the annotation processor will generate the META-INF services file regardless of module-path or classpath. Have I missed something? Is there a better approach that I should be looking at? (Given that these services are test specific services generated by APT and moving them into a separate module isn't really an option) Thanks, Rob.