Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Native Image] Missing support for ServiceLoader services registered via module-info #9952

Closed
1 of 2 tasks
JaroslavTulach opened this issue Oct 23, 2024 · 9 comments
Closed
1 of 2 tasks

Comments

@JaroslavTulach
Copy link
Contributor

JaroslavTulach commented Oct 23, 2024

Describe the Issue

Java Platform Module System defines a way to register services to be located by ServiceLoader. However there seems to be no support for such registrations in native image.

Using the latest version of GraalVM can resolve many issues.

GraalVM Version

I tried two versions:

  • GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30)
  • Oracle GraalVM 23.0.1+11.1 (build 23.0.1+11-jvmci-b01)

None of them works the way it "should". Looking at the code of ServiceLoaderFeature explains why it is not working - there is no ModuleLayer related code at all - which is probably necessary to extract information from the module-info.class of the modules on module path.

Operating System and Version

Tested on Ubuntu, but this is cross OS problem

Diagnostic Flag Confirmation

  • I tried the -H:ThrowMissingRegistrationErrors= flag.

Run Command

I have prepared a special repository with NativeImageModuleDemo with a demo Maven project, follow the read me that suggests to:

NativeImageModularDemo$ mvn clean install
NativeImageModularDemo$ mvn -q -Pjvm -f api exec:exec
NativeImageModularDemo with following modules:
  Api
Found no API provider. Include Impl JPMS module!
NativeImageModularDemo$ mvn -q -Pjvm -f impl exec:exec
NativeImageModularDemo with following modules:
  Api
  Impl
Hi from Impl!

e.g. two modules Api and Impl are enabled and Hi from Impl! gets printed. While with native-image:

NativeImageModularDemo$ mvn clean install -Pnative
NativeImageModularDemo$ ./impl/target/NativeImageModularDemo
NativeImageModularDemo with following modules:
  Impl
  Api
Found no API provider. Fix native-image support for modular ServiceLoader!

e.g. two modules are enabled, but the ServiceLoader.load finds no implementation of the interface it is looking for.

Expected Behavior

Native image version should work just like the JVM one:

NativeImageModularDemo$ mvn clean install -Pnative
NativeImageModularDemo$ ./impl/target/NativeImageModularDemo
NativeImageModularDemo with following modules:
  Impl
  Api
Hi from Impl!

Actual Behavior

NativeImageModularDemo$ mvn clean install -Pnative
NativeImageModularDemo$ ./impl/target/NativeImageModularDemo
NativeImageModularDemo with following modules:
  Impl
  Api
Found no API provider. Fix native-image support for modular ServiceLoader!

Steps to Reproduce

I have prepared a special repository with NativeImageModuleDemo with a demo Maven project, follow the read me that suggests to:

NativeImageModularDemo$ mvn clean install
NativeImageModularDemo$ mvn -q -Pjvm -f api exec:exec
NativeImageModularDemo with following modules:
  Api
Found no API provider. Include Impl JPMS module!
NativeImageModularDemo$ mvn -q -Pjvm -f impl exec:exec
NativeImageModularDemo with following modules:
  Api
  Impl
Hi from Impl!

e.g. two modules Api and Impl are enabled and Hi from Impl! gets printed. While with native-image:

NativeImageModularDemo$ mvn clean install -Pnative
NativeImageModularDemo$ ./impl/target/NativeImageModularDemo
NativeImageModularDemo with following modules:
  Impl
  Api
Found no API provider. Fix native-image support for modular ServiceLoader!

e.g. two modules are enabled, but the ServiceLoader.load finds no implementation of the interface it is looking for.

Additional Context

No response

Run-Time Log Output and Error Messages

No response

@wirthi
Copy link
Member

wirthi commented Oct 23, 2024

Thanks Jaroslav for reporting this. I suspect this is a duplicate of #7634 / GR-49635. @olpaw can you confirm?

@olpaw
Copy link
Member

olpaw commented Oct 23, 2024

I suspect this is a duplicate of #7634 / GR-49635. @olpaw can you confirm?

Correct. But I prefer @JaroslavTulach s issue as it is more recent.

@olpaw
Copy link
Member

olpaw commented Oct 23, 2024

I will look into that soon 🤞

@olpaw
Copy link
Member

olpaw commented Oct 28, 2024

@JaroslavTulach I debugged this. The parameterless constructor for a service impl. class gets correctly registered for reflective access and the ServiceLoader at runtime is almost able to do the right thing. But it relies on using LazyClassPathLookupIterator which then refuses to use the parameterless constructor because the implementation class is in a named module. See https://github.com/openjdk/jdk/blob/52382e285fdf853c01605f8e0d7f3f5d34965802/src/java.base/share/classes/java/util/ServiceLoader.java#L1228

Turns out we do not correctly implement ServicesCatalog retrieval at image image runtime. If we fix that then java.util.ServiceLoader.ModuleServicesLookupIterator will be responsible to instantiating the ServiceLoader impl. (as it should be anyways in this case).

I will find someone to fix this hopefully next week.

@JaroslavTulach
Copy link
Contributor Author

Thank you @olpaw for investigating the issue. I tried to workaround the problem by loading the services in build time, but no luck so far. Was there any progress on your side?

@olpaw
Copy link
Member

olpaw commented Nov 25, 2024

Yes, this is right now in the process of getting fixed by @ivan-ristovic

@ivan-ristovic
Copy link
Contributor

Hi @JaroslavTulach , the PR that adresses this issue is up: #10202

@ivan-ristovic
Copy link
Contributor

ivan-ristovic commented Dec 5, 2024

The fix has been merged (#10202) and will be part of GraalVM 24.2.

We will also backport to GraalVM 23.1.

@JaroslavTulach
Copy link
Contributor Author

JaroslavTulach commented Dec 16, 2024

The fix has been merged (#10202) and will be part of GraalVM 24.2.
We will also backport to GraalVM 23.1.

Thank you! I can confirm that my NativeImageModuleDemo works with 0c2731c GraalVM. I used:

graal/vm$ mx --env ni-ce build
graal/vm$ export JAVA_HOME=`mx --env ni-ce graalvm-home`

and then used the generated JVM in NativeImageModuleDemo as:

NativeImageModularDemo$ mvn clean install -Pnative
NativeImageModularDemo$ $ ./impl/target/NativeImageModularDemo 
NativeImageModularDemo with following modules:
  Api
  Impl
Hi from Impl!

Everything is working as expected. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants