[guava-libraries] 04/05: Backported a fix addressing a compatibility issue with Java 8 (Closes: #751544)

Emmanuel Bourg ebourg-guest at moszumanska.debian.org
Fri May 22 10:29:26 UTC 2015


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to branch master
in repository guava-libraries.

commit 6dd544c8072cf72290ff577eae3c8d58019628a0
Author: Emmanuel Bourg <ebourg at apache.org>
Date:   Fri May 22 10:30:41 2015 +0200

    Backported a fix addressing a compatibility issue with Java 8 (Closes: #751544)
---
 debian/changelog                            |   2 +
 debian/patches/07-java8-compatibility.patch | 146 ++++++++++++++++++++++++++++
 debian/patches/series                       |   1 +
 3 files changed, 149 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 9a6f118..ffc8273 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,8 @@ guava-libraries (18.0-1) UNRELEASED; urgency=medium
     - Added a patch reintroducing the deprecated methods removed
       from the Files, ByteStreams and CharStreams classes still used
       by other packages (gradle andclosure-compiler)
+  * Backported a fix addressing a compatibility issue with Java 8
+    (Closes: #751544)
   * Modified the short description of libguava-java (Closes: #729355)
   * Standards-Version updated to 3.9.6 (no changes)
 
diff --git a/debian/patches/07-java8-compatibility.patch b/debian/patches/07-java8-compatibility.patch
new file mode 100644
index 0000000..f72aeee
--- /dev/null
+++ b/debian/patches/07-java8-compatibility.patch
@@ -0,0 +1,146 @@
+Description: Fixes a compatibility problem introduced by Java 8
+Origin: backport, https://github.com/google/guava/commit/f4aa25e
+Bug: https://github.com/google/guava/issues/1738
+Bug-Debian: https://bugs.debian.org/751544
+--- a/guava/src/com/google/common/reflect/Types.java
++++ b/guava/src/com/google/common/reflect/Types.java
+@@ -26,6 +26,7 @@
+ import com.google.common.base.Objects;
+ import com.google.common.base.Predicates;
+ import com.google.common.collect.ImmutableList;
++import com.google.common.collect.ImmutableMap;
+ import com.google.common.collect.Iterables;
+ 
+ import java.io.Serializable;
+@@ -33,9 +34,11 @@
+ import java.lang.reflect.Array;
+ import java.lang.reflect.GenericArrayType;
+ import java.lang.reflect.GenericDeclaration;
++import java.lang.reflect.InvocationHandler;
+ import java.lang.reflect.InvocationTargetException;
+ import java.lang.reflect.Method;
+ import java.lang.reflect.ParameterizedType;
++import java.lang.reflect.Proxy;
+ import java.lang.reflect.Type;
+ import java.lang.reflect.TypeVariable;
+ import java.lang.reflect.WildcardType;
+@@ -149,7 +152,7 @@
+    */
+   static <D extends GenericDeclaration> TypeVariable<D> newArtificialTypeVariable(
+       D declaration, String name, Type... bounds) {
+-    return new TypeVariableImpl<D>(
++    return newTypeVariableImpl(
+         declaration,
+         name,
+         (bounds.length == 0)
+@@ -317,8 +320,70 @@
+     private static final long serialVersionUID = 0;
+   }
+ 
+-  private static final class TypeVariableImpl<D extends GenericDeclaration>
+-      implements TypeVariable<D> {
++  private static <D extends GenericDeclaration> TypeVariable<D> newTypeVariableImpl(
++      D genericDeclaration, String name, Type[] bounds) {
++    TypeVariableImpl<D> typeVariableImpl =
++        new TypeVariableImpl<D>(genericDeclaration, name, bounds);
++    @SuppressWarnings("unchecked")
++    TypeVariable<D> typeVariable = Reflection.newProxy(
++        TypeVariable.class, new TypeVariableInvocationHandler(typeVariableImpl));
++    return typeVariable;
++  }
++
++  /**
++   * Invocation handler to work around a compatibility problem between Java 7 and Java 8.
++   *
++   * <p>Java 8 introduced a new method {@code getAnnotatedBounds()} in the {@link TypeVariable}
++   * interface, whose return type {@code AnnotatedType[]} is also new in Java 8. That means that we
++   * cannot implement that interface in source code in a way that will compile on both Java 7 and
++   * Java 8. If we include the {@code getAnnotatedBounds()} method then its return type means
++   * it won't compile on Java 7, while if we don't include the method then the compiler will
++   * complain that an abstract method is unimplemented. So instead we use a dynamic proxy to
++   * get an implementation. If the method being called on the {@code TypeVariable} instance has
++   * the same name as one of the public methods of {@link TypeVariableImpl}, the proxy calls
++   * the same method on its instance of {@code TypeVariableImpl}. Otherwise it throws {@link
++   * UnsupportedOperationException}; this should only apply to {@code getAnnotatedBounds()}. This
++   * does mean that users on Java 8 who obtain an instance of {@code TypeVariable} from {@link
++   * TypeResolver#resolveType} will not be able to call {@code getAnnotatedBounds()} on it, but that
++   * should hopefully be rare.
++   *
++   * <p>This workaround should be removed at a distant future time when we no longer support Java
++   * versions earlier than 8.
++   */
++  private static final class TypeVariableInvocationHandler implements InvocationHandler {
++    private static final ImmutableMap<String, Method> typeVariableMethods;
++    static {
++      ImmutableMap.Builder<String, Method> builder = ImmutableMap.builder();
++      for (Method method : TypeVariableImpl.class.getMethods()) {
++        if (method.getDeclaringClass().equals(TypeVariableImpl.class)) {
++          builder.put(method.getName(), method);
++        }
++      }
++      typeVariableMethods = builder.build();
++    }
++
++    private final TypeVariableImpl<?> typeVariableImpl;
++
++    TypeVariableInvocationHandler(TypeVariableImpl<?> typeVariableImpl) {
++      this.typeVariableImpl = typeVariableImpl;
++    }
++
++    @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
++      String methodName = method.getName();
++      Method typeVariableMethod = typeVariableMethods.get(methodName);
++      if (typeVariableMethod == null) {
++        throw new UnsupportedOperationException(methodName);
++      } else {
++        try {
++          return typeVariableMethod.invoke(typeVariableImpl, args);
++        } catch (InvocationTargetException e) {
++          throw e.getCause();
++        }
++      }
++    }
++  }
++
++  private static final class TypeVariableImpl<D extends GenericDeclaration> {
+ 
+     private final D genericDeclaration;
+     private final String name;
+@@ -331,15 +396,19 @@
+       this.bounds = ImmutableList.copyOf(bounds);
+     }
+ 
+-    @Override public Type[] getBounds() {
++    public Type[] getBounds() {
+       return toArray(bounds);
+     }
+ 
+-    @Override public D getGenericDeclaration() {
++    public D getGenericDeclaration() {
+       return genericDeclaration;
+     }
+ 
+-    @Override public String getName() {
++    public String getName() {
++      return name;
++    }
++
++    public String getTypeName() {
+       return name;
+     }
+ 
+@@ -354,8 +423,12 @@
+     @Override public boolean equals(Object obj) {
+       if (NativeTypeVariableEquals.NATIVE_TYPE_VARIABLE_ONLY) {
+         // equal only to our TypeVariable implementation with identical bounds
+-        if (obj instanceof TypeVariableImpl) {
+-          TypeVariableImpl<?> that = (TypeVariableImpl<?>) obj;
++        if (obj != null
++            && Proxy.isProxyClass(obj.getClass())
++            && Proxy.getInvocationHandler(obj) instanceof TypeVariableInvocationHandler) {
++          TypeVariableInvocationHandler typeVariableInvocationHandler =
++              (TypeVariableInvocationHandler) Proxy.getInvocationHandler(obj);
++          TypeVariableImpl<?> that = typeVariableInvocationHandler.typeVariableImpl;
+           return name.equals(that.getName())
+               && genericDeclaration.equals(that.getGenericDeclaration())
+               && bounds.equals(that.bounds);
diff --git a/debian/patches/series b/debian/patches/series
index a935f21..194bef1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,4 @@
 04-source-encoding.patch
 05-preserve-mapmaker-makecomputingmap.patch
 06-preserve-pre-guava18-methods.patch
+07-java8-compatibility.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/guava-libraries.git



More information about the pkg-java-commits mailing list