[Git][java-team/cglib][upstream] New upstream version 3.2.10

Emmanuel Bourg gitlab at salsa.debian.org
Sun Jan 6 00:12:55 GMT 2019


Emmanuel Bourg pushed to branch upstream at Debian Java Maintainers / cglib


Commits:
0f1cbc6d by Emmanuel Bourg at 2019-01-06T00:06:46Z
New upstream version 3.2.10
- - - - -


10 changed files:

- cglib-integration-test/pom.xml
- cglib-jmh/pom.xml
- cglib-nodep/pom.xml
- cglib-sample/pom.xml
- cglib/pom.xml
- cglib/src/main/java/net/sf/cglib/beans/BulkBeanEmitter.java
- cglib/src/main/java/net/sf/cglib/core/AbstractClassGenerator.java
- cglib/src/main/java/net/sf/cglib/proxy/BridgeMethodResolver.java
- cglib/src/test/java/net/sf/cglib/proxy/TestEnhancer.java
- pom.xml


Changes:

=====================================
cglib-integration-test/pom.xml
=====================================
@@ -9,7 +9,7 @@
     <parent>
         <groupId>cglib</groupId>
         <artifactId>cglib-parent</artifactId>
-        <version>3.2.9</version>
+        <version>3.2.10</version>
     </parent>
 
     <!-- ====================================================================== -->


=====================================
cglib-jmh/pom.xml
=====================================
@@ -7,7 +7,7 @@
     <parent>
         <artifactId>cglib-parent</artifactId>
         <groupId>cglib</groupId>
-        <version>3.2.9</version>
+        <version>3.2.10</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 


=====================================
cglib-nodep/pom.xml
=====================================
@@ -9,7 +9,7 @@
     <parent>
         <groupId>cglib</groupId>
         <artifactId>cglib-parent</artifactId>
-        <version>3.2.9</version>
+        <version>3.2.10</version>
     </parent>
 
     <!-- ====================================================================== -->


=====================================
cglib-sample/pom.xml
=====================================
@@ -9,7 +9,7 @@
     <parent>
         <groupId>cglib</groupId>
         <artifactId>cglib-parent</artifactId>
-        <version>3.2.9</version>
+        <version>3.2.10</version>
     </parent>
 
     <!-- ====================================================================== -->


=====================================
cglib/pom.xml
=====================================
@@ -9,7 +9,7 @@
     <parent>
         <groupId>cglib</groupId>
         <artifactId>cglib-parent</artifactId>
-        <version>3.2.9</version>
+        <version>3.2.10</version>
     </parent>
 
     <!-- ====================================================================== -->


