karakun / OpenWebStart

Run Web Start based applications after the release of Java 11
https://openwebstart.com
Other
417 stars 48 forks source link

Question on findBestRuntime method behavior (debug log difference between local JRE match parser and LocalRuntimeManager JRE chosen) #590

Open middletonk opened 3 months ago

middletonk commented 3 months ago

Hi folks, thank you and congrats on a fantastic project. I come to you hat in hand thinking this is a vendor/developer issue rather than an OpenWebStart issue, but would be grateful for a double-check.

Description

When OpenWebStart 1.10.0 is used alongside two locally-installed instances of Eclipse Adoptium JRE x64, versions 8 and 17 for sake of two projects, one which has a well-structured JNLP requiring version 17* and one which is stated by a vendor to require version 8 but whose JNLP file specifies version "1.6+", the latter project fails to load. OpenWebStart debug logs seem to indicate a switch from choosing Adoptium JRE 8 to using JRE 17 during stage 1 JNLP load. It is unclear to me if this is intended behavior by the findBestRuntime function to resort to the highest available JRE combined with poor vendor JNLP-based JRE version scoping, or unexpected behavior.

For context both Java projects work on PCs where only one local and appropriate JRE version for the given project is pre-installed, and the well-structured version 17 project / JNLP file launches even when both copies are installed. This leads me to believe that the problem is in the vendor's JNLP file rather than OpenWebStart, especially with OWS being developed for JNLP support after version 8.

To Reproduce

  1. Install OpenWebStart latest for all users + Eclipse Adoptium x64 v8 JRE latest + v17 latest.
  2. Enable OpenWebStart debug logging and disable update strategy on app launches.
  3. Test a well-structured v17 JNLP (example).
  4. Test a "6+" JNLP stated by the vendor to require v8 (see Files > launch.jnlp.txt, attached).
  5. Note that OWS debug logs will first state "[net.sourceforge.jnlp.Parser] good - your JRE - 1.8.0_412 - match requested JRE - 1.6+", but later in logs will state "[com.openwebstart.jvm.LocalRuntimeManager] Trying to find local Java runtime. Requested version: '1.6+' Requested vendor: '*' requested os: 'WIN64' active: 'true'" and finally "[com.openwebstart.jvm.JavaRuntimeSelector] Local runtime JavaRuntime{version=17.0.11, vendor=Eclipse Adoptium, operationSystem=WIN64} found and will be used". (see Files > 2024-06-10_17_13_56.444-ows-stage1.log).

Files

launch.jnlp.txt 2024-06-10_17_13_56.444-ows-stage1.log

Thank you so much!

sclassen commented 3 months ago

The behavior is as expected. The 1.6+ basically means any version greater than or equal to 1.6

There is a possibility to limit the versions OWS will chose from by using the property ows.jvm.manager.versionRange See https://openwebstart.com/docs/OWSGuide.html#_configuration for details on how to configure OWS

Here the section about version numbers from the JSR:

Appendix A Version IDs and Version Strings

This section is simply a formal encoding of common conventions for dot-notations. The formal syntax is to ensure predictable behavior of the download protocols.

This section describes the formal syntax of the version-ids and version strings used in this specification. A version-id is an exact version that is associated with a resource, such as a JAR file. A version string is a key that can match one or more version-ids.

The version-id used in this specification must conform to the following syntax:

version-id ::= string ( separator string ) *
string     ::= char ( char ) *
char       ::= any ASCII character except a space, an ampersand, a separator, or a modifier.
separator  ::= "." | "-" | "_" 

A version string is a list of version-ids separated with spaces. Each version-id can be postfixed with a '+' to indicate a greater-than-or-equal match, a "*" to indicated a prefix match, or have no postfix to indicate an exact match. The syntax of version-strings is:

version-string     ::=  version-range ( " " element) *
version-range      ::=  simple-range ( "&" simple-range) *
simple-range       ::=  version-id | version-id modifier
modifier           ::=  `+` | '*' 

A version-id can be described as a tuple of values. A version-id string is broken in parts for each separator ('.', '-', or '_'). For example, "1.3.0-rc2-w" becomes (1,3,0,rc2,w), and "1.2.2-001" becomes (1,2,2,001).

Each element in a tuple is either numeric or alphanumeric. An elements is numeric if it can be parsed as Java int, otherwise it is alphanumeric. Two numeric elements are compared numerically. Two alphanumeric elements are compared lexicographically according to the Unicode value of the individual characters. When one element is numeric and the other is alphanumeric, the alphanumeric element is greater than the numeric element. (Numeric elements have lower precedence than non-numeric elements.)

Before two version-ids are compared the two tuples are normalized. This means that the shortest tuple is padded with 0 (zero element) entries at the end. Two normalized tuples are always of the same length. For example, comparing (1, 3) and (1, 3, 1), will result in comparing (1, 3, 0) and (1, 3, 1). A.1 Ordering

The version-ids are ordered by the natural ordering of dot-notations.

A normalized version-id tuple can be written as (Head Tail), where Head is the first element in the tuple, and Tail is the rest16.

Given two version-ids, (HA TA) and (HB TB), then (HA TA) is greater than (HB TB) if and only if:

HA is greater than HB, or

HA is equal to HB, TA and TB are not empty, and TA is greater than TB recursively

In other words, A is greater than B if, when represented as normalized tuples, there exists some element of A which is greater than the corresponding element of B, and all earlier elements of A are the same as in B.

For example, "1.2.2" is greater than "1.2", and less than "1.3" (i.e., in effect, comparing "1.2.2", "1.2.0", and "1.3.0") A.2 Exact Match

Two normalized version-ids, (HA TA) and (HB TB), match exactly if and only if:

HA is equal to HB and

TA and TB are both empty, or TA matches TB exactly.

In other words, A is an exact match of B if, when represented as normalized tuples, the elements of A are the same as the elements of B.

For example, given the above definition "1.2.2-004" will be an exact match for "1.2.2.4", and "1.3" is an exact match of "1.3.0". A.3 Prefix Match

Given two version-ids, (HA TA) and (HB TB), then first (HB TB) is padded with 0 (zero element) entries at the end so it is at least the same length as the (HA TA) tuple.

(HA TA) is a prefix match of (HB TB) if and only if:

HA is equal to HB, and

    TA is empty, or

    TA is a prefix match of TB

In other words, A is a prefix match of B if, when represented as tuples, the elements of A are the same as the first elements of B. The padding ensures that B has at least as many elements as A.

For example, given the above definition "1.2.1" will be a prefix match to "1.2.1-004", but not to "1.2.0" or "1.2.10". The padding step ensures that "1.2.0.0" is a prefix of "1.2". Note that prefix matching and ordering are distinct: "1.3" is greater than "1.2", and less than "1.4", but not a prefix of either. A.4 Version Selection

If two or more available resources match the given version-string, the JNLP Client should use the one matching the earlier version-range in the version-string. If two or more available resources match a given version-range, the JNLP Client should use the one with the highest version-id.

middletonk commented 3 months ago

Hi @sclassen, this was incredibly helpful and thank you so much. Being able to quote a vendor's misinterpretation of Java specification JSR-56 itself when that vendor uses Java will be interesting. My issue is certainly closed, unrelated to OWS and I'll send my kudos yet again. Thank you!

(Regarding our own internal issue of vendor collision, we will simply deliver OWS + Adoptium JRE 8 or 17 depending on the use case, which will be suboptimal but will be all we can do given the Java 8-using vendor's choice of Java range as defined in their JNLP.)