Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-05-03 Thread Marián Konček

Replying to some previous comments:

* OpenJDK 21 is the last version to support Java 8 AFAIK.
* Indeed it is possible to compile projects using the system JDK 
together with the -target + -source / --release flags.
* In the spirit of "staying close to the upstream", the our (Maven) 
ecosystem does not touch the compilation flags unless the project can 
not be built using the system JDK. In that case we tend to override the 
selected version to the closest version supported by the system JDK. 
(See how moving to to OpenJDK 21 required adding these flags in majority 
of the failing builds.)
* I am in favor of adding soft RPM constraints on the Java libraries 
regarding the bytecode version (like Recommends field) but this move is 
heavily dependent on what the OpenJDK Provides fields are. I heard there 
was evolution and some complex reasons why they decided to change the 
Provides. For this reason, I am not in favor of adding hard constraints 
(Requires) on Java packages.


On 3. 5. 2024 7:44, Christopher wrote:

On Thu, May 2, 2024 at 9:24 PM Kevin Kofler via devel
 wrote:

Christopher wrote:

So, I actually think that building with the *latest* JDK that we ship,
and using the `--release` flag during compilation is actually safer
than building against the lowest that we support, because it is most
likely to strictly enforce correct byte code generation for the target
JRE.

The problem is, without ALSO installing the JDK for the targeted version AND
explicitly pointing -bootclasspath to that JDK, this does NOT catch code
trying to use class library features (as opposed to language or bytecode

For context, the use of the bootclasspath is only applicable to
building for Java 8. (A related question that I don't know the answer
to: how much longer is Fedora going to include Java 8?)

However, I believe you are incorrect. JEP 247, which added the
`--release` flag, specifically made it replace the need for using
`-bootclasspath`. See https://openjdk.org/jeps/247 ; The problem I
described in the email you're replying to is specifically that the
`-bootclasspath` with JDK 8 will pick up class APIs *outside* of the
"", whereas the use of `--release 8` strictly
enforces that only the "" are available. This
is what I meant when I said that using the `--release` flag more
strictly enforces Java 8 language compliance than building with JDK 8.
I stand by that statement. It is the `-bootclasspath` that leads
people astray, and thus it has been removed for Java 9 and later.


features) from the newer JDK, and worse, in rare occasions, even if the
source code is in principle compatible with the targeted older Java, when
compiled with a newer compiler and older target release, it will fail to
actually run (!) with the latter (because the compiler picks up a subclass
override of a method added in the newer Java instead of the baseclass method
that was always available and, for performance reasons, tries calling the
override explicitly rather than going through the virtual method lookup).
One example of that latter issue is NetBeans, where versions 12.5 and 12.6
were supposed to be compatible with Java 8, but some upstream-published
binaries of 12.5 and all of 12.6 do not actually work properly on it because
they were built with Java 11 in "-release 8" mode: some editor features fail
with runtime exceptions. See
https://issues.apache.org/jira/browse/NETBEANS-6349 for details. (They
"fixed" it by just requiring Java 11 in NetBeans 13 and newer. No fixed 12.x
release was ever issued.)

The CharBuffer/ByteBuffer issues mentioned in that are specifically
issues that the use of `--release` resolves. I have fixed this in
several projects already who encountered this same issue. Digging into
the tickets you linked, it looks like the problem with that issue was
that the binaries were built with JDK 11 *without* the use of the
`--release` flag... or rather, it looks like somebody tried to use the
`--release` flag, but they also used `-Xbootclasspath`, which ended up
*disabling* the `--release` behavior. The problem isn't the use of
`--release`, it's the *non*-use of it... or the broken use of it,
because boot class path options are still being used when they
shouldn't. So again, I assert that it's the `-bootclasspath` option
that is leading people astray.


So I am AGAINST systematically using "-release" without "-bootclasspath",
even though that works in most cases and is often successfully used in
production (me and my employer use it, too, but on projects we control where
we will fix the source code or add a workaround to it if any issues come up
from that, not systematically on repackaging third-party projects). The
compiler even warns about the missing "-bootclasspath". And the potential to
cause subtle misbehavior that is a pain to debug is just too high,
especially if we have the actual older JDK available and could just
BuildRequire the correct version.

This doesn't make sense. The purpose of the `--release` flag was to
repl

Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-05-02 Thread Christopher
On Thu, May 2, 2024 at 9:24 PM Kevin Kofler via devel
 wrote:
