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

Bug#931012: marked as done (unblock: gradle/4.4.1-6)



Your message dated Tue, 25 Jun 2019 17:53:00 +0000
with message-id <d7b4b450-5d2b-2268-1bfa-ea7ce3b8b764@thykier.net>
and subject line Re: Bug#931012: unblock: gradle/4.4.1-6
has caused the Debian Bug report #931012,
regarding unblock: gradle/4.4.1-6
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
931012: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=931012
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Hi,

I'd like to request gradle/4.4.1-6 to be unblocked. When fixing the gradle
package to work with OpenJDK 11 we mistakenly broke the compatibility with
OpenJDK 8 (#925225). Even if Buster ships only with OpenJDK 11 we cared to
preserve the compatibility of the Java build tools in Debian (Ant and Maven)
with OpenJDK 8 since it's still the most popular JDK (a recent survey
conducted by Jetbrains showed that 80% of the Java developers were still
using Java 8, and only 20% have adopted Java 11). We can expect the users
to be disappointed if the gradle package requires OpenJDK 11 or higher.

Ubuntu fixed the OpenJDK 8 compatibility 3 months ago and forwarded the
patch to Debian (the patch was backported from upstream). I've uploaded
the fix to unstable as gradle/4.4.1-6 and I've verified that the main
packages using Gradle are still building fine (openjfx, libspring-java,
gradle itself and a few others).

Thank you,

Emmanuel Bourg

