Summary
Our build pipeline has been broken after some machines have updated from JDK 11.0.10-
to JDK 11.0.11+
. This happens due to changed jdeps
behavior. After some research it became evident, this is likely due to changes introduced with JDK-8214213
:
Assuming we were retrieving dependencies for sentry-1.7.25.jar
, then our usage of jdeps
via CLI is as follows:
jdeps --list-deps -filter:module --multi-release=11 "..\somePath\sentry-1.7.25.jar
The resulting dependency lists look like this:
11.0.10
and below
java.base
java.logging
java.naming
11.0.11
and above
Error: Missing dependencies: classes not found from the module path and classpath.
To suppress this error, use --ignore-missing-deps to continue.
sentry-1.7.25.jar
io.sentry.event.helper.BasicRemoteAddressResolver -> javax.servlet.http.HttpServletRequest not found
io.sentry.event.helper.ForwardedAddressResolver -> javax.servlet.http.HttpServletRequest not found
io.sentry.event.helper.HttpEventBuilderHelper -> javax.servlet.http.HttpServletRequest not found
io.sentry.event.helper.RemoteAddressResolver -> javax.servlet.http.HttpServletRequest not found
io.sentry.event.interfaces.HttpInterface -> javax.servlet.http.Cookie not found
io.sentry.event.interfaces.HttpInterface -> javax.servlet.http.HttpServletRequest not found
io.sentry.servlet.SentryServletContainerInitializer -> javax.servlet.ServletContainerInitializer not found
io.sentry.servlet.SentryServletContainerInitializer -> javax.servlet.ServletContext not found
io.sentry.servlet.SentryServletContainerInitializer -> javax.servlet.ServletException not found
io.sentry.servlet.SentryServletRequestListener -> javax.servlet.ServletRequest not found
io.sentry.servlet.SentryServletRequestListener -> javax.servlet.ServletRequestEvent not found
io.sentry.servlet.SentryServletRequestListener -> javax.servlet.ServletRequestListener not found
io.sentry.servlet.SentryServletRequestListener -> javax.servlet.http.HttpServletRequest not found
In order to fix this on OpenJDK 11.0.11+
it's necessary to set --ignore-missing-deps
when calling jdeps
. If done, then the output again looks correct again:
java.base
java.logging
java.naming
Question
So I am able to produce the same output with jdeps
using JDK 11.0.11+
as I was able to do with JDK 11.0.10-
. That being said, this output is used to create a custom runtime and in the description of JDK-8214213
is explicitely stated:
Note that a custom image is created with the list of modules output by jdeps when using the
--ignore-missing-deps
option for a non-modular application. Such an application, running on the custom image, might fail at runtime when missing dependence errors are suppressed.
From my understanding this means that if there is a transitive dependency involved, where the dependency of a dependency requires a runtime module that is not required by any of the top level dependencies, then this can lead to a custom runtime uncapable of running the application, since the transitive dependency cannot be resolved. In other words, if my application requires dependency A
, which requires dependency B
and module C
, but dependency B
also requires module D
, then my application is at risk of encountering runtime errors, since my custom runtime is not being provided with module D
.
My question now is this, since I am unable to derive it from documentation:
With JDK 11.0.11+
I can only get the same dependency list output, if --ignore-missing-deps
is used. Does that mean that...
- ...
jdeps
was able to resolve transitive dependencies prior to11.0.11
, but cannot do so anylonger above said version, e.g. because dependency analysis is done differently internally injdeps
? - ...
jdeps
acted as if it was using--ignore-missing-deps
prior to11.0.11
by default, hence if the default changed,jdeps
is now throwing an error on11.0.11+
? - ...something else is going on?
The resulting dependency list might be the same, simply because there are a lot of libraries, so most modules are used either way. However I am trying to determine, whether
jdeps --list-deps -filter:module --multi-release=11 "..\somePath\sentry-1.7.25.jar (11.0.10)
and
jdeps --list-deps --ignore-missing-deps -filter:module --multi-release=11 "..\somePath\sentry-1.7.25.jar (11.0.11)
behave exactly the same, or whether using --ignore-missing-deps
introduces a new risk when adding new libraries to our project, as they may at some point require a module that is not part of the current jdeps
-list.
Bear in mind, to me this is rather a deep-dive into OpenJDK specifics, so if there is faulty terminoogy or problems with my understanding of these scenarios, then feel free to point out and correct them.