16.04 incorrectly installs openjdk-9 to satisfy java8-runtime dependency

Bug #1584118 reported by Jonas Kalderstam
14
This bug affects 3 people
Affects Status Importance Assigned to Milestone
openjdk-9 (Ubuntu)
Invalid
Undecided
Unassigned

Bug Description

Hi,
A user recently reported an issue on our bug tracker stating that our package was pulling in openjdk-9 and subsequently crashed when started. This apparently because openjdk-9 is the default choice for java8-runtime, which is quite surprising.

Now it is technically correct that java9 does provide a java8-runtime, but java9 isn't even released yet and should definitely not be the default java8-runtime until that time.

Same bug was reported against puppet here:
https://tickets.puppetlabs.com/browse/EZ-77

Revision history for this message
Jonas Kalderstam (jonas-ubuntuone) wrote :

Forgot to mention, version 16.04 (sorry, got lost in an edit)

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in openjdk-9 (Ubuntu):
status: New → Confirmed
Revision history for this message
Tiago Stürmer Daitx (tdaitx) wrote :

Thank you for taking the time to report this bug and helping to make
Ubuntu better.

I can see from https://github.com/puppetlabs/ezbake/pull/303 that you have implemented a fix.

Your current settings will force the user to install a openkdk-7|8-jre-headless package even if he has something else installed that could be used as a JRE 7|8.

If you actually need to depend on OpenJDK then keep it as it is, otherwise for a broader JRE dependency you can also use:
-Depends: ${misc:Depends}, openjdk-7-jre-headless | openjdk-8-jre-headless, net-tools, adduser<%=
+Depends: ${misc:Depends}, default-jre-headless | openjdk-7-jre-headless | openjdk-8-jre-headless | java7-runtime-headless | java8-runtime-headless, net-tools, adduser<%=

This will:
- Install the distro's default headless JRE (either OpenJDK 7 or 8 depending on the distro release)
- Or reuse any installed openjdk-7|8-jre-headless
- Or reuse any installed package that satisfy the java7|8-runtime-headless

Revision history for this message
Tiago Stürmer Daitx (tdaitx) wrote :

Bug description says it affects 3 people. Let me know if improving the Depends: field did *not* fix this for you.

Meanwhile I will set it as Incomplete and it will be invalidated after a while if I get no response.

Changed in openjdk-9 (Ubuntu):
status: Confirmed → Incomplete
Revision history for this message
Jonas Kalderstam (jonas-ubuntuone) wrote :

I am not involved with Puppet. I just linked to them as an example. But your suggestion doesn't work since the problem is that Java9 is the default java8-runtime which is installed if you don't have java installed already.

And until Java9 is released, the default java8-runtime should be provided by Java8.

We went a different route to work around this:
https://github.com/neo4j/neo4j/commit/874c8da6bcb7b227b7451c06e4678924abc93800

Revision history for this message
Tiago Stürmer Daitx (tdaitx) wrote :

Jonas, thank you for your contribution.

> I am not involved with Puppet. I just linked to them
> as an example. But your suggestion doesn't work since

Actually, it does work just fine and will install OpenJDK 8 *if* the user has not installed OpenJDK 9 before (otherwise OpenJDK 9 will satisfy the java8|9-runtime dependencies). In order to guarantee that OpenJDK 8 is installed, it's better to drop javaX-runtime references altogether and instead use:
Depends: default-jre-headless | openjdk-7-jre-headless | openjdk-8-jre-headless

> the problem is that Java9 is the default java8-runtime
> which is installed if you don't have java installed
> already.

That is because both OpenJDK 8 and OpenJDK 9 packages provide the java8-runtime, but as openjdk-9-jre has a higher version it is the "preferred" install.

Since dpkg 1.17.11 [1] a virtual package in "Provides:" can be versioned, allowing a "Depends:" on a virtual package to also be versioned. I will investigate if and when we can start versioning the virtual packages of both OpenJDK 8 and 9. Please read the comment #33 in [1] to understand how that works.

> We went a different route to work around this:
> https://github.com/neo4j/neo4j/commit/874c8da6bcb7b227b7451c06e4678924abc93800

The issue I see is that a "Conflicts: java9-runtime-headless, java9-runtime" entry will force the user to select either that package (in this example, neo4j) OR OpenJDK 9.

Using such clause is also the wrong approach regarding Debian's policy [2]:
"Neither Breaks nor Conflicts should be used unless two packages cannot be installed at the same time or installing them both causes one of them to be broken or unusable. Having similar functionality or performing the same tasks as another package is not sufficient reason to declare Breaks or Conflicts with that package."

ie. having OpenJDK 9 installed does *not* cause neo4j to be broken as it is possible to have another OpenJDK version installed at the same time and use that to run neo4j.