>
> Christopher wrote:
> > So, I actually think that building with the *latest* JDK that we ship,
> > and using the `--release` flag during compilation is actually safer
> > than building against the lowest that we support, because it is most
> > likely to strictly enforce correct byte code generation for the target
> > JRE.
>
> The problem is, without ALSO installing the JDK for the targeted version AND
> explicitly pointing -bootclasspath to that JDK, this does NOT catch code
> trying to use class library features (as opposed to language or bytecode

For context, the use of the bootclasspath is only applicable to
building for Java 8. (A related question that I don't know the answer
to: how much longer is Fedora going to include Java 8?)

However, I believe you are incorrect. JEP 247, which added the
`--release` flag, specifically made it replace the need for using
`-bootclasspath`. See https://openjdk.org/jeps/247 ; The problem I
described in the email you're replying to is specifically that the
`-bootclasspath` with JDK 8 will pick up class APIs *outside* of the
"", whereas the use of `--release 8` strictly
enforces that only the "" are available. This
is what I meant when I said that using the `--release` flag more
strictly enforces Java 8 language compliance than building with JDK 8.
I stand by that statement. It is the `-bootclasspath` that leads
people astray, and thus it has been removed for Java 9 and later.

> features) from the newer JDK, and worse, in rare occasions, even if the
> source code is in principle compatible with the targeted older Java, when
> compiled with a newer compiler and older target release, it will fail to
> actually run (!) with the latter (because the compiler picks up a subclass
> override of a method added in the newer Java instead of the baseclass method
> that was always available and, for performance reasons, tries calling the
> override explicitly rather than going through the virtual method lookup).
> One example of that latter issue is NetBeans, where versions 12.5 and 12.6
> were supposed to be compatible with Java 8, but some upstream-published
> binaries of 12.5 and all of 12.6 do not actually work properly on it because
> they were built with Java 11 in "-release 8" mode: some editor features fail
> with runtime exceptions. See
> https://issues.apache.org/jira/browse/NETBEANS-6349 for details. (They
> "fixed" it by just requiring Java 11 in NetBeans 13 and newer. No fixed 12.x
> release was ever issued.)

The CharBuffer/ByteBuffer issues mentioned in that are specifically
issues that the use of `--release` resolves. I have fixed this in
several projects already who encountered this same issue. Digging into
the tickets you linked, it looks like the problem with that issue was
that the binaries were built with JDK 11 *without* the use of the
`--release` flag... or rather, it looks like somebody tried to use the
`--release` flag, but they also used `-Xbootclasspath`, which ended up
*disabling* the `--release` behavior. The problem isn't the use of
`--release`, it's the *non*-use of it... or the broken use of it,
because boot class path options are still being used when they
shouldn't. So again, I assert that it's the `-bootclasspath` option
that is leading people astray.

>
> So I am AGAINST systematically using "-release" without "-bootclasspath",
> even though that works in most cases and is often successfully used in
> production (me and my employer use it, too, but on projects we control where
> we will fix the source code or add a workaround to it if any issues come up
> from that, not systematically on repackaging third-party projects). The
> compiler even warns about the missing "-bootclasspath". And the potential to
> cause subtle misbehavior that is a pain to debug is just too high,
> especially if we have the actual older JDK available and could just
> BuildRequire the correct version.

This doesn't make sense. The purpose of the `--release` flag was to
replace the need for `-bootclasspath`. The `-bootclasspath` doesn't
exist anymore for JDK 9 compliance and later, and using it *breaks*
the compliance checks done by `--release` by allowing the built-in
checks to be overridden.

As for the warning you've mentioned... I'm not sure what warning
you're referring to. I've never seen such a warning and have been
using `--release` for a long time now.

Respectfully, I think you're wrong on some of the points you're
raising. Please look into the points I've made, and correct me if it
turns out that I'm the one in error. Getting this correct is important
to me, and I think it matters for Fedora's Java packaging guidelines,
even if it doesn't end up affecting the decision about Requires. So,
I'd like to know if I'm wrong.

>
> Kevin Kofler
> --
> ___
> devel mailing list -- devel@lists.fedoraproject.org
> To unsubscribe send an email to devel-le...@li

Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-05-02 Thread Carlos Rodriguez-Fernandez
Sorry, with "package" I mean a *new* package for jdk 17, depending on a 
lib built and tested only for jdk 8 to 11. Basically, that metadata in 
the rpm for the lib would not have that runtime information for any new 
package wanting to depend on it targeted for jdk 17.


On 5/2/24 18:35, Kevin Kofler via devel wrote:

Carlos Rodriguez-Fernandez wrote:

How could that be expressed so that those are caught quickly at build
time? Someone wants to depend on a java lib that has been tested only in
JRE 8 to 11, but wants to build the package with JRE 17+, or vice-versa,
for example. Perhaps, the only feasible way to detect that case is with
CI.


IMHO, the library should have a:
Requires: (java-devel >= 1:8 with java-devel < 1:11)

Sure, this will not per se prevent you from attempting to use the library
with the Java 17 compiler, but if you do not have Java 8 or 11 installed,
installing the library attempting to install it as a dependency should raise
a red flag.

As a quick check, you could write a specfile for your application with:
BuildRequires: java-devel >= 1:17
BuildConflicts: java-devel < 1:17
and then run mock on that. The latter line should prevent the old version
from being installed in parallel.

One annoyance is that older OpenJDK packages currently drop that virtual
Provides, presumably in an attempt to get all Java packages systematically
built with a newer JDK. That is something that ought to get fixed. (If we
switch to building with the oldest possible Java as I suggest, it will have
to get fixed anyway.) As is, you may need to explicitly:
BuildConflicts: java-1.8.0-devel
BuildConflicts: java-11-devel

 Kevin Kofler
