diff options
author | chibash <chiba@javassist.org> | 2018-09-10 02:39:42 +0900 |
---|---|---|
committer | chibash <chiba@javassist.org> | 2018-09-10 02:39:42 +0900 |
commit | c32e946317054a13214b772188a3daa8fc44f425 (patch) | |
tree | 6b2bac6adaa1f76ef4684e55862f400dff383355 | |
parent | 46069993ec2284e5e48347fd445997a4f0ba5321 (diff) | |
download | javassist-c32e946317054a13214b772188a3daa8fc44f425.tar.gz javassist-c32e946317054a13214b772188a3daa8fc44f425.zip |
adds a method taking Lookup to java.util.proxy.
-rw-r--r-- | src/main/javassist/CtClass.java | 6 | ||||
-rw-r--r-- | src/main/javassist/util/proxy/DefineClassHelper.java | 1 | ||||
-rw-r--r-- | src/main/javassist/util/proxy/FactoryHelper.java | 18 | ||||
-rw-r--r-- | src/main/javassist/util/proxy/ProxyFactory.java | 76 |
4 files changed, 88 insertions, 13 deletions
diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index 140a9cab..bb5bab6e 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -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 diff --git a/src/main/javassist/util/proxy/DefineClassHelper.java b/src/main/javassist/util/proxy/DefineClassHelper.java index dea53670..401fed69 100644 --- a/src/main/javassist/util/proxy/DefineClassHelper.java +++ b/src/main/javassist/util/proxy/DefineClassHelper.java @@ -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); diff --git a/src/main/javassist/util/proxy/FactoryHelper.java b/src/main/javassist/util/proxy/FactoryHelper.java index 38fcbf42..1928fdd5 100644 --- a/src/main/javassist/util/proxy/FactoryHelper.java +++ b/src/main/javassist/util/proxy/FactoryHelper.java @@ -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); diff --git a/src/main/javassist/util/proxy/ProxyFactory.java b/src/main/javassist/util/proxy/ProxyFactory.java index 07b0e161..bc2c024f 100644 --- a/src/main/javassist/util/proxy/ProxyFactory.java +++ b/src/main/javassist/util/proxy/ProxyFactory.java @@ -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) { |