[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=7330#38
[2] https://www.debian.org/doc/debian-policy/ch-relationships.html#s-conflicts

Revision history for this message
Jonas Kalderstam (jonas-ubuntuone) wrote :

Thanks for your reply

> Actually, it does work just fine and will install OpenJDK 8
> *if* the user has not installed OpenJDK 9 before (otherwise
> OpenJDK 9 will satisfy the java8|9-runtime dependencies)

I can confirm that this works. However, this introduces another issue
in case the user has installed for example an Oracle JRE, or even an
IBM JRE. In that case, openjdk-8 would unnecessarily be pulled in.

> That is because both OpenJDK 8 and OpenJDK 9 packages provide the
> java8-runtime, but as openjdk-9-jre has a higher version it is the
> "preferred" install.

It is perfectly reasonable for openjdk-9-jre to provide a
java8-runtime, anything else would be incorrect. However, it is very
surprising that it is the "preferred" install simply due to a "higher
version".

It is surprising because openjdk-9 is still in a pre-release version
and is scheduled for release next year [1]. Only when released would
it be the expected behavior.

> The issue I see is that a "Conflicts: java9-runtime-headless,
> java9-runtime" entry will force the user to select either that package
> (in this example, neo4j) OR OpenJDK 9.

Can you recommend a workaround which does not require Conflicts but
still remains compatible with multiple JREs (openjdk, oracle, ibm,
etc)?

[1]: http://openjdk.java.net/projects/jdk9/

Revision history for this message
Tiago Stürmer Daitx (tdaitx) wrote :

Thanks Jonas for your comments.

> I can confirm that this works. However, this introduces another issue
> in case the user has installed for example an Oracle JRE, or even an
> IBM JRE. In that case, openjdk-8 would unnecessarily be pulled in.

When using only "Depends:" it must contain each supported JRE in order to avoid this scenario.

> It is perfectly reasonable for openjdk-9-jre to provide a
> java8-runtime, anything else would be incorrect. However, it is very
> surprising that it is the "preferred" install simply due to a "higher
> version".

That was the situation before dpkg 1.17.11, when virtual packages couldn't be versioned.

> It is surprising because openjdk-9 is still in a pre-release version
> and is scheduled for release next year [1]. Only when released would
> it be the expected behavior.

Indeed, unfortunately for Xenial the openjdk-9 package already reached the release pocket and any update to it will land in the -updates pocket, thus we are unable to remove the java8-runtime from openjdk-9 "Provides: " - if we ever did that, then the version in the release pocket (9~b114-0ubuntu1) would take over.

> Can you recommend a workaround which does not require Conflicts but
> still remains compatible with multiple JREs (openjdk, oracle, ibm,
> etc)?

The only workaround right now is to list each compatible package in "Depends:".

The right way to go would be to depend on a versioned the virtual package (as soon as that support comes to openjdk-8 and openjdk-9).

Changed in openjdk-9 (Ubuntu):
status: Incomplete → Confirmed
Revision history for this message
Jonas Kalderstam (jonas-ubuntuone) wrote :

Tiago,

after some additional testing, this appears to be a solution, can you see
any problems with it?

```
Depends: ${misc:Depends}, bash, daemon, adduser, psmisc, lsb-base, openjdk-8-jre-headless | java8-runtime
Conflicts:
```

These were the results in my testing:

- With no JRE installed, openjdk-8-jre-headless is pulled in.
- With oracle-java8-installer from webupd8 already installed, no JRE is pulled in.

Am I correct in assuming that the first package (in this case openjdk-8-jre-headless) will be installed in case none of the (virtual) packages are installed on the system?

Revision history for this message
Tiago Stürmer Daitx (tdaitx) wrote :

> after some additional testing, this appears to
> be a solution, can you see any problems with it?

Any installed JRE that Provides java8-runtime will satisfy your Depends. Unfortunately that includes openjdk-9-jre - but then the user must have installed it beforehand. Otherwise openjdk-8-jre-headless will be installed.

It's exactly because openjdk-9-jre can also satisfy that Depends that I previously suggested depending explicitly on the JRE packages that you support instead of relying on the "java8-runtime" virtual package for a "catch all".

On a side note, if you prefer to keep relying on the virtual package you might want to use "java8-runtime-headless" instead of "java8-runtime" (given that your other dependency is "openjdk-8-jre-headless").

> These were the results in my testing:
> - With no JRE installed, openjdk-8-jre-headless
> is pulled in.
> - With oracle-java8-installer from webupd8 already
> installed, no JRE is pulled in.

Correct, if the user has previously installed any JRE that provides java8-runtime than no JRE will be pulled in.

> Am I correct in assuming that the first package
> (in this case openjdk-8-jre-headless) will be
> installed in case none of the (virtual) packages
> are installed on the system?

Yes, that is correct.

Revision history for this message
Jonas Kalderstam (jonas-ubuntuone) wrote :

> Any installed JRE that Provides java8-runtime will satisfy your Depends.
> Unfortunately that includes openjdk-9-jre - but then the user must have
> installed it beforehand. Otherwise openjdk-8-jre-headless will be
> installed.

We are OK with openjdk-9 satisfying the Depends as long as it has been
installed explicitly. The concern is primarily for less experienced users who do no have java installed already.

> It's exactly because openjdk-9-jre can also satisfy that Depends that I
> previously suggested depending explicitly on the JRE packages that you
> support instead of relying on the "java8-runtime" virtual package for a
> "catch all".

Problem for us is that we don't have a list of packages that we support. We have a clear list of supported JREs but only openjdk is available in a clear package. The rest might be called anything.

> On a side note, if you prefer to keep relying on the virtual package you
> might want to use "java8-runtime-headless" instead of "java8-runtime"
> (given that your other dependency is "openjdk-8-jre-headless").

Yes, good catch.

Thanks for your help on this issue.

BR
/Jonas

Revision history for this message
Matthias Klose (doko) wrote :

closing this issue. you should always have a dependency on a real package first, not just depending on a virtual package.

Changed in openjdk-9 (Ubuntu):
status: Confirmed → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.