--
___
devel mailing list -- devel@lists.fedoraproject.org
To unsubscribe send an email to devel-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue


OpenPGP_signature.asc
Description: OpenPGP digital signature
--
___
devel mailing list -- devel@lists.fedoraproject.org
To unsubscribe send an email to devel-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue


Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-05-02 Thread Kevin Kofler via devel
Carlos Rodriguez-Fernandez wrote:
> How could that be expressed so that those are caught quickly at build
> time? Someone wants to depend on a java lib that has been tested only in
> JRE 8 to 11, but wants to build the package with JRE 17+, or vice-versa,
> for example. Perhaps, the only feasible way to detect that case is with
> CI.

IMHO, the library should have a:
Requires: (java-devel >= 1:8 with java-devel < 1:11)

Sure, this will not per se prevent you from attempting to use the library 
with the Java 17 compiler, but if you do not have Java 8 or 11 installed, 
installing the library attempting to install it as a dependency should raise 
a red flag.

As a quick check, you could write a specfile for your application with:
BuildRequires: java-devel >= 1:17
BuildConflicts: java-devel < 1:17
and then run mock on that. The latter line should prevent the old version 
from being installed in parallel.

One annoyance is that older OpenJDK packages currently drop that virtual 
Provides, presumably in an attempt to get all Java packages systematically 
built with a newer JDK. That is something that ought to get fixed. (If we 
switch to building with the oldest possible Java as I suggest, it will have 
to get fixed anyway.) As is, you may need to explicitly:
BuildConflicts: java-1.8.0-devel
BuildConflicts: java-11-devel

Kevin Kofler
--
___
devel mailing list -- devel@lists.fedoraproject.org
To unsubscribe send an email to devel-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue


Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-05-02 Thread Kevin Kofler via devel
Christopher wrote:
> So, I actually think that building with the *latest* JDK that we ship,
> and using the `--release` flag during compilation is actually safer
> than building against the lowest that we support, because it is most
> likely to strictly enforce correct byte code generation for the target
> JRE.

The problem is, without ALSO installing the JDK for the targeted version AND 
explicitly pointing -bootclasspath to that JDK, this does NOT catch code 
trying to use class library features (as opposed to language or bytecode 
features) from the newer JDK, and worse, in rare occasions, even if the 
source code is in principle compatible with the targeted older Java, when 
compiled with a newer compiler and older target release, it will fail to 
actually run (!) with the latter (because the compiler picks up a subclass 
override of a method added in the newer Java instead of the baseclass method 
that was always available and, for performance reasons, tries calling the 
override explicitly rather than going through the virtual method lookup). 
One example of that latter issue is NetBeans, where versions 12.5 and 12.6 
were supposed to be compatible with Java 8, but some upstream-published 
binaries of 12.5 and all of 12.6 do not actually work properly on it because 
they were built with Java 11 in "-release 8" mode: some editor features fail 
with runtime exceptions. See 
https://issues.apache.org/jira/browse/NETBEANS-6349 for details. (They 
"fixed" it by just requiring Java 11 in NetBeans 13 and newer. No fixed 12.x 
release was ever issued.)

So I am AGAINST systematically using "-release" without "-bootclasspath", 
even though that works in most cases and is often successfully used in 
production (me and my employer use it, too, but on projects we control where 
we will fix the source code or add a workaround to it if any issues come up 
from that, not systematically on repackaging third-party projects). The 
compiler even warns about the missing "-bootclasspath". And the potential to 
cause subtle misbehavior that is a pain to debug is just too high, 
especially if we have the actual older JDK available and could just 
BuildRequire the correct version.

Kevin Kofler
--
___
devel mailing list -- devel@lists.fedoraproject.org
To unsubscribe send an email to devel-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue


Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-05-02 Thread Carlos Rodriguez-Fernandez
I have dealt with bugs where a library runs well in JRE 11, but crashes 
when run in JRE 17 because the InetSocketAddress implementation changed. 
Totally unrelated with the language features or bytecode versions.


Nevertheless, even in that case, if I bring in that library from the 
distro repo, I wouldn't want that lib to also bring JRE 11, because I'll 
be running my app in JRE 17, however, ... I'd learn quickly that it fails.


The other way around can happen too, a library runs well in 17, but 
crashes in JRE 11 because of that InetSocketAddress change, for example.


How could that be expressed so that those are caught quickly at build 
time? Someone wants to depend on a java lib that has been tested only in 
JRE 8 to 11, but wants to build the package with JRE 17+, or vice-versa, 
for example. Perhaps, the only feasible way to detect that case is with CI.



On 5/2/24 11:58, Christopher wrote:

On Thu, May 2, 2024 at 6:59 AM Kevin Kofler via devel
 wrote:


Carlos Rodriguez-Fernandez wrote:

Regarding the proposal as a whole, I think the proposal idea makes a lot
of sense, but for apps depending on system jar libraries, there should
be a way to specify that the app depends on a specific java bytecode
version range. System libraries packages could provide compatibility
packages, so couldn't those apps just depend on those compatibility
packages instead? That can become a maintenance burden for those libs,
though.


