[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Gradle and JDK 11 issues



Hi,

I have updated the java11-compatibility patch by pulling more changes
from the upstream patch in commit ac15612d41b43c39c. I basically
pulled all the upstream changes in that commit done to
subprojects/base-services/src/main/java/org/gradle/api/JavaVersion.java
and reverted the previous debian change that created the JAVA_1_11
enum value. It seems the other upstream changes are safe to be ignored
- the original upstream commit also touches a test file but gradle
build fine without those changes (which are about 303 lines, thus is
debdiff is much easier to review).

I tested the proposed patch with an unpatched zeroc-ice and the tests
ran fine, it no longer FTBFS. This should help on other gradle
projects, both from debian packages and on the user side.

Let me know what you think.

Just in case anyone prefers that way: the full original upstream
commit applies fine except for the
changes/accepted-public-api-changes.json file, but it is a very easy
fix.

Regards,
Tiago
On Sat, Nov 3, 2018 at 8:03 PM Emmanuel Bourg <ebourg@apache.org> wrote:
>
> On 03/11/2018 23:36, Markus Koschany wrote:
>
> > I have fixed it like that in mockito but it still feels like a
> > regression to me. sourceCompatibility and targetCompatibility had been
> > already set in build.gradle but now with OpenJDK 11 I have to specify it
> > in two other .gradle files as well. Maybe this is magically resolved in
> > a later Gradle version.
>
> It looks like Gradle uses the current Java version when compiling a
> project not specifying the source/target level explicitly, and it does
> so by passing the -source and -target options to javac with a 1.x value,
> where x is the version of the JDK targeted. The issue is, up to Java 10
> javac accepted the values 1.x and x, but starting with Java 11 it no
> longer accepts the 1.x values (for x >= 11).
>
> So with Java 11, we can still do:
>
>   javac -source 1.10 -target 1.10 Foo.java
>
> but not:
>
>   javac -source 1.11 -target 1.11 Foo.java
>
> This returns the error "invalid source release: 1.11". The following
> syntax has to be used instead:
>
>   javac -source 11 -target 11 Foo.java
>
> This is very likely to be fixed in a recent Gradle update, but upgrading
> the gradle package won't be possible before the Buster release. So
> either someone figures out a patch for Gradle 4.4.1, or we simply add
> two lines to the few affected packages.
>
> Emmanuel Bourg
>


-- 
Tiago Stürmer Daitx
Software Engineer
tiago.daitx@canonical.com

PGP Key: 4096R/F5B213BE (hkp://keyserver.ubuntu.com)
Fingerprint = 45D0 FE5A 8109 1E91 866E  8CA4 1931 8D5E F5B2 13BE
diff -Nru gradle-4.4.1/debian/changelog gradle-4.4.1/debian/changelog
--- gradle-4.4.1/debian/changelog	2018-10-03 10:53:14.000000000 -0300
+++ gradle-4.4.1/debian/changelog	2018-11-06 00:46:32.000000000 -0200
@@ -1,3 +1,10 @@
+gradle (4.4.1-2) UNRELEASED; urgency=medium
+
+  * Improve OpenJDK 11 support by backporting additional changes from upstream
+    (commit ac15612d41b43c39c).
+
+ -- Tiago Stürmer Daitx <tiago.daitx@ubuntu.com>  Tue, 06 Nov 2018 02:46:32 +0000
+
 gradle (4.4.1-1) unstable; urgency=medium
 
   * Team upload.
diff -Nru gradle-4.4.1/debian/patches/java11-compatibility.patch gradle-4.4.1/debian/patches/java11-compatibility.patch
--- gradle-4.4.1/debian/patches/java11-compatibility.patch	2018-10-03 10:53:14.000000000 -0300
+++ gradle-4.4.1/debian/patches/java11-compatibility.patch	2018-11-06 00:46:32.000000000 -0200
@@ -2,17 +2,3 @@
 Origin: backport, https://github.com/gradle/gradle/commit/ac15612d41b43c39c8e39d12fdd6621589b0f782
                   https://github.com/gradle/gradle/commit/028548460bd929fd034a552704798ad7f689493a
                   https://github.com/gradle/gradle/commit/3db6e256987053171178aa96a0ef46caedc8d1a4
---- a/subprojects/base-services/src/main/java/org/gradle/api/JavaVersion.java
-+++ b/subprojects/base-services/src/main/java/org/gradle/api/JavaVersion.java
-@@ -26,7 +26,7 @@
- public enum JavaVersion {
-     VERSION_1_1(false), VERSION_1_2(false), VERSION_1_3(false), VERSION_1_4(false),
-     // starting from here versions are 1_ but their official name is "Java 6", "Java 7", ...
--    VERSION_1_5(true), VERSION_1_6(true), VERSION_1_7(true), VERSION_1_8(true), VERSION_1_9(true), VERSION_1_10(true);
-+    VERSION_1_5(true), VERSION_1_6(true), VERSION_1_7(true), VERSION_1_8(true), VERSION_1_9(true), VERSION_1_10(true), VERSION_1_11(true);
-     private static JavaVersion currentJavaVersion;
-     private final boolean hasMajorVersion;
-     private final String versionName;
 --- a/subprojects/base-services/src/main/java/org/gradle/internal/classloader/ClassLoaderUtils.java
 +++ b/subprojects/base-services/src/main/java/org/gradle/internal/classloader/ClassLoaderUtils.java
 @@ -24,6 +24,9 @@
@@ -60,3 +49,191 @@
 +        }
      }
  }
+--- a/subprojects/base-services/src/main/java/org/gradle/api/JavaVersion.java
++++ b/subprojects/base-services/src/main/java/org/gradle/api/JavaVersion.java
+@@ -17,25 +17,26 @@ package org.gradle.api;
+ 
+ import com.google.common.annotations.VisibleForTesting;
+ 
+-import java.util.regex.Matcher;
+-import java.util.regex.Pattern;
++import java.util.ArrayList;
++import java.util.List;
+ 
+ /**
+  * An enumeration of Java versions.
++ * Before 9: http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
++ * 9+: http://openjdk.java.net/jeps/223
+  */
+ public enum JavaVersion {
+-    VERSION_1_1(false), VERSION_1_2(false), VERSION_1_3(false), VERSION_1_4(false),
+-    // starting from here versions are 1_ but their official name is "Java 6", "Java 7", ...
+-    VERSION_1_5(true), VERSION_1_6(true), VERSION_1_7(true), VERSION_1_8(true), VERSION_1_9(true), VERSION_1_10(true);
++    VERSION_1_1, VERSION_1_2, VERSION_1_3, VERSION_1_4,
++    VERSION_1_5, VERSION_1_6, VERSION_1_7, VERSION_1_8,
++    VERSION_1_9, VERSION_1_10, VERSION_11, VERSION_HIGHER;
++    // Since Java 9, version should be X instead of 1.X
++    // However, to keep backward compatibility, we change from 11
++    private static final int FIRST_MAJOR_VERSION_ORDINAL = 10;
+     private static JavaVersion currentJavaVersion;
+-    private final boolean hasMajorVersion;
+     private final String versionName;
+-    private final String majorVersion;
+ 
+-    JavaVersion(boolean hasMajorVersion) {
+-        this.hasMajorVersion = hasMajorVersion;
+-        this.versionName = name().substring("VERSION_".length()).replace('_', '.');
+-        this.majorVersion = name().substring(10);
++    JavaVersion() {
++        this.versionName = ordinal() >= FIRST_MAJOR_VERSION_ORDINAL ? getMajorVersion() : "1." + getMajorVersion();
+     }
+ 
+     /**
+@@ -54,22 +55,18 @@ public enum JavaVersion {
+         }
+ 
+         String name = value.toString();
+-        Matcher matcher = Pattern.compile("(\\d{1,2})(\\D.+)?").matcher(name);
+-        if (matcher.matches()) {
+-            int index = Integer.parseInt(matcher.group(1)) - 1;
+-            if (index > 0 && index < values().length && values()[index].hasMajorVersion) {
+-                return values()[index];
+-            }
+-        }
+ 
+-        matcher = Pattern.compile("1\\.(\\d{1,2})(\\D.+)?").matcher(name);
+-        if (matcher.matches()) {
+-            int versionIdx = Integer.parseInt(matcher.group(1)) - 1;
+-            if (versionIdx >= 0 && versionIdx < values().length) {
+-                return values()[versionIdx];
+-            }
++        int firstNonVersionCharIndex = findFirstNonVersionCharIndex(name);
++
++        String[] versionStrings = name.substring(0, firstNonVersionCharIndex).split("\\.");
++        List<Integer> versions = convertToNumber(name, versionStrings);
++
++        if (isLegacyVersion(versions)) {
++            assertTrue(name, versions.get(1) > 0);
++            return getVersionForMajor(versions.get(1));
++        } else {
++            return getVersionForMajor(versions.get(0));
+         }
+-        throw new IllegalArgumentException(String.format("Could not determine java version from '%s'.", name));
+     }
+ 
+     /**
+@@ -90,11 +87,7 @@ public enum JavaVersion {
+     }
+ 
+     public static JavaVersion forClassVersion(int classVersion) {
+-        int index = classVersion - 45; //class file versions: 1.1 == 45, 1.2 == 46...
+-        if (index >= 0 && index < values().length) {
+-            return values()[index];
+-        }
+-        throw new IllegalArgumentException(String.format("Could not determine java version from '%d'.", classVersion));
++        return getVersionForMajor(classVersion - 44); //class file versions: 1.1 == 45, 1.2 == 46...
+     }
+ 
+     public static JavaVersion forClass(byte[] classData) {
+@@ -116,18 +109,22 @@ public enum JavaVersion {
+         return this == VERSION_1_7;
+     }
+ 
+-    private boolean isJava8() {
++    public boolean isJava8() {
+         return this == VERSION_1_8;
+     }
+ 
+-    private boolean isJava9() {
++    public boolean isJava9() {
+         return this == VERSION_1_9;
+     }
+ 
+-    private boolean isJava10() {
++    public boolean isJava10() {
+         return this == VERSION_1_10;
+     }
+ 
++    public boolean isJava11() {
++        return this == VERSION_11;
++    }
++
+     public boolean isJava5Compatible() {
+         return this.compareTo(VERSION_1_5) >= 0;
+     }
+@@ -148,21 +145,69 @@ public enum JavaVersion {
+         return this.compareTo(VERSION_1_9) >= 0;
+     }
+ 
+-    @Incubating
+     public boolean isJava10Compatible() {
+         return this.compareTo(VERSION_1_10) >= 0;
+     }
+ 
+-    @Override
+-    public String toString() {
+-        return getName();
++    public boolean isJava11Compatible() {
++        return this.compareTo(VERSION_11) >= 0;
+     }
+ 
+-    private String getName() {
++    @Override
++    public String toString() {
+         return versionName;
+     }
+ 
+     public String getMajorVersion() {
+-        return majorVersion;
++        return String.valueOf(ordinal() + 1);
++    }
++
++    private static JavaVersion getVersionForMajor(int major) {
++        return major >= values().length ? JavaVersion.VERSION_HIGHER : values()[major - 1];
++    }
++
++    private static void assertTrue(String value, boolean condition) {
++        if (!condition) {
++            throw new IllegalArgumentException("Could not determine java version from '" + value + "'.");
++        }
++    }
++
++    private static boolean isLegacyVersion(List<Integer> versions) {
++        return 1 == versions.get(0) && versions.size() > 1;
++    }
++
++    private static List<Integer> convertToNumber(String value, String[] versionStrs) {
++        List<Integer> result = new ArrayList<Integer>();
++        for (String s : versionStrs) {
++            assertTrue(value, !isNumberStartingWithZero(s));
++            try {
++                result.add(Integer.parseInt(s));
++            } catch (NumberFormatException e) {
++                assertTrue(value, false);
++            }
++        }
++        assertTrue(value, !result.isEmpty() && result.get(0) > 0);
++        return result;
++    }
++
++    private static boolean isNumberStartingWithZero(String number) {
++        return number.length() > 1 && number.startsWith("0");
++    }
++
++    private static int findFirstNonVersionCharIndex(String s) {
++        assertTrue(s, s.length() != 0);
++
++        for (int i = 0; i < s.length(); ++i) {
++            if (!isDigitOrPeriod(s.charAt(i))) {
++                assertTrue(s, i != 0);
++                return i;
++            }
++        }
++
++        return s.length();
++    }
++
++    private static boolean isDigitOrPeriod(char c) {
++        return (c >= '0' && c <= '9') || c == '.';
+     }
+ }

Reply to: