Browse Source

adds a method taking Lookup to java.util.proxy.

tags/rel_3_24_0_rc
chibash 5 years ago
parent
commit
c32e946317

+ 4
- 2
src/main/javassist/CtClass.java View 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

+ 1
- 0
src/main/javassist/util/proxy/DefineClassHelper.java View 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);

+ 18
- 0
src/main/javassist/util/proxy/FactoryHelper.java View 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);

+ 65
- 11
src/main/javassist/util/proxy/ProxyFactory.java View 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) {

Loading…
Cancel
Save