The safest approach for library JARs would be to always build them against
the lowest possible Java version (the oldest JDK branch that we still ship
if the library supports that, otherwise the oldest the library supports).
And IMHO, if the library is built against a higher version than the lowest
we ship, it needs a versioned Requires on the JRE.

 Kevin Kofler


I have noticed that the `--release` flag on javac (JDK>=9) actually
enforces JLS compliance more strictly than even compiling with the
specific version it targets. For example, it is possible to write a
project that is non-compliant with the Java 8 JLS that the Java 8
compiler will incorrectly permit without error. Such a project will
not work properly on Java 9 and newer JREs. However, if JDK 9 were
used to compile the project with `javac --release 8`, the compiler
will catch the non-compliance with the Java 8 JLS that the JDK 8
compiler failed to catch, forcing compliance with Java 8, and allowing
the resulting byte code to work on JRE 9 and later.

So, I actually think that building with the *latest* JDK that we ship,
and using the `--release` flag during compilation is actually safer
than building against the lowest that we support, because it is most
likely to strictly enforce correct byte code generation for the target
JRE. But, this requires project maintainers to explicitly add the use
of the `--release` flag if the upstream build does not already set it
in some way. Doing this, it should not matter which of our JDKs it
builds with, but building with the latest available (rather than the
oldest available, as Kevin suggests) will have the best chance for
compliance-related bugs to be fixed (but only if the `--release` flag
is used). Of course, there are many ways to break Java libraries
across JRE versions, but the one I'm focusing on here is one that is
preventable, due to JDK enforcement of JLS compliance during
compilation, which is more strict in newer JDKs than in earlier ones.

If upstream's oldest supported JRE is still supported by the
`--release` flag by the JDK used in Fedora's build, then it should be
fine to just specify that version, even if it is older than the oldest
JRE that Fedora ships. In such cases, it might not technically be
necessary to specify a Requires for the JRE. However, if the oldest
supported JRE in the upstream project is newer than Fedora's oldest
shipped JRE, then having the Requires >= would still be needed. For
example, if Fedora ships JRE 11, 17, and 21, and the upstream project
targets Java 8, then it should be fine to build that project using JDK
21 with `--release 8` and have no Requires. However, if upstream
targets Java 11, then building using JDK 21 with `--release 11` would
be okay, but you'd need Requires >= 11 (or maybe Recommends >= 11 ?).

I don't object to the original proposal, though. There have been times
I've wanted to install a Java library not to run it, but to inspect
the jar with a third-party tool (or even just vim). But, I think it's
important for Java package maintainers to be aware of what versions
their packages' upstream projects are targeting, and make sure they
are built correctly for Fedora using Fedora's JDKs. I also think it's
important that Fedora packagers communicate the JRE requirements for
each package *if* it were to be run. Maybe that can be done with
Recommends instead of Requires? I'm not sure about that part, but I
acknowledge that installing a library is not the same as intending for
it to be run.

Christopher
--
___

Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-05-02 Thread Christopher
On Thu, May 2, 2024 at 6:59 AM Kevin Kofler via devel
 wrote:
>
> Carlos Rodriguez-Fernandez wrote:
> > Regarding the proposal as a whole, I think the proposal idea makes a lot
> > of sense, but for apps depending on system jar libraries, there should
> > be a way to specify that the app depends on a specific java bytecode
> > version range. System libraries packages could provide compatibility
> > packages, so couldn't those apps just depend on those compatibility
> > packages instead? That can become a maintenance burden for those libs,
> > though.
>
> The safest approach for library JARs would be to always build them against
> the lowest possible Java version (the oldest JDK branch that we still ship
> if the library supports that, otherwise the oldest the library supports).
> And IMHO, if the library is built against a higher version than the lowest
> we ship, it needs a versioned Requires on the JRE.
>
> Kevin Kofler

I have noticed that the `--release` flag on javac (JDK>=9) actually
enforces JLS compliance more strictly than even compiling with the
specific version it targets. For example, it is possible to write a
project that is non-compliant with the Java 8 JLS that the Java 8
compiler will incorrectly permit without error. Such a project will
not work properly on Java 9 and newer JREs. However, if JDK 9 were
used to compile the project with `javac --release 8`, the compiler
will catch the non-compliance with the Java 8 JLS that the JDK 8
compiler failed to catch, forcing compliance with Java 8, and allowing
the resulting byte code to work on JRE 9 and later.

So, I actually think that building with the *latest* JDK that we ship,
and using the `--release` flag during compilation is actually safer
than building against the lowest that we support, because it is most
likely to strictly enforce correct byte code generation for the target
JRE. But, this requires project maintainers to explicitly add the use
of the `--release` flag if the upstream build does not already set it
in some way. Doing this, it should not matter which of our JDKs it
builds with, but building with the latest available (rather than the
oldest available, as Kevin suggests) will have the best chance for
compliance-related bugs to be fixed (but only if the `--release` flag
is used). Of course, there are many ways to break Java libraries
across JRE versions, but the one I'm focusing on here is one that is
preventable, due to JDK enforcement of JLS compliance during
compilation, which is more strict in newer JDKs than in earlier ones.

