Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8296329

jar validator doesn't account for minor class file version

    XMLWordPrintable

Details

    • jar
    • b25

    Backports

      Description

        There's currently a check in the jar validator that checks if a class file in a versioned directory is of a greater version than the class file of the same class in the 'default' section of the jar. This happens in `FingerPrint::isCompatibleVersion`.

        This rejects for instance a case where a Java 19 class file has a versioned class file for java 17:

            entry: META-INF/versions/17/Lib.class, has a class version incompatible with an earlier version

        The 'version' that is used by the check comes from ASM, and is a mix of the major and minor version fused into a single int. However, this check doesn't seem to account for preview versions, which change the minor in such a way that the 'version' will appear negative, and will allow the above check to pass, seemingly erroneously.

        I think this check was only ever designed to compare major versions, so we can fix this issue by extracting just the major version bits from the 'version' value given by ASM.

        Here is a full reproducer that demonstrates the issue. I have 2 versions of the same class:

        src/17/Lib.java:

            public class Lib {
                public static void method() {
                    System.out.println("java 17");
                }
            }

        src/19/Lib.java:

            public class Lib {
                public static void method() {
                    System.out.println("java 19");
                }
            }

        Compiled into a jar as follows (resulting in an error):

            $ javac --release 19 -d classes/19 ./src/19/Lib.java
            $ javac --release 17 -d classes/17 ./src/17/Lib.java
            $ jar --create --file lib.jar -C classes/19 Lib.class --release 17 -C classes/17 Lib.class
            entry: META-INF/versions/17/Lib.class, has a class version incompatible with an earlier version
            invalid multi-release jar file lib.jar deleted

        However, if I modify src/19/Lib.java to reference a preview API:

            public class Lib {
                public static void method() {
                    System.out.println("java 19");
                    java.lang.foreign.Linker.nativeLinker();
                }
            }

        And then recompile the jar:

            $ javac --enable-preview --release 19 -d classes/19 .\src\19\Lib.java
            Note: .\src\19\Lib.java uses preview features of Java SE 19.
            Note: Recompile with -Xlint:preview for details.
            $ jar --create --file lib.jar -C classes/19 Lib.class --release 17 -C classes/17 Lib.class

        I don't receive any error from the jar validator (due to the reasons outlined above). I believe that is a bug.

        Attachments

          Issue Links

            Activity

              People

                jvernee Jorn Vernee
                jvernee Jorn Vernee
                Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: