Why is openjdk-11-jre installed together with maven when openjdk-8-jdk is specified in the package list?

The package maven depends on default-jre-headless (>= 2:1.7) | java7-runtime-headless (according to sudo dpkg -I /var/cache/apt/archives/maven_3.5.2-2_all.deb). I noticed the following behavior on Ubuntu 18.04 running inside Docker (image docker:18.04):

apt-get update && apt-get install --yes openjdk-8-jdk
apt-get install --yes maven

install OpenJDK 8 JDK (including JRE) and then only Maven because a JRE is already provided. However both

apt-get update && apt-get install --yes maven openjdk-8-jdk

and

apt-get update && apt-get install --yes openjdk-8-jdk maven

cause OpenJDK 11 JRE to be installed because it's the default JRE. Why does apt-get install not scan the package list to check whether dependencies are provided? I'll go so far and say that apt-get usually does that, even though I find no info about it.

One overview of the command and results (with a project which requires JDK 8 through the maven-enforcer-plugin) is provided at https://gitlab.com/krichter/maven-enforcer-plugin-docker/pipelines/26241321. I have no reason to believe that the behavior on my desktop Ubuntu 18.04 is different.

I'm looking for an explanation of the described scenario and maybe a hint to a configuration which adapt the package list parsing. This is not a problem for me and I need no workaround.

In my opinion this behavior is sub-optimal since it's more intuitive that the explicit specification of a package fulfilling a dependency of a package in the same list overrides the need to install an implicit default. If you'd want both OpenJDK 8 and 11 installed you'd specify both in the package list. Maybe someone else had this idea and filed an enhancement request (probably to Debian rather than Ubuntu). I'd the happy about the link.


Solution 1:

It's probably a result of how apt walks the dependency tree. Looking at the maven package details, we see:

  • default-jre-headless (>= 2:1.7)
    Standard Java or Java compatible Runtime (headless)

    or java7-runtime-headless
    virtual package provided by default-jre-headless, openjdk-11-jre-headless, openjdk-8-jre-headless

If openjdk-8-jre-headless is already installed, then the java-7-runtime-headless dependency is fulfilled and apt doesn't need to install anything additional there.

On the other hand, if nothing satisfying java-7-runtime-headless is installed, then apt will go first for default-jre-headless, since none of the packages named for installation fulfills either dependency, and JDK 11 gets installed. Since otherwise the package fulfilling this dependency is buried in the dependency of another package, we have a Catch-22 when it comes to creating the list of packages for installation.

If you explicitly name one of the packages providing java7-runtime-headless for installation, apt will work as you want:

# apt-get install --assume-no maven openjdk-8-jre-headless
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  ca-certificates ca-certificates-java dbus fontconfig-config fonts-dejavu-core
  java-common krb5-locales libaopalliance-java libapache-pom-java libapparmor1
  libatinject-jsr330-api-java libavahi-client3 libavahi-common-data
  libavahi-common3 libbsd0 libcdi-api-java libcommons-cli-java
  libcommons-io-java libcommons-lang3-java libcommons-parent-java libcups2
  libdbus-1-3 libexpat1 libfontconfig1 libfreetype6
  libgeronimo-annotation-1.3-spec-java libgeronimo-interceptor-3.0-spec-java
  libgssapi-krb5-2 libguava-java libguice-java libhawtjni-runtime-java
  libjansi-java libjansi-native-java libjpeg-turbo8 libjpeg8 libjsr305-java
  libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 liblcms2-2
  libmaven-parent-java libmaven-resolver-java libmaven-shared-utils-java
  libmaven3-core-java libnspr4 libnss3 libpcsclite1 libplexus-cipher-java
  libplexus-classworlds-java libplexus-component-annotations-java
  libplexus-interpolation-java libplexus-sec-dispatcher-java
  libplexus-utils2-java libpng16-16 libsisu-inject-java libsisu-plexus-java
  libslf4j-java libsqlite3-0 libssl1.1 libwagon-file-java
  libwagon-http-shaded-java libwagon-provider-api-java libx11-6 libx11-data
  libxau6 libxcb1 libxdmcp6 libxext6 libxi6 libxrender1 libxtst6
  multiarch-support openssl ucf x11-common
Suggested packages:
  default-dbus-session-bus | dbus-session-bus default-jre
  libaopalliance-java-doc libatinject-jsr330-api-java-doc libservlet3.1-java
  libcommons-io-java-doc libcommons-lang3-java-doc cups-common krb5-doc
  krb5-user libasm-java libcglib-java libjsr305-java-doc liblcms2-utils
  libmaven-shared-utils-java-doc liblogback-java pcscd
  libplexus-cipher-java-doc libplexus-classworlds-java-doc
  libplexus-interpolation-java-doc libplexus-sec-dispatcher-java-doc
  libplexus-utils2-java-doc junit4 testng libcommons-logging-java
  liblog4j1.2-java libnss-mdns fonts-dejavu-extra fonts-ipafont-gothic
  fonts-ipafont-mincho fonts-wqy-microhei fonts-wqy-zenhei fonts-indic
The following NEW packages will be installed:
  ca-certificates ca-certificates-java dbus fontconfig-config fonts-dejavu-core
  java-common krb5-locales libaopalliance-java libapache-pom-java libapparmor1
  libatinject-jsr330-api-java libavahi-client3 libavahi-common-data
  libavahi-common3 libbsd0 libcdi-api-java libcommons-cli-java
  libcommons-io-java libcommons-lang3-java libcommons-parent-java libcups2
  libdbus-1-3 libexpat1 libfontconfig1 libfreetype6
  libgeronimo-annotation-1.3-spec-java libgeronimo-interceptor-3.0-spec-java
  libgssapi-krb5-2 libguava-java libguice-java libhawtjni-runtime-java
  libjansi-java libjansi-native-java libjpeg-turbo8 libjpeg8 libjsr305-java
  libk5crypto3 libkeyutils1 libkrb5-3 libkrb5support0 liblcms2-2
  libmaven-parent-java libmaven-resolver-java libmaven-shared-utils-java
  libmaven3-core-java libnspr4 libnss3 libpcsclite1 libplexus-cipher-java
  libplexus-classworlds-java libplexus-component-annotations-java
  libplexus-interpolation-java libplexus-sec-dispatcher-java
  libplexus-utils2-java libpng16-16 libsisu-inject-java libsisu-plexus-java
  libslf4j-java libsqlite3-0 libssl1.1 libwagon-file-java
  libwagon-http-shaded-java libwagon-provider-api-java libx11-6 libx11-data
  libxau6 libxcb1 libxdmcp6 libxext6 libxi6 libxrender1 libxtst6 maven
  multiarch-support openjdk-8-jre-headless openssl ucf x11-common
0 upgraded, 78 newly installed, 0 to remove and 4 not upgraded.
Need to get 44.0 MB of archives.
After this operation, 138 MB of additional disk space will be used.
Do you want to continue? [Y/n] N
Abort.

Solution 2:

The solution provided by muru is not complete IMO. When you run

apt-get install --assume-no maven openjdk-8-jre-headless

you have only JRE, not JDK. To install OpenJDK 8 version with Maven without installing OpenJDK 11 I modified apt command

apt-get install -y openjdk-8-jre-headless openjdk-8-jdk-headless maven