If upstream's oldest supported JRE is still supported by the
`--release` flag by the JDK used in Fedora's build, then it should be
fine to just specify that version, even if it is older than the oldest
JRE that Fedora ships. In such cases, it might not technically be
necessary to specify a Requires for the JRE. However, if the oldest
supported JRE in the upstream project is newer than Fedora's oldest
shipped JRE, then having the Requires >= would still be needed. For
example, if Fedora ships JRE 11, 17, and 21, and the upstream project
targets Java 8, then it should be fine to build that project using JDK
21 with `--release 8` and have no Requires. However, if upstream
targets Java 11, then building using JDK 21 with `--release 11` would
be okay, but you'd need Requires >= 11 (or maybe Recommends >= 11 ?).

I don't object to the original proposal, though. There have been times
I've wanted to install a Java library not to run it, but to inspect
the jar with a third-party tool (or even just vim). But, I think it's
important for Java package maintainers to be aware of what versions
their packages' upstream projects are targeting, and make sure they
are built correctly for Fedora using Fedora's JDKs. I also think it's
important that Fedora packagers communicate the JRE requirements for
each package *if* it were to be run. Maybe that can be done with
Recommends instead of Requires? I'm not sure about that part, but I
acknowledge that installing a library is not the same as intending for
it to be run.

Christopher
--
___
devel mailing list -- devel@lists.fedoraproject.org
To unsubscribe send an email to devel-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue


Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-05-02 Thread Kevin Kofler via devel
Carlos Rodriguez-Fernandez wrote:
> Regarding the proposal as a whole, I think the proposal idea makes a lot
> of sense, but for apps depending on system jar libraries, there should
> be a way to specify that the app depends on a specific java bytecode
> version range. System libraries packages could provide compatibility
> packages, so couldn't those apps just depend on those compatibility
> packages instead? That can become a maintenance burden for those libs,
> though.

The safest approach for library JARs would be to always build them against 
the lowest possible Java version (the oldest JDK branch that we still ship 
if the library supports that, otherwise the oldest the library supports). 
And IMHO, if the library is built against a higher version than the lowest 
we ship, it needs a versioned Requires on the JRE.

Kevin Kofler
--
___
devel mailing list -- devel@lists.fedoraproject.org
To unsubscribe send an email to devel-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue


Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-04-30 Thread Carlos Rodriguez-Fernandez

Marián,

I echo your concerns, however, regarding jars with multiple bytecode 
versions, aren't java rpm expected to build their sources with one 
specific JDK? (per the guidelines) how can multiple bytecode version end 
up in the JAR in that scenario?



Regarding the proposal as a whole, I think the proposal idea makes a lot 
of sense, but for apps depending on system jar libraries, there should 
be a way to specify that the app depends on a specific java bytecode 
version range. System libraries packages could provide compatibility 
packages, so couldn't those apps just depend on those compatibility 
packages instead? That can become a maintenance burden for those libs, 
though.


Thank you,
Carlos.

On 4/30/24 07:56, Marián Konček wrote:

On 25. 4. 2024 17:46, Michel Lind wrote:



On 4/24/24 11:14 AM, Aoife Moloney wrote:
Wiki - 
https://fedoraproject.org/wiki/Changes/Drop_Mandatory_Requires_on_JRE
Announced - 
https://discussion.fedoraproject.org/t/f41-change-proposal-drop-mandatory-requires-on-jre-system-wide/114186



[snip]



=== Context ===
Java packages are compiled using `javac` into `.class` files and
composed into `.jar` archives. Jar archives can be used as compile or
runtime dependencies for other packages or can be directly executed
with the java command provided by a JRE.

Jar archives can be executed using the command: `java -jar ${FILE}`.
This command executes the `main` method either specified via CLI or
specified within the Jar manifest file.

Java packages, which serve as libraries only, lack the `main` method
and are not executable. Therefore, there is no requirement on any
specific JRE imposed by the library implicitly.

Sort of... bytecodes do get introduced over time, right? While in 
practice I expect nobody will try and running, say, anything older 
than Java 7 (JSR 7 introduced invokedynamic), should there be a way to 
specify a generic minimum runtime version? I guess the tricky thing 
here is that different JDKs might not be packaged in a way where they 
all implement a common virtual provide that can be targeted


$ fedrq pkgs -P java-headless
java-21-openjdk-headless-1:21.0.2.0.13-3.fc41.x86_64

$ fedrq pkgs -P java-headless -F provides
libjsvml.so()(64bit)
libsyslookup.so()(64bit)
libjvm.so()(64bit)
libjvm.so(SUNWprivate_1.1)(64bit)
lible.so()(64bit)
libjava.so()(64bit)
libjsig.so()(64bit)
libverify.so()(64bit)
java-21-openjdk-headless(x86-64) = 1:21.0.2.0.13-3.fc41
config(java-21-openjdk-headless) = 1:21.0.2.0.13-3.fc41
java-21-headless = 1:21.0.2.0.13-3.fc41
java-21-openjdk-headless = 1:21.0.2.0.13-3.fc41
java-headless = 1:21.0.2.0.13-3.fc41
java-openjdk-headless = 1:21.0.2.0.13-3.fc41
jre-21-headless = 1:21.0.2.0.13-3.fc41
jre-21-openjdk-headless = 1:21.0.2.0.13-3.fc41
jre-headless = 1:21.0.2.0.13-3.fc41
jre-openjdk-headless = 1:21.0.2.0.13-3.fc41

Every major JDK version introduces a new bytecode version. The bytecode 
version number is part of the .class file format. If an older JVM is 
attempting to load a .class with a higher bytecode version than it 
supports, it fails without attempting to load it.


What you propose makes some sense but I am not completely convinced it 
is a good idea. First of all we need to agree on the meaning of the 
Requires field and what it means to install a package.
* Does one install a package just to look at the files / contents / 
bytecode of the classes? In that case there is no strict requirement on 
the bytecode interpreter (= JVM).
* Does one install a package to **use** it? To load the bytecode using 
some JVM? In that case adding a requirement to the package turns a 
runtime failure (to load the class) into an RPM transaction.


Even if we would agree on the second option, there is another problem: 
an .rpm archive can contain multiple .jar files. a .jar archive consists 
of multiple .class files. Bytecode version is specified for each .class 
file. While a generator that walks over the whole contents and extracts 
the bytecode version numbers could be implemented, should it simply 
reduce the numbers to a maximum? That would possibly prevent the users 
from some valid use cases. Should the packaging guidelines specify that 
an .rpm package may install at most one .jar archive? Although rare, 
there are cases when even .class files in a single .jar have different 
versions. Most notable case: module-info.jar with bytecode version for 
Java 9 and the rest of the source files with version for Java < 9.


Looking at it, I see many questions and potential problems but I also 
find this idea intriguing, to have a generated `Requires: java-bytecode 
 >= 55` or something like that.


This would also require all the JVMs to Provide such a field.

The spirit of this proposal, however, is to allow more freedom for the 
package users at the cost of disabling some implicit behaviours.



=== Different JDKs ===
This proposal is also related to the topic of different JDKs.
Developers may want to use or build packages

Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-04-30 Thread Marián Konček

On 25. 4. 2024 17:46, Michel Lind wrote:



On 4/24/24 11:14 AM, Aoife Moloney wrote:
Wiki - 
https://fedoraproject.org/wiki/Changes/Drop_Mandatory_Requires_on_JRE
Announced - 
https://discussion.fedoraproject.org/t/f41-change-proposal-drop-mandatory-requires-on-jre-system-wide/114186



[snip]



=== Context ===
Java packages are compiled using `javac` into `.class` files and
composed into `.jar` archives. Jar archives can be used as compile or
runtime dependencies for other packages or can be directly executed
with the java command provided by a JRE.

Jar archives can be executed using the command: `java -jar ${FILE}`.
This command executes the `main` method either specified via CLI or
specified within the Jar manifest file.

Java packages, which serve as libraries only, lack the `main` method
and are not executable. Therefore, there is no requirement on any
specific JRE imposed by the library implicitly.

Sort of... bytecodes do get introduced over time, right? While in 
practice I expect nobody will try and running, say, anything older 
than Java 7 (JSR 7 introduced invokedynamic), should there be a way to 
specify a generic minimum runtime version? I guess the tricky thing 
here is that different JDKs might not be packaged in a way where they 
all implement a common virtual provide that can be targeted


$ fedrq pkgs -P java-headless
java-21-openjdk-headless-1:21.0.2.0.13-3.fc41.x86_64

$ fedrq pkgs -P java-headless -F provides
libjsvml.so()(64bit)
libsyslookup.so()(64bit)
libjvm.so()(64bit)
libjvm.so(SUNWprivate_1.1)(64bit)
lible.so()(64bit)
libjava.so()(64bit)
libjsig.so()(64bit)
libverify.so()(64bit)
java-21-openjdk-headless(x86-64) = 1:21.0.2.0.13-3.fc41
config(java-21-openjdk-headless) = 1:21.0.2.0.13-3.fc41
java-21-headless = 1:21.0.2.0.13-3.fc41
java-21-openjdk-headless = 1:21.0.2.0.13-3.fc41
java-headless = 1:21.0.2.0.13-3.fc41
java-openjdk-headless = 1:21.0.2.0.13-3.fc41
jre-21-headless = 1:21.0.2.0.13-3.fc41
jre-21-openjdk-headless = 1:21.0.2.0.13-3.fc41
jre-headless = 1:21.0.2.0.13-3.fc41
jre-openjdk-headless = 1:21.0.2.0.13-3.fc41

Every major JDK version introduces a new bytecode version. The bytecode 
version number is part of the .class file format. If an older JVM is 
attempting to load a .class with a higher bytecode version than it 
supports, it fails without attempting to load it.


What you propose makes some sense but I am not completely convinced it 
is a good idea. First of all we need to agree on the meaning of the 
Requires field and what it means to install a package.
* Does one install a package just to look at the files / contents / 
bytecode of the classes? In that case there is no strict requirement on 
the bytecode interpreter (= JVM).
* Does one install a package to **use** it? To load the bytecode using 
some JVM? In that case adding a requirement to the package turns a 
runtime failure (to load the class) into an RPM transaction.


Even if we would agree on the second option, there is another problem: 
an .rpm archive can contain multiple .jar files. a .jar archive consists 
of multiple .class files. Bytecode version is specified for each .class 
file. While a generator that walks over the whole contents and extracts 
the bytecode version numbers could be implemented, should it simply 
reduce the numbers to a maximum? That would possibly prevent the users 
from some valid use cases. Should the packaging guidelines specify that 
an .rpm package may install at most one .jar archive? Although rare, 
there are cases when even .class files in a single .jar have different 
versions. Most notable case: module-info.jar with bytecode version for 
Java 9 and the rest of the source files with version for Java < 9.


Looking at it, I see many questions and potential problems but I also 
find this idea intriguing, to have a generated `Requires: java-bytecode 
>= 55` or something like that.


This would also require all the JVMs to Provide such a field.

The spirit of this proposal, however, is to allow more freedom for the 
package users at the cost of disabling some implicit behaviours.



=== Different JDKs ===
This proposal is also related to the topic of different JDKs.
Developers may want to use or build packages which use a JDK different
than the one provided by the `java--openjdk` package. After this
proposal was implemented, they would be able to depend on Java library
packages with no introduction of the OpenJDK package.

=== Rationale ===
Java libraries are more similar to native libraries than to libraries
written in dynamic scripting languages. They are compiled to a
bytecode and are not executable. Java libraries can be used as
dependencies for any Java application and there is no implicit
dependency on the system default JDK.

Java applications, on the other hand, are expected to be tested and to
work with the system JDK and from the user's perspective: after
installing an application they must be able to simply run the binary.
Therefore the `Requi

Re: F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-04-25 Thread Michel Lind



On 4/24/24 11:14 AM, Aoife Moloney wrote:

Wiki - https://fedoraproject.org/wiki/Changes/Drop_Mandatory_Requires_on_JRE
Announced - 
https://discussion.fedoraproject.org/t/f41-change-proposal-drop-mandatory-requires-on-jre-system-wide/114186


[snip]



=== Context ===
Java packages are compiled using `javac` into `.class` files and
composed into `.jar` archives. Jar archives can be used as compile or
runtime dependencies for other packages or can be directly executed
with the java command provided by a JRE.

Jar archives can be executed using the command: `java -jar ${FILE}`.
This command executes the `main` method either specified via CLI or
specified within the Jar manifest file.

Java packages, which serve as libraries only, lack the `main` method
and are not executable. Therefore, there is no requirement on any
specific JRE imposed by the library implicitly.

Sort of... bytecodes do get introduced over time, right? While in practice I 
expect nobody will try and running, say, anything older than Java 7 (JSR 7 
introduced invokedynamic), should there be a way to specify a generic minimum 
runtime version? I guess the tricky thing here is that different JDKs might not 
be packaged in a way where they all implement a common virtual provide that can 
be targeted


$ fedrq pkgs -P java-headless
java-21-openjdk-headless-1:21.0.2.0.13-3.fc41.x86_64

$ fedrq pkgs -P java-headless -F provides
libjsvml.so()(64bit)
libsyslookup.so()(64bit)
libjvm.so()(64bit)
libjvm.so(SUNWprivate_1.1)(64bit)
lible.so()(64bit)
libjava.so()(64bit)
libjsig.so()(64bit)
libverify.so()(64bit)
java-21-openjdk-headless(x86-64) = 1:21.0.2.0.13-3.fc41
config(java-21-openjdk-headless) = 1:21.0.2.0.13-3.fc41
java-21-headless = 1:21.0.2.0.13-3.fc41
java-21-openjdk-headless = 1:21.0.2.0.13-3.fc41
java-headless = 1:21.0.2.0.13-3.fc41
java-openjdk-headless = 1:21.0.2.0.13-3.fc41
jre-21-headless = 1:21.0.2.0.13-3.fc41
jre-21-openjdk-headless = 1:21.0.2.0.13-3.fc41
jre-headless = 1:21.0.2.0.13-3.fc41
jre-openjdk-headless = 1:21.0.2.0.13-3.fc41


=== Different JDKs ===
This proposal is also related to the topic of different JDKs.
Developers may want to use or build packages which use a JDK different
than the one provided by the `java--openjdk` package. After this
proposal was implemented, they would be able to depend on Java library
packages with no introduction of the OpenJDK package.

=== Rationale ===
Java libraries are more similar to native libraries than to libraries
written in dynamic scripting languages. They are compiled to a
bytecode and are not executable. Java libraries can be used as
dependencies for any Java application and there is no implicit
dependency on the system default JDK.

Java applications, on the other hand, are expected to be tested and to
work with the system JDK and from the user's perspective: after
installing an application they must be able to simply run the binary.
Therefore the `Requires` on the system JDK is kept for Java
applications.

Would this be clearer if it says "the JRE from the system JDK"? Since the apps 
are not actually pulling in the full JDK itself.


Best regards,

--
 _o) Michel Lind
_( ) identities: https://keyoxide.org/5dce2e7e9c3b1cffd335c1d78b229d2f7ccc04f2


OpenPGP_0x8B229D2F7CCC04F2.asc
Description: OpenPGP public key


OpenPGP_signature.asc
Description: OpenPGP digital signature
--
___
devel mailing list -- devel@lists.fedoraproject.org
To unsubscribe send an email to devel-le...@lists.fedoraproject.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue


F41 Change Proposal: Drop Mandatory Requires on JRE (system-wide)

2024-04-24 Thread Aoife Moloney
Wiki - https://fedoraproject.org/wiki/Changes/Drop_Mandatory_Requires_on_JRE
Announced - 
https://discussion.fedoraproject.org/t/f41-change-proposal-drop-mandatory-requires-on-jre-system-wide/114186

This is a proposed Change for Fedora Linux.
This document represents a proposed Change. As part of the Changes
process, proposals are publicly announced in order to receive
community feedback. This proposal will only be implemented if approved
by the Fedora Engineering Steering Committee.


== Summary ==
Drop the requirement of Java libraries to have Requires on JREs.

== Owner ==
* Name: [[User:mkoncek| Marián Konček]]
* Email: mkon...@redhat.com

== Detailed Description ==
Current 
[https://docs.fedoraproject.org/en-US/packaging-guidelines/Java/#_buildrequires_and_requires
guidelines] require all Java packages to `Require: java-headless or
java-headless >= 1:minimal_required_version`.

Our aim is to drop this explicit requirement on Java library packages.
The requirement should stay for Java applications.


=== Context ===
Java packages are compiled using `javac` into `.class` files and
composed into `.jar` archives. Jar archives can be used as compile or
runtime dependencies for other packages or can be directly executed
with the java command provided by a JRE.

Jar archives can be executed using the command: `java -jar ${FILE}`.
This command executes the `main` method either specified via CLI or
specified within the Jar manifest file.

Java packages, which serve as libraries only, lack the `main` method
and are not executable. Therefore, there is no requirement on any
specific JRE imposed by the library implicitly.

=== Different JDKs ===
This proposal is also related to the topic of different JDKs.
Developers may want to use or build packages which use a JDK different
than the one provided by the `java--openjdk` package. After this
proposal was implemented, they would be able to depend on Java library
packages with no introduction of the OpenJDK package.

=== Rationale ===
Java libraries are more similar to native libraries than to libraries
written in dynamic scripting languages. They are compiled to a
bytecode and are not executable. Java libraries can be used as
dependencies for any Java application and there is no implicit
dependency on the system default JDK.

Java applications, on the other hand, are expected to be tested and to
work with the system JDK and from the user's perspective: after
installing an application they must be able to simply run the binary.
Therefore the `Requires` on the system JDK is kept for Java
applications.

== Feedback ==


== Benefit to Fedora ==
* Very little user-visible benefit.
* Reduced dependencies of Java packages.
* Simplified maintenance of Java packages.
** Smaller impact of JDK major updates (e.g. `1.8.0 -> 11 -> 17 ->
21`). Introducing a new system version of JDK requires the rebuild of
each Java package in order to have updated `Requires` to contain the
newest version.


== Scope ==
* Proposal owners:
** Find all Java applications in Fedora, i.e. packages which
`BuildRequire` `java-devel / maven-local / ant` and at the same time
install files into `/bin` or `/sbin` or `/usr/bin` or `/usr/sbin`.
** Open pull requests adding `Requires: java-headless` into their `.spec` file.
** Remove `Requires` generator from
[https://src.fedoraproject.org/rpms/javapackages-tools/blob/8714cc1d03d3f31251539c3fca53383b822834bc/f/javapackages-config.json#_5
javapackages-tools]
** Wait for a mass rebuild.

* Other developers:
** Maintainers of Java applications will need to add an explicit
`Requires: java-headless` field into their `.spec` file or a specific
version of thereof (such as `java-17-openjdk-headless`).

* Release engineering: [https://pagure.io/releng/issue/12069 #12069]
** Mass rebuild is not required, this change can propagate via natural rebuilds.

* Policies and guidelines:
** Guidelines need to be modified
([https://pagure.io/packaging-committee/pull-request/1360 open Pull
Request]).

* Trademark approval: N/A (not needed for this Change)

* Alignment with Community Initiatives: N/A


== Upgrade/compatibility impact ==
* For Java libraries:
** This change is removing `Requires` and therefore users manually
installing a Java library will not additionally install the JVM.

* For Java applications:
** After fully implemented, applications will no longer be installable
along with any JVM but rather only the system one (unless the package
maintainer decides otherwise)


== How To Test ==
* Installing a Java library should not typically install JVM (but can
if the library depends on a Java application)
* Installing a Java application MUST cause the installation of the
system-wide JVM (or a different version thereof)
* Executing a binary installed in typical locations (such as
`/usr/bin`) MUST NOT cause an error related to the JVM not being
installed.


== User Experience ==
Users with no Java application installed, but some Java libraries
installe