=====================================
cglib/src/main/java/net/sf/cglib/beans/BulkBeanEmitter.java
=====================================
@@ -56,7 +56,7 @@ class BulkBeanEmitter extends ClassEmitter {
 
     private void generateGet(final Class target, final Method[] getters) {
         CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null);
-        if (getters.length >= 0) {
+        if (getters.length > 0) {
             e.load_arg(0);
             e.checkcast(Type.getType(target));
             Local bean = e.make_local();


=====================================
cglib/src/main/java/net/sf/cglib/core/AbstractClassGenerator.java
=====================================
@@ -39,13 +39,16 @@ implements ClassGenerator
 
     private static volatile Map<ClassLoader, ClassLoaderData> CACHE = new WeakHashMap<ClassLoader, ClassLoaderData>();
 
+    private static final boolean DEFAULT_USE_CACHE =
+        Boolean.parseBoolean(System.getProperty("cglib.useCache", "true"));
+
     private GeneratorStrategy strategy = DefaultGeneratorStrategy.INSTANCE;
     private NamingPolicy namingPolicy = DefaultNamingPolicy.INSTANCE;
     private Source source;
     private ClassLoader classLoader;
     private String namePrefix;
     private Object key;
-    private boolean useCache = true;
+    private boolean useCache = DEFAULT_USE_CACHE;
     private String className;
     private boolean attemptLoad;
 


=====================================
cglib/src/main/java/net/sf/cglib/proxy/BridgeMethodResolver.java
=====================================
@@ -22,19 +22,21 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
-
 import net.sf.cglib.core.Constants;
 import net.sf.cglib.core.Signature;
-
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 
 /**
- * Uses bytecode reflection to figure out the targets of all bridge methods
- * that use invokespecial, so that we can later rewrite them to use invokevirtual.
- * 
+ * Uses bytecode reflection to figure out the targets of all bridge methods that use invokespecial
+ * and invokeinterface, so that we can later rewrite them to use invokevirtual.
+ *
+ * <p>For interface bridges, using invokesuper will fail since the method being bridged to is in a
+ * superinterface, not a superclass. Starting in Java 8, javac emits default bridge methods in
+ * interfaces, which use invokeinterface to bridge to the target method.
+ *
  * @author sberlin at gmail.com (Sam Berlin)
  */
 class BridgeMethodResolver {
@@ -96,9 +98,11 @@ class BridgeMethodResolver {
             if (eligibleMethods.remove(sig)) {
                 currentMethod = sig;
                 return new MethodVisitor(Constants.ASM_API) {
-                    public void visitMethodInsn(int opcode, String owner, String name,
-                                                String desc, boolean itf) {
-                        if (opcode == Opcodes.INVOKESPECIAL && currentMethod != null) {
+                    public void visitMethodInsn(
+                            int opcode, String owner, String name, String desc, boolean itf) {
+                        if ((opcode == Opcodes.INVOKESPECIAL
+                                        || (itf && opcode == Opcodes.INVOKEINTERFACE))
+                                && currentMethod != null) {
                             Signature target = new Signature(name, desc);
                             // If the target signature is the same as the current,
                             // we shouldn't change our bridge becaues invokespecial


=====================================
cglib/src/test/java/net/sf/cglib/proxy/TestEnhancer.java
=====================================
@@ -1418,6 +1418,163 @@ public class TestEnhancer extends CodeGenTestCase {
     assertEquals(Arrays.asList(Object.class, String.class), paramTypes);
   }
 
+    public void testInterfaceBridge() throws Exception {
+        // recent versions of javac will generate a synthetic default bridge for f(Object) in B
+
+        // interface A<T> {
+        //     void f(T t);
+        // }
+        // interface B<T extends Number> extends A<T>{
+        //     void f(T t);
+        // }
+
+        if (getMajor() < 8) {
+            // The test relies on Java 8 bytecode for default methods.
+            return;
+        }
+
+        final Map<String, byte[]> classes = new HashMap<String, byte[]>();
+        {
+            ClassWriter classWriter = new ClassWriter(0);
+            classWriter.visit(
+                    Opcodes.V1_8,
+                    Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE | Opcodes.ACC_PUBLIC,
+                    "A",
+                    "<T:Ljava/lang/Object;>Ljava/lang/Object;",
+                    "java/lang/Object",
+                    null);
+            MethodVisitor methodVisitor =
+                    classWriter.visitMethod(
+                            Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT,
+                            "f",
+                            "(Ljava/lang/Object;)V",
+                            "(TT;)V",
+                            null);
+            methodVisitor.visitEnd();
+            classWriter.visitEnd();
+
+            classes.put("A.class", classWriter.toByteArray());
+        }
+
+        {
+            ClassWriter classWriter = new ClassWriter(0);
+            classWriter.visit(
+                    Opcodes.V1_8,
+                    Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE | Opcodes.ACC_PUBLIC,
+                    "B",
+                    "<T:Ljava/lang/Number;>Ljava/lang/Object;LA<TT;>;",
+                    "java/lang/Object",
+                    new String[] {"A"});
+            {
+                MethodVisitor methodVisitor =
+                        classWriter.visitMethod(
+                                Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT,
+                                "f",
+                                "(Ljava/lang/Number;)V",
+                                "(TT;)V",
+                                null);
+                methodVisitor.visitEnd();
+            }
+            {
+                MethodVisitor methodVisitor =
+                        classWriter.visitMethod(
+                                Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_SYNTHETIC,
+                                "f",
+                                "(Ljava/lang/Object;)V",
+                                null,
+                                null);
+                methodVisitor.visitCode();
+                methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
+                methodVisitor.visitVarInsn(Opcodes.ALOAD, 1);
+                methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Number");
+                methodVisitor.visitMethodInsn(
+                        Opcodes.INVOKEINTERFACE, "B", "f", "(Ljava/lang/Number;)V", true);
+                methodVisitor.visitInsn(Opcodes.RETURN);
+                methodVisitor.visitMaxs(2, 2);
+                methodVisitor.visitEnd();
+            }
+            classWriter.visitEnd();
+
+            classes.put("B.class", classWriter.toByteArray());
+        }
+
+        ClassLoader classLoader =
+                new ClassLoader(getClass().getClassLoader()) {
+                    @Override
+                    public InputStream getResourceAsStream(String name) {
+                        InputStream is = super.getResourceAsStream(name);
+                        if (is != null) {
+                            return is;
+                        }
+                        if (classes.containsKey(name)) {
+                            return new ByteArrayInputStream(classes.get(name));
+                        }
+                        return null;
+                    }
+
+                    public Class findClass(String name) throws ClassNotFoundException {
+                        byte[] ba = classes.get(name.replace('.', '/') + ".class");
+                        if (ba != null) {
+                            return defineClass(name, ba, 0, ba.length);
+                        }
+                        throw new ClassNotFoundException(name);
+                    }
+                };
+
+        final List<Class> paramTypes = new ArrayList<Class>();
+
+        Enhancer e = new Enhancer();
+        e.setClassLoader(classLoader);
+        e.setInterfaces(new Class[] {classLoader.loadClass("B")});
+        e.setCallbackFilter(
+                new CallbackFilter() {
+                    public int accept(Method method) {
+                        return method.isBridge() ? 1 : 0;
+                    }
+                });
+        e.setCallbacks(
+                new Callback[] {
+                    new MethodInterceptor() {
+                        public Object intercept(
+                                Object obj, Method method, Object[] args, MethodProxy proxy) {
+                            if (method.getParameterTypes().length > 0) {
+                                paramTypes.add(method.getParameterTypes()[0]);
+                            }
+                            return null;
+                        }
+                    },
+                    NoOp.INSTANCE
+                });
+
+        Object c = e.create();
+
+        for (Method m : classLoader.loadClass("A").getDeclaredMethods()) {
+            if (m.getName().equals("f")) {
+                m.invoke(c, new Object[] {null});
+            }
+        }
+
+        // f(Object)void should bridge to f(Number)void
+        assertEquals(Arrays.asList(Number.class), paramTypes);
+    }
+
+    private static int getMajor() {
+        try {
+            Method versionMethod = Runtime.class.getMethod("version");
+            Object version = versionMethod.invoke(null);
+            return (Integer) version.getClass().getMethod("major").invoke(version);
+        } catch (Exception e) {
+            // continue below
+        }
+
+        int version = (int) Double.parseDouble(System.getProperty("java.class.version"));
+        if (49 <= version && version <= 52) {
+            return version - (49 - 5);
+        }
+        throw new IllegalStateException(
+                "Unknown Java version: " + System.getProperty("java.specification.version"));
+    }
+
     static class ErasedType {}
     static class RetType extends ErasedType {}
     static class Refined extends RetType {}


=====================================
pom.xml
=====================================
@@ -14,7 +14,7 @@
     <!-- ====================================================================== -->
     <groupId>cglib</groupId>
     <artifactId>cglib-parent</artifactId>
-    <version>3.2.9</version>
+    <version>3.2.10</version>
     <packaging>pom</packaging>
 
     <name>Code Generation Library</name>



View it on GitLab: https://salsa.debian.org/java-team/cglib/commit/0f1cbc6d488929ea6b7cfefc7af7e34dd1749a2f

-- 
View it on GitLab: https://salsa.debian.org/java-team/cglib/commit/0f1cbc6d488929ea6b7cfefc7af7e34dd1749a2f
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20190106/73d752a8/attachment.html>


More information about the pkg-java-commits mailing list