[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