aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchibash <chiba@javassist.org>2018-09-10 02:39:42 +0900
committerchibash <chiba@javassist.org>2018-09-10 02:39:42 +0900
commitc32e946317054a13214b772188a3daa8fc44f425 (patch)
tree6b2bac6adaa1f76ef4684e55862f400dff383355
parent46069993ec2284e5e48347fd445997a4f0ba5321 (diff)
downloadjavassist-c32e946317054a13214b772188a3daa8fc44f425.tar.gz
javassist-c32e946317054a13214b772188a3daa8fc44f425.zip
adds a method taking Lookup to java.util.proxy.
-rw-r--r--src/main/javassist/CtClass.java6
-rw-r--r--src/main/javassist/util/proxy/DefineClassHelper.java1
-rw-r--r--src/main/javassist/util/proxy/FactoryHelper.java18
-rw-r--r--src/main/javassist/util/proxy/ProxyFactory.java76
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) {