]> source.dussan.org Git - javassist.git/commitdiff
adds a method taking Lookup to java.util.proxy.
authorchibash <chiba@javassist.org>
Sun, 9 Sep 2018 17:39:42 +0000 (02:39 +0900)
committerchibash <chiba@javassist.org>
Sun, 9 Sep 2018 17:39:42 +0000 (02:39 +0900)
src/main/javassist/CtClass.java
src/main/javassist/util/proxy/DefineClassHelper.java
src/main/javassist/util/proxy/FactoryHelper.java
src/main/javassist/util/proxy/ProxyFactory.java

index 140a9cab6590b7a009604acfdde31a7bc32e6801..bb5bab6e5ca38f19ffa6ad8ffb6f26230d621b2d 100644 (file)
@@ -1295,8 +1295,9 @@ public abstract class CtClass {
      * Once this method is called, further modifications are not
      * allowed any more.
      *
-     * <p>This method is provided for convenience.  If you need more
-     * complex functionality, you should write your own class loader.
+     * <p>This method is provided for convenience.  You should use
+     * {@code toClass(Lookup)} for better compatibility with the
+     * module system.
      *
      * <p>Note: this method calls <code>toClass()</code>
      * in <code>ClassPool</code>.
@@ -1308,6 +1309,7 @@ public abstract class CtClass {
      * @param neighbor    A class belonging to the same package that this
      *                    class belongs to.  It is used to load the class.
      * @see ClassPool#toClass(CtClass,Class)
+     * @see #CtClass(java.lang.invoke.MethodHandles.Lookup)
      * @since 3.24
      */
     public Class<?> toClass(Class<?> neighbor) throws CannotCompileException
index dea536704a8dc979239a7068c958cbea034d9d68..401fed6977e98bc4b3f5fb29a0cd9009044f8f26 100644 (file)
@@ -292,6 +292,7 @@ public class DefineClassHelper {
         throws CannotCompileException
     {
         try {
+            DefineClassHelper.class.getModule().addReads(neighbor.getModule());
             Lookup lookup = MethodHandles.lookup();
             Lookup prvlookup = MethodHandles.privateLookupIn(neighbor, lookup);
             return prvlookup.defineClass(bcode);
index 38fcbf42e3305775e0ece520e141701d294064d9..1928fdd5bdb96a641d0608c2d32aae08420c99ce 100644 (file)
@@ -141,6 +141,24 @@ public class FactoryHelper {
         }
      }
 
+    /**
+     * Loads a class file by a given lookup.
+     *
+     * @param lookup        used to define the class.
+     * @since 3.24
+     */
+    public static Class<?> toClass(ClassFile cf, java.lang.invoke.MethodHandles.Lookup lookup)
+        throws CannotCompileException
+    {
+        try {
+            byte[] b = toBytecode(cf);
+            return DefineClassHelper.toClass(lookup, b);
+        }
+        catch (IOException e) {
+            throw new CannotCompileException(e);
+        }
+     }
+
     private static byte[] toBytecode(ClassFile cf) throws IOException {
         ByteArrayOutputStream barray = new ByteArrayOutputStream();
         DataOutputStream out = new DataOutputStream(barray);
index 07b0e16136b6f62ac6931e351074fbd7eea9f256..bc2c024f0c2a2d8b350e52bc0912bee01a1dfbeb 100644 (file)
@@ -35,6 +35,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
+import java.lang.invoke.MethodHandles.Lookup;
 
 import javassist.CannotCompileException;
 import javassist.bytecode.AccessFlag;
@@ -436,43 +437,92 @@ public class ProxyFactory {
 
     /**
      * Generates a proxy class using the current filter.
+     * The module or package where a proxy class is created
+     * has to be opened to this package or the Javassist module.
+     *
+     * @see #createClass(Lookup)
      */
     public Class<?> createClass() {
         if (signature == null) {
             computeSignature(methodFilter);
         }
-        return createClass1();
+        return createClass1(null);
     }
 
     /**
      * Generates a proxy class using the supplied filter.
+     * The module or package where a proxy class is created
+     * has to be opened to this package or the Javassist module.
      */
     public Class<?> createClass(MethodFilter filter) {
         computeSignature(filter);
-        return createClass1();
+        return createClass1(null);
     }
 
     /**
      * Generates a proxy class with a specific signature.
      * access is package local so ProxyObjectInputStream can use this
      * @param signature
-     * @return
      */
     Class<?> createClass(byte[] signature)
     {
         installSignature(signature);
-        return createClass1();
+        return createClass1(null);
+    }
+
+    /**
+     * Generates a proxy class using the current filter.
+     *
+     * @param lookup    used for loading the proxy class.
+     *                  It needs an appropriate right to invoke {@code defineClass}
+     *                  for the proxy class.
+     * @since 3.24
+     */
+    public Class<?> createClass(Lookup lookup) {
+        if (signature == null) {
+            computeSignature(methodFilter);
+        }
+        return createClass1(lookup);
     }
 
-    private Class<?> createClass1() {
+    /**
+     * Generates a proxy class using the supplied filter.
+     *
+     * @param lookup    used for loading the proxy class.
+     *                  It needs an appropriate right to invoke {@code defineClass}
+     *                  for the proxy class.
+     * @param filter    the filter.
+     * @since 3.24
+     */
+    public Class<?> createClass(Lookup lookup, MethodFilter filter) {
+        computeSignature(filter);
+        return createClass1(lookup);
+    }
+
+    /**
+     * Generates a proxy class with a specific signature.
+     * access is package local so ProxyObjectInputStream can use this.
+     *
+     * @param lookup    used for loading the proxy class.
+     *                  It needs an appropriate right to invoke {@code defineClass}
+     *                  for the proxy class.
+     * @param signature         the signature.
+     */
+    Class<?> createClass(Lookup lookup, byte[] signature)
+    {
+        installSignature(signature);
+        return createClass1(lookup);
+    }
+
+    private Class<?> createClass1(Lookup lookup) {
         Class<?> result = thisClass;
         if (result == null) {
             ClassLoader cl = getClassLoader();
             synchronized (proxyCache) {
                 if (factoryUseCache)
-                    createClass2(cl);
+                    createClass2(cl, lookup);
                 else
-                    createClass3(cl);
+                    createClass3(cl, lookup);
 
                 result = thisClass;
                 // don't retain any unwanted references
@@ -512,7 +562,7 @@ public class ProxyFactory {
         return sbuf.toString();
     }
 
-    private void createClass2(ClassLoader cl) {
+    private void createClass2(ClassLoader cl, Lookup lookup) {
         String key = getKey(superClass, interfaces, signature, factoryWriteReplace);
         /*
          * Excessive concurrency causes a large memory footprint and slows the
@@ -534,13 +584,13 @@ public class ProxyFactory {
                     return;
                 }
             }
-            createClass3(cl);
+            createClass3(cl, lookup);
             details = new  ProxyDetails(signature, thisClass, factoryWriteReplace);
             cacheForTheLoader.put(key, details);
         // }
     }
 
-    private void createClass3(ClassLoader cl) {
+    private void createClass3(ClassLoader cl, Lookup lookup) {
         // we need a new class so we need a new class name
         allocateClassName();
 
@@ -549,7 +599,11 @@ public class ProxyFactory {
             if (writeDirectory != null)
                 FactoryHelper.writeFile(cf, writeDirectory);
 
-            thisClass = FactoryHelper.toClass(cf, getClassInTheSamePackage(), cl, getDomain());
+            if (lookup == null)
+                thisClass = FactoryHelper.toClass(cf, getClassInTheSamePackage(), cl, getDomain());
+            else
+                thisClass = FactoryHelper.toClass(cf, lookup);
+
             setField(FILTER_SIGNATURE_FIELD, signature);
             // legacy behaviour : we only set the default interceptor static field if we are not using the cache
             if (!factoryUseCache) {