unblock gradle/4.4.1-6
diff -Nru gradle-4.4.1/debian/changelog gradle-4.4.1/debian/changelog
--- gradle-4.4.1/debian/changelog	2019-02-26 20:02:13.000000000 +0100
+++ gradle-4.4.1/debian/changelog	2019-06-22 00:52:47.000000000 +0200
@@ -1,3 +1,17 @@
+gradle (4.4.1-6) unstable; urgency=medium
+
+  [ Tiago Stürmer Daitx ]
+  * Fix OpenJDK 8 compatibility: (Closes: #925225)
+    - debian/patches/java8-compatibility.patch: cast ByteBuffer to Buffer
+      in org.gradle.internal.hash.Hashing to prevent NoSuchMethodError
+      exception.
+    - debian/patches/java11-compatibility.patch: copy upstream commit for
+      "Use Lookup to invoke defineClass on Java 9+ (#4976)" instead using
+      the previous partial backport to enable both OpenJDK 8 and 11 support.
+  * debian/control: revert gradle Depends back to java 8
+
+ -- Emmanuel Bourg <ebourg@apache.org>  Sat, 22 Jun 2019 00:52:47 +0200
+
 gradle (4.4.1-5) unstable; urgency=medium
 
   * Team upload.
diff -Nru gradle-4.4.1/debian/control gradle-4.4.1/debian/control
--- gradle-4.4.1/debian/control	2019-02-26 20:02:13.000000000 +0100
+++ gradle-4.4.1/debian/control	2019-06-22 00:49:27.000000000 +0200
@@ -76,7 +76,7 @@
 
 Package: gradle
 Architecture: all
-Depends: default-jre-headless (>= 2:1.9) | java9-runtime-headless,
+Depends: default-jre-headless (>= 2:1.8) | java8-runtime-headless,
          libgradle-core-java (>= ${binary:Version}),
          libgradle-plugins-java (>= ${binary:Version}),
          ${misc:Depends}
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	2019-02-26 20:02:13.000000000 +0100
+++ gradle-4.4.1/debian/patches/java11-compatibility.patch	2019-06-22 00:50:07.000000000 +0200
@@ -4,51 +4,238 @@
                   https://github.com/gradle/gradle/commit/3db6e256987053171178aa96a0ef46caedc8d1a4
 --- 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 @@
+@@ -15,51 +15,41 @@
+  */
+ package org.gradle.internal.classloader;
+ 
++import org.gradle.api.JavaVersion;
+ import org.gradle.internal.Cast;
+ import org.gradle.internal.UncheckedException;
+ import org.gradle.internal.concurrent.CompositeStoppable;
+ import org.gradle.internal.reflect.JavaMethod;
+-import org.gradle.internal.reflect.JavaReflectionUtil;
+-import sun.misc.Unsafe;
  
  import javax.annotation.Nullable;
  import java.io.IOException;
+-import java.lang.reflect.Field;
+-import java.net.MalformedURLException;
 +import java.lang.invoke.MethodHandle;
 +import java.lang.invoke.MethodHandles;
 +import java.lang.invoke.MethodType;
- import java.lang.reflect.Field;
- import java.net.MalformedURLException;
  import java.net.URL;
-@@ -31,16 +34,15 @@
- 
- public abstract class ClassLoaderUtils {
+ import java.net.URLConnection;
  
+-public abstract class ClassLoaderUtils {
+-
 -    private static final Unsafe UNSAFE;
-+    private static MethodHandle defineClassMethodHandle;
- 
-     static {
-         try {
+-
+-    static {
+-        try {
 -            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
 -            theUnsafe.setAccessible(true);
 -            UNSAFE = (Unsafe) theUnsafe.get(null);
 -        } catch (NoSuchFieldException e) {
 -            throw new RuntimeException(e);
 -        } catch (IllegalAccessException e) {
-+            MethodHandles.Lookup baseLookup = MethodHandles.lookup();
-+            MethodType defineClassMethodType = MethodType.methodType(Class.class, new Class[]{String.class, byte[].class, int.class, int.class});
-+            MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(ClassLoader.class, baseLookup);
-+            defineClassMethodHandle = lookup.findVirtual(ClassLoader.class, "defineClass", defineClassMethodType);
-+        } catch (Throwable e) {
-             throw new RuntimeException(e);
+-            throw new RuntimeException(e);
+-        }
+-    }
++import static org.gradle.internal.reflect.JavaReflectionUtil.method;
++import static org.gradle.internal.reflect.JavaReflectionUtil.staticMethod;
+ 
++public abstract class ClassLoaderUtils {
++    private static final ClassDefiner CLASS_DEFINER;
+     private static final JavaMethod<ClassLoader, Package[]> GET_PACKAGES_METHOD;
+     private static final JavaMethod<ClassLoader, Package> GET_PACKAGE_METHOD;
+ 
+     static {
++        CLASS_DEFINER = JavaVersion.current().isJava9Compatible() ? new LookupClassDefiner() : new ReflectionClassDefiner();
+         GET_PACKAGES_METHOD = getMethodWithFallback(Package[].class, new Class[0], "getDefinedPackages", "getPackages");
+-        GET_PACKAGE_METHOD = getMethodWithFallback(Package.class, new Class[] {String.class}, "getDefinedPackage", "getPackage");
++        GET_PACKAGE_METHOD = getMethodWithFallback(Package.class, new Class[]{String.class}, "getDefinedPackage", "getPackage");
+     }
+ 
+     private static <T> JavaMethod<ClassLoader, T> getMethodWithFallback(Class<T> clazz, Class<?>[] params, String firstChoice, String fallback) {
+         JavaMethod<ClassLoader, T> method;
+         try {
+-            method = JavaReflectionUtil.method(ClassLoader.class, clazz, firstChoice, params);
++            method = method(ClassLoader.class, clazz, firstChoice, params);
+         } catch (Throwable e) {
+             // We must not be on Java 9 where the getDefinedPackages() method exists. Fall back to getPackages()
+-            method = JavaReflectionUtil.method(ClassLoader.class, clazz, fallback, params);
++            method = method(ClassLoader.class, clazz, fallback, params);
          }
+         return method;
      }
-@@ -101,6 +103,10 @@
+@@ -85,8 +75,6 @@ public static void disableUrlConnectionCaching() {
+             URL url = new URL("jar:file://valid_jar_url_syntax.jar!/");
+             URLConnection urlConnection = url.openConnection();
+             urlConnection.setDefaultUseCaches(false);
+-        } catch (MalformedURLException e) {
+-            throw UncheckedException.throwAsUncheckedException(e);
+         } catch (IOException e) {
+             throw UncheckedException.throwAsUncheckedException(e);
+         }
+@@ -101,6 +89,63 @@ public static void disableUrlConnectionCaching() {
      }
  
      public static <T> Class<T> define(ClassLoader targetClassLoader, String className, byte[] clazzBytes) {
 -        return Cast.uncheckedCast(UNSAFE.defineClass(className, clazzBytes, 0, clazzBytes.length, targetClassLoader, null));
-+        try {
-+            return (Class) defineClassMethodHandle.bindTo(targetClassLoader).invokeWithArguments(className, clazzBytes, 0, clazzBytes.length);
-+        } catch (Throwable e) {
-+            throw new RuntimeException(e);
++        return CLASS_DEFINER.defineClass(targetClassLoader, className, clazzBytes);
++    }
++
++    private interface ClassDefiner {
++        <T> Class<T> defineClass(ClassLoader classLoader, String className, byte[] classBytes);
++    }
++
++    private static class ReflectionClassDefiner implements ClassDefiner {
++        private final JavaMethod<ClassLoader, Class> defineClassMethod;
++
++        private ReflectionClassDefiner() {
++            defineClassMethod = method(ClassLoader.class, Class.class, "defineClass", String.class, byte[].class, int.class, int.class);
++        }
++
++        @Override
++        public <T> Class<T> defineClass(ClassLoader classLoader, String className, byte[] classBytes) {
++            return Cast.uncheckedCast(defineClassMethod.invoke(classLoader, className, classBytes, 0, classBytes.length));
++        }
++    }
++
++    private static class LookupClassDefiner implements ClassDefiner {
++        private final Class methodHandlesLookupClass;
++        private final JavaMethod methodHandlesLookup;
++        private final JavaMethod methodHandlesPrivateLookupIn;
++        private final JavaMethod lookupFindVirtual;
++        private final MethodType defineClassMethodType;
++
++        private LookupClassDefiner() {
++            try {
++                methodHandlesLookupClass = Class.forName("java.lang.invoke.MethodHandles$Lookup");
++            } catch (ClassNotFoundException e) {
++                throw new RuntimeException(e);
++            }
++            methodHandlesLookup = staticMethod(MethodHandles.class, methodHandlesLookupClass, "lookup");
++            methodHandlesPrivateLookupIn = staticMethod(MethodHandles.class, methodHandlesLookupClass, "privateLookupIn", Class.class, methodHandlesLookupClass);
++            lookupFindVirtual = method(methodHandlesLookupClass, MethodHandle.class, "findVirtual", Class.class, String.class, MethodType.class);
++            defineClassMethodType = MethodType.methodType(Class.class, new Class[]{String.class, byte[].class, int.class, int.class});
++        }
++
++        /*
++            This method is equivalent to the following code but use reflection to compile on Java 7:
++
++            MethodHandles.Lookup baseLookup = MethodHandles.lookup();
++            MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(ClassLoader.class, baseLookup);
++            MethodHandle defineClassMethodHandle = lookup.findVirtual(ClassLoader.class, "defineClass", defineClassMethodType);
++            handle.bindTo(classLoader).invokeWithArguments(className, classBytes, 0, classBytes.length));
++         */
++        @Override
++        public <T> Class<T> defineClass(ClassLoader classLoader, String className, byte[] classBytes) {
++            Object baseLookup = methodHandlesLookup.invoke(null);
++            Object lookup = methodHandlesPrivateLookupIn.invoke(null, ClassLoader.class, baseLookup);
++            MethodHandle defineClassMethodHandle = (MethodHandle) lookupFindVirtual.invoke(lookup, ClassLoader.class, "defineClass", defineClassMethodType);
++            try {
++                return Cast.uncheckedCast(defineClassMethodHandle.bindTo(classLoader).invokeWithArguments(className, classBytes, 0, classBytes.length));
++            } catch (Throwable throwable) {
++                throw new RuntimeException(throwable);
++            }
 +        }
      }
  }
+diff --git a/subprojects/core/src/main/java/org/gradle/process/internal/worker/child/WorkerProcessClassPathProvider.java b/subprojects/core/src/main/java/org/gradle/process/internal/worker/child/WorkerProcessClassPathProvider.java
+index 9a7fd911c78f..c1324a04fef5 100644
+--- a/subprojects/core/src/main/java/org/gradle/process/internal/worker/child/WorkerProcessClassPathProvider.java
++++ b/subprojects/core/src/main/java/org/gradle/process/internal/worker/child/WorkerProcessClassPathProvider.java
+@@ -18,6 +18,7 @@
+ 
+ import org.gradle.api.Action;
+ import org.gradle.api.GradleException;
++import org.gradle.api.JavaVersion;
+ import org.gradle.api.internal.ClassPathProvider;
+ import org.gradle.api.specs.Spec;
+ import org.gradle.cache.CacheRepository;
+@@ -57,7 +58,9 @@
+ import java.io.InputStream;
+ import java.net.URL;
+ import java.util.Arrays;
++import java.util.HashSet;
+ import java.util.List;
++import java.util.Set;
+ import java.util.zip.ZipEntry;
+ import java.util.zip.ZipOutputStream;
+ 
+@@ -116,32 +119,9 @@ public void execute(PersistentCache cache) {
+             try {
+                 File jarFile = jarFile(cache);
+                 LOGGER.debug("Generating worker process classes to {}.", jarFile);
+-
+-                // TODO - calculate this list of classes dynamically
+-                List<Class<?>> classes = Arrays.asList(
+-                        GradleWorkerMain.class,
+-                        BootstrapSecurityManager.class,
+-                        EncodedStream.EncodedInput.class,
+-                        ClassLoaderUtils.class,
+-                        FilteringClassLoader.class,
+-                        FilteringClassLoader.Spec.class,
+-                        ClassLoaderHierarchy.class,
+-                        ClassLoaderVisitor.class,
+-                        ClassLoaderSpec.class,
+-                        SystemClassLoaderSpec.class,
+-                        JavaReflectionUtil.class,
+-                        JavaMethod.class,
+-                        GradleException.class,
+-                        NoSuchPropertyException.class,
+-                        NoSuchMethodException.class,
+-                        UncheckedException.class,
+-                        PropertyAccessor.class,
+-                        PropertyMutator.class,
+-                        Factory.class,
+-                        Spec.class);
+                 ZipOutputStream outputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(jarFile)));
+                 try {
+-                    for (Class<?> classToMap : classes) {
++                    for (Class<?> classToMap : getClassesForWorkerJar()) {
+                         remapClass(classToMap, outputStream);
+                     }
+                 } finally {
+@@ -152,6 +132,37 @@ public void execute(PersistentCache cache) {
+             }
+         }
+ 
++        private Set<Class<?>> getClassesForWorkerJar() {
++            // TODO - calculate this list of classes dynamically
++            List<Class<?>> classes = Arrays.asList(
++                GradleWorkerMain.class,
++                BootstrapSecurityManager.class,
++                EncodedStream.EncodedInput.class,
++                ClassLoaderUtils.class,
++                FilteringClassLoader.class,
++                ClassLoaderHierarchy.class,
++                ClassLoaderVisitor.class,
++                ClassLoaderSpec.class,
++                SystemClassLoaderSpec.class,
++                JavaReflectionUtil.class,
++                JavaMethod.class,
++                GradleException.class,
++                NoSuchPropertyException.class,
++                NoSuchMethodException.class,
++                UncheckedException.class,
++                PropertyAccessor.class,
++                PropertyMutator.class,
++                Factory.class,
++                Spec.class,
++                JavaVersion.class);
++            Set<Class<?>> result = new HashSet<Class<?>>(classes);
++            for (Class<?> klass : classes) {
++                result.addAll(Arrays.asList(klass.getDeclaredClasses()));
++            }
++
++            return result;
++        }
++
+         private void remapClass(Class<?> classToMap, ZipOutputStream jar) throws IOException {
+             String internalName = Type.getInternalName(classToMap);
+             String resourceName = internalName.concat(".class");
 --- 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 @@
diff -Nru gradle-4.4.1/debian/patches/java8-compatibility.patch gradle-4.4.1/debian/patches/java8-compatibility.patch
--- gradle-4.4.1/debian/patches/java8-compatibility.patch	2019-02-26 20:02:13.000000000 +0100
+++ gradle-4.4.1/debian/patches/java8-compatibility.patch	2019-06-22 00:48:57.000000000 +0200
@@ -74,3 +74,14 @@
          return charbuffer;
      }
  
+--- a/subprojects/base-services/src/main/java/org/gradle/internal/hash/Hashing.java
++++ b/subprojects/base-services/src/main/java/org/gradle/internal/hash/Hashing.java
+@@ -158,7 +158,7 @@ public class Hashing {
+         private void update(int length) {
+             checkNotDone();
+             digest.update(buffer.array(), 0, length);
+-            buffer.clear();
++            ((java.nio.Buffer) buffer).clear();
+         }
+ 
+         @Override

--- End Message ---
--- Begin Message ---
Emmanuel Bourg:
> Package: release.debian.org
> Severity: normal
> User: release.debian.org@packages.debian.org
> Usertags: unblock
> 
> Hi,
> 
> I'd like to request gradle/4.4.1-6 to be unblocked. When fixing the gradle
> package to work with OpenJDK 11 we mistakenly broke the compatibility with
> OpenJDK 8 (#925225). Even if Buster ships only with OpenJDK 11 we cared to
> preserve the compatibility of the Java build tools in Debian (Ant and Maven)
> with OpenJDK 8 since it's still the most popular JDK (a recent survey
> conducted by Jetbrains showed that 80% of the Java developers were still
> using Java 8, and only 20% have adopted Java 11). We can expect the users
> to be disappointed if the gradle package requires OpenJDK 11 or higher.
> 
> Ubuntu fixed the OpenJDK 8 compatibility 3 months ago and forwarded the
> patch to Debian (the patch was backported from upstream). I've uploaded
> the fix to unstable as gradle/4.4.1-6 and I've verified that the main
> packages using Gradle are still building fine (openjfx, libspring-java,
> gradle itself and a few others).
> 
> Thank you,
> 
> Emmanuel Bourg
> 
> unblock gradle/4.4.1-6
> 

Unblocked, thanks.
~Niels

--- End Message ---

Reply to: