Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find which java.base runtime dependencies are being used by an application?

Question

What are ways to systematically find all modules of the JDK that will be/have been used during the runtime of a Java application through reflection and the service provider model?

Clarifications

  • I am, to my understanding, not looking for the jdeps command unless someone has a particular set of arguments that can resolve reflected runtime-only dynamic dependencies, which does not seem to be its purpose.
  • I already understand there is the jlinks --suggest-providers option, but this requires knowledge of each provider that is lacking.

Problem Summary

I've been working with a self-contained jar (for our current example code, the Paper Minecraft server, which has requirements to download a jar, the Minecraft jar, and patch it while running it). When I go to build a minimal Docker container for running the application using a runtime like Eclipse Temurin it is recommended:

JRE images are available for all versions of Eclipse Temurin, but it is recommended that you produce a custom JRE-like runtime using jlink (see usage below).

Their code sample:

# Example of custom Java runtime using jlink in a multi-stage container build
FROM eclipse-temurin:21 as jre-build

# Create a custom Java runtime
RUN $JAVA_HOME/bin/jlink \
         --add-modules java.base \
         --strip-debug \
         --no-man-pages \
         --no-header-files \
         --compress=2 \
         --output /javaruntime

# Define your base image
FROM debian:buster-slim
ENV JAVA_HOME=/opt/java/openjdk
ENV PATH "${JAVA_HOME}/bin:${PATH}"
COPY --from=jre-build /javaruntime $JAVA_HOME

# Continue with your application deployment
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]

From: https://hub.docker.com/_/eclipse-temurin

This build command in particular does not include any required service providers and runs into the common problem of searching for a laundry list of service providers from other modules such as jdk.crypto.cryptoki and jdk.crypto.ec, which are common requirements to complete even a basic HTTPS handshake for web requests.

There is the option to simply use --bind-services to include every single module that could provide a service for java.base module, but as discussed here, this defeats the purpose of creating a slimmed-down JRE in the first place, as it includes everything.

This introduces a weird and frustrating dance of running and breaking your application endlessly until you've found the exact 8-20 piece --add-modules argument to provide just enough services to run your application.

I feel like there should be some form of profiler command or tool shipped with the jdk or potentially otherwise runnable alongside your application that can answer the question "What jdk modules were used during your applications execution?" not just java.base but "java.base leveraged jdk.crypto.cryptoki during this execution" to speed up the process of tracing all required modules for a slimmed down runtime.

Resources Already used

  • https://docs.oracle.com/en/java/javase/21/docs/specs/man/jlink.html
  • https://docs.oracle.com/en/java/javase/21/docs/specs/man/jdeps.html
  • https://hub.docker.com/_/eclipse-temurin
  • https://jaehong21.com/posts/java/java-jdeps-jlink/
    • This blog is probably the most briefly summarized but also the most depth I've seen on the topic, all other guides/any AI slop (of which for this there is unfortunately much relative to the niche topic) pretty much says the same or similar and follows only the basic usage of the command as seen from it's documentation.
  • jlink: service binding links many unnecessary modules
    • There were additional stack overflow questions but all summarized essentially the same usage.

Disclaimer

I have searched through Stack Overflow questions, blogs, and JDK 21 documentation about JLinks and jdeps for about 6-7ish hours. I am happy to mark an answer correct if I have simply missed a crucial option referenced in another answer either but I have not managed to turn up an answer as of yet. Happy to add additional clarifications if needed. I may eventually write essentially a profiler to handle this, but I want to see if that already exists.

like image 724
Matthew Fallon Avatar asked Dec 01 '25 10:12

Matthew Fallon


1 Answers

For Java 21,

java -Xlog:class+load=info -cp your-app.jar com.myapp.Main

to show all modules attempted to be loaded.

Filter from there for Java packages as needed.

like image 130
Brandon Murry Avatar answered Dec 03 '25 00:12

Brandon Murry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!