• Packaging applications with JVM version restrictions

    From Rob Browning@21:1/5 to All on Mon Apr 17 21:50:01 2023
    Is there Is there a policy or preferred way to handle a package that
    needs a particular version or versions of java? e.g. say it doesn't
    work with < 9.

    I could imagine it might not want to just rely on /usr/bin/java because
    you might not want it to break if the system has 8 and 11 installed, and
    then the local admin changes the default to 8 via update-alternatives.

    To avoid that, I imagine the application's /usr/bin/something could
    examine $(update-alternatives --list java) to find a suitable version,
    but is that reasonable, or is there a preferable approach?

    Thanks
    --
    Rob Browning
    rlb @defaultvalue.org and @debian.org
    GPG as of 2011-07-10 E6A9 DA3C C9FD 1FF8 C676 D2C4 C0F0 39E9 ED1B 597A
    GPG as of 2002-11-03 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thorsten Glaser@21:1/5 to Rob Browning on Mon Apr 17 22:00:01 2023
    On Mon, 17 Apr 2023, Rob Browning wrote:

    Is there Is there a policy or preferred way to handle a package that
    needs a particular version or versions of java? e.g. say it doesn't
    work with < 9.

    From a Depends standpoint, java9-runtime-headless or java9-runtime. But…

    I could imagine it might not want to just rely on /usr/bin/java because
    you might not want it to break if the system has 8 and 11 installed, and
    then the local admin changes the default to 8 via update-alternatives.

    … this is, indeed, possible: the Depends simply means it’s present,
    not the default. (And that is a good thing.)

    To avoid that, I imagine the application's /usr/bin/something could
    examine $(update-alternatives --list java) to find a suitable version,
    but is that reasonable, or is there a preferable approach?

    I’m a bit wary of auto-selecting something. I’d instead check whether ${JAVA:-java} has the right version and complain when not. Possibly
    check whether $JAVA_HOME is set (which it isn’t in a regular Debian
    one-JRE installation) and use that if suitable instead of complaining.
    (Where complaining means echo "E: some msg" >&2; exit 1)

    bye,
    //mirabilos
    --
    Infrastrukturexperte • tarent solutions GmbH
    Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
    Telephon +49 228 54881-393 • Fax: +49 228 54881-235
    HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
    Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

    **************************************************** /⁀\ The UTF-8 Ribbon
    ╲ ╱ Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:  ╳  HTML eMail! Also, https://www.tarent.de/newsletter
    ╱ ╲ header encryption!
    ****************************************************

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?utf-8?Q?Lo=C3=AFc_Rouchon?=@21:1/5 to Thorsten Glaser on Tue Apr 18 15:30:01 2023
    Hi,

    I’m a bit wary of auto-selecting something. I’d instead check whether ${JAVA:-java} has the right version and complain when not. Possibly
    check whether $JAVA_HOME is set (which it isn’t in a regular Debian
    one-JRE installation) and use that if suitable instead of complaining.
    (Where complaining means echo "E: some msg" >&2; exit 1)

    I find this approach of failing in case the default java alternative is
    not matching the expected version to run your application far from ideal.

    If you have two java applications, one requiring JDK 11 but not yet 17 compatible and one requiring JDK 17, you can not easily write a script
    using both programs.

    In order for this to work, it will require both:
    - Engineering effort on the applications side to read specific environment variables
    - User manual environment setup of the JVM for those application in order to work

    The biggest issue is the user manual effort here as it severly affect the user experience for Java applications. This might be fine if you only have one major version every 10 years (python 2 to 3). But the JVM has a six months delivery cycle.

    This problem is so annoying I even wrote an article about it https://loicrouchon.com/posts/distributing-java-cli-app/
    where I do not have a satisfactory solution.

    One possibility could be to provide versioned stable paths or links.
    For example:
    - /usr/lib/jvm/11/bin/java -> targets the lowest installed JVM which version is greater or equals to 11
    - /usr/lib/jvm/17/bin/java -> targets the lowest installed JVM which version is greater or equals to 11
    - /usr/lib/jvm/latest/bin/java -> targets the latest installed JVM

    This is not perfect as it's not taking the vendor into account but maybe
    could default to openjdk. Also, every time a new JDK is installed/removed,
    a script to re-generate all of those links would be required.


    I also took a look at Fedora and installed JDK 17 and the latest JDK (20)
    and see the following things:
    # ls -l /usr/lib/jvm
    java-17-openjdk-17.0.6.0.10-1.fc37.aarch64 java-20-openjdk-20.0.0.0.36-1.rolling.fc37.aarch64
    jre -> /etc/alternatives/jre
    jre-17 -> /etc/alternatives/jre_17
    jre-17-openjdk -> /etc/alternatives/jre_17_openjdk jre-17-openjdk-17.0.6.0.10-1.fc37.aarch64 -> java-17-openjdk-17.0.6.0.10-1.fc37.aarch64
    jre-20 -> /etc/alternatives/jre_20
    jre-20-openjdk -> /etc/alternatives/jre_20_openjdk jre-20-openjdk-20.0.0.0.36-1.rolling.fc37.aarch64 -> java-20-openjdk-20.0.0.0.36-1.rolling.fc37.aarch64
    jre-openjdk -> /etc/alternatives/jre_openjdk

    It seems they are generating additional entries for update-alternatives
    that could be used for querying.


    I'm not here to push a particular solution, what I mentioned above are just ideas. But I think this is a serious issue because of the high frequency release
    of the JDK. I would love this problem to find a solution and I'd be happy
    to help in discussing ideas and designing a solution. However, I'm no
    Debian expert and I am very unaware of Debian constraints or best practices
    to address such a problem.

    Regards,

    PS: first time I'm posting here, so let me know if I missed some guidelines

    ------- Original Message -------
    On Monday, April 17th, 2023 at 21:53, Thorsten Glaser <t.glaser@tarent.de> wrote:




    On Mon, 17 Apr 2023, Rob Browning wrote:

    Is there Is there a policy or preferred way to handle a package that
    needs a particular version or versions of java? e.g. say it doesn't
    work with < 9.


    From a Depends standpoint, java9-runtime-headless or java9-runtime. But…

    I could imagine it might not want to just rely on /usr/bin/java because
    you might not want it to break if the system has 8 and 11 installed, and then the local admin changes the default to 8 via update-alternatives.


    … this is, indeed, possible: the Depends simply means it’s present,
    not the default. (And that is a good thing.)

    To avoid that, I imagine the application's /usr/bin/something could
    examine $(update-alternatives --list java) to find a suitable version,
    but is that reasonable, or is there a preferable approach?


    I’m a bit wary of auto-selecting something. I’d instead check whether ${JAVA:-java} has the right version and complain when not. Possibly
    check whether $JAVA_HOME is set (which it isn’t in a regular Debian
    one-JRE installation) and use that if suitable instead of complaining.
    (Where complaining means echo "E: some msg" >&2; exit 1)


    bye,
    //mirabilos
    --
    Infrastrukturexperte • tarent solutions GmbH
    Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
    Telephon +49 228 54881-393 • Fax: +49 228 54881-235
    HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
    Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

    ****************************************************
    /⁀\ The UTF-8 Ribbon
    ╲ ╱ Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
    ╳ HTML eMail! Also, https://www.tarent.de/newsletter
    ╱ ╲ header encryption! ****************************************************

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thorsten Glaser@21:1/5 to All on Wed Apr 19 09:20:01 2023
    On Tue, 18 Apr 2023, Loïc Rouchon wrote:

    targets the lowest installed JVM which version is greater or equals to

    I’m very much not fond of this approach, because who’s to say you
    want the lowest?

    I’d rather have the local admin or invoking user specify the version
    to use if the default version is not it, and if you have to run two incompatible ones from a script then you have to set an environment
    variablke at some point inside that script and so be it.

    Besides, what’s compatible? Some things may run with an older/newer
    JRE but others won’t.

    And how are you going to retrofit anything new to the old JDKs/JREs now?
    We cannot simply add new things now to old releases.

    bye,
    //mirabilos
    --
    Infrastrukturexperte • tarent solutions GmbH
    Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
    Telephon +49 228 54881-393 • Fax: +49 228 54881-235
    HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
    Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

    **************************************************** /⁀\ The UTF-8 Ribbon
    ╲ ╱ Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:  ╳  HTML eMail! Also, https://www.tarent.de/newsletter
    ╱ ╲ header encryption!
    ****************************************************

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?utf-8?Q?Lo=C3=AFc_Rouchon?=@21:1/5 to Thorsten Glaser on Wed Apr 19 12:10:01 2023
    ------- Original Message -------
    On Wednesday, April 19th, 2023 at 09:18, Thorsten Glaser <t.glaser@tarent.de> wrote:


    Besides, what’s compatible? Some things may run with an older/newer
    JRE but others won’t.

    If I follow this line of thinking, it means:

    * You should not depend on java11-runtime-headless virtual package:

    JDK17 could be installed before hand providing java11-runtime-headless
    but maybe your application is not compatible with 17

    * You should not rely on the java in the $PATH

    Because who knows what the java in the $PATH is pointing to.
    Yes it can be changed by the user, but then the system is very fragile
    as you might need to constantly change between two alternatives when alternatively invoking an application requiring JDK X and another
    requiring JDK Y.

    It's a super fragile approach severely affecting user experience
    compared to languages not requiring a runtime engine.


    I agree this is not an easy problem to solve.


    From the point of view of a Java application developer, I can provide a
    list of JDK versions my application can be run with.

    In this case, my start script could look like this:

    # check if JAVA_HOME is a match
    # check if default java is a match
    # else try every other supported version
    for version in 17 16 15 14 13 12 11; do
    if [ JRE with exact java $version exists ]; then
    JAVA_HOME=...
    fi
    done

    Debian would need to provide a way to perform the "JRE with exact java $version exists"
    check. This could be done by providing stable symlinks, or alternatives like /etc/alternatives/jre_<VERSION>

    Would that be a better direction of a solution for you?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gregor herrmann@21:1/5 to All on Thu Apr 20 20:00:01 2023
    On Wed, 19 Apr 2023 09:48:54 +0000, Loc Rouchon wrote:

    Debian would need to provide a way to perform the "JRE with exact java $version exists"
    check. This could be done by providing stable symlinks, or alternatives like /etc/alternatives/jre_<VERSION>

    (I haven't read the complete thread in detail, so this might be not
    completely appropriate):

    There's also the java-wrappers package which helps to find java
    runtimes from shell wrapper scripts.


    Cheers,
    gregor

    --
    .''`. https://info.comodo.priv.at -- Debian Developer https://www.debian.org
    : :' : OpenPGP fingerprint D1E1 316E 93A7 60A8 104D 85FA BB3A 6801 8649 AA06
    `. `' Member VIBE!AT & SPI Inc. -- Supporter Free Software Foundation Europe
    `-

    -----BEGIN PGP SIGNATURE-----

    iQKTBAEBCgB9FiEE0eExbpOnYKgQTYX6uzpoAYZJqgYFAmRBdopfFIAAAAAALgAo aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEQx RTEzMTZFOTNBNzYwQTgxMDREODVGQUJCM0E2ODAxODY0OUFBMDYACgkQuzpoAYZJ qgYkfQ/9FqbZPSMY29ipRGCvsT7nDf4cORpBAPrK/6R9QP8snc2PnEWELT/X0yB5 Q60TDaEk5p0b3J1NQuadgRBA7YYe3nAeQAcnmZfln6hQoZkyaNDI3qGDIvk06Dha TVCOPRQpeB4G/T7OcXpdbFaXu3E3BMZlyIqGDrolUXrT8BtASgQAqzi8hQAPPx9t p8N1LEwLzGjWVF5eDarjKHaoOBXXKDzUVuFSWda6mlimqzLNy2y3LrDUnak4j7nJ 75dDVJVqhNNHQhLFE22CvPQKPhtkkOailoyZYTJNm10mTUQMvEjhz7OgMC0JOcHh On+PvS1RoL7Pj62LeGgyBarde0LURVHgvTbS+6vfFVUy1yOR/AXnKwwjKXHQ4694 9FxwMevCvRiLC6njXq4pJNzn81fHL2w/DFPiwlWQN6JFanORWNOuoTCo7/AStFNn Z84uXvBMisiNIGPte1fQQE3PkL+kaOYuuddiznAy1ve1gZpVa6UHi92ElKZFI/gU
    lxUJrMIQ
  • From =?utf-8?Q?Lo=C3=AFc_Rouchon?=@21:1/5 to gregor herrmann on Sat May 6 15:40:02 2023
    Hi Gregor,

    From what I've seen of the java-wrappers package, it seems to solve the problem
    in a single direction: specifying the minimum JVM's version, but not the maximum.

    That was one of the remark of Thorsten to me.

    The more I think about it, the more I think it is not a problem which should
    be solved by Debian. Nor by Fedora, Nor by Homebrew, ...
    I'd like to have a solution that is common for all systems/platform to ease the packaging of java applications.

    So I started a prototype of a program that would choose a JVM based on criteria like the minimum/maximum java specification version, the vendor of the JVM, the capabilities of the JVM (java, javac, javap, native-image, ...)

    It would consist of two steps:
    - JVMs discovery
    - JVM selection

    I would typically expect the paths/environment variables to use for the discovery
    to be OS/package managers specific.
    For Debian, it could be /usr/bin/java, /usr/lib/jvm, $JAVA_HOME.
    Rules could be specified at system level to say for example: use a JVM in the [11, 17] range.
    Those rules could be overridden on a per program basis.

    Here is the prototype: https://github.com/loicrouchon/jvm-finder/tree/main#readme
    It's written in Go so that the JVM selection is quite fast. I'm more of a
    Java developer, so probably not great Go, but I'll improve it over time.

    I do not expect any of you to help me with the implementation, but feel free ;) However, I would love you to contribute to the requirements of such a program. Because I have the point of view of someone wanting to distribute a Java program.
    But I lack the point of view of distributions/packages maintainers

    PS: I'll be at Devoxx UK next week and will try to discuss of this topic
    with other Java developers.

    Regards,

    ------- Original Message -------
    On Thursday, April 20th, 2023 at 19:29, gregor herrmann <gregoa@debian.org> wrote:




    On Wed, 19 Apr 2023 09:48:54 +0000, Loïc Rouchon wrote:

    Debian would need to provide a way to perform the "JRE with exact java $version exists"
    check. This could be done by providing stable symlinks, or alternatives like
    /etc/alternatives/jre_<VERSION>


    (I haven't read the complete thread in detail, so this might be not completely appropriate):

    There's also the java-wrappers package which helps to find java
    runtimes from shell wrapper scripts.


    Cheers,
    gregor

    --
    .''`. https://info.comodo.priv.at -- Debian Developer https://www.debian.org : :' : OpenPGP fingerprint D1E1 316E 93A7 60A8 104D 85FA BB3A 6801 8649 AA06` . `' Member VIBE!AT & SPI Inc. -- Supporter Free Software Foundation Europe` -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)