Class ProxyFactory
- java.lang.Object
-
- javassist.util.proxy.ProxyFactory
-
public class ProxyFactory extends java.lang.Object
Factory of dynamic proxy classes.This factory generates a class that extends the given super class and implements the given interfaces. The calls of the methods inherited from the super class are forwarded and then
invoke()
is called on the method handler associated with instances of the generated class. The calls of the methods from the interfaces are also forwarded to the method handler.For example, if the following code is executed,
ProxyFactory f = new ProxyFactory(); f.setSuperclass(Foo.class); f.setFilter(new MethodFilter() { public boolean isHandled(Method m) { // ignore finalize() return !m.getName().equals("finalize"); } }); Class c = f.createClass(); MethodHandler mi = new MethodHandler() { public Object invoke(Object self, Method m, Method proceed, Object[] args) throws Throwable { System.out.println("Name: " + m.getName()); return proceed.invoke(self, args); // execute the original method. } }; Foo foo = (Foo)c.newInstance(); ((Proxy)foo).setHandler(mi);
Here,
Method
isjava.lang.reflect.Method
.Then, the following method call will be forwarded to MethodHandler
mi
and prints a message before executing the originally called methodbar()
inFoo
.foo.bar();
The last three lines of the code shown above can be replaced with a call to the helper method
create
, which generates a proxy class, instantiates it, and sets the method handler of the instance:: Foo foo = (Foo)f.create(new Class[0], new Object[0], mi);
To change the method handler during runtime, execute the following code:
MethodHandler mi = ... ; // alternative handler ((Proxy)foo).setHandler(mi);
If setHandler is never called for a proxy instance then it will employ the default handler which proceeds by invoking the original method. The behaviour of the default handler is identical to the following handler:
class EmptyHandler implements MethodHandler { public Object invoke(Object self, Method m, Method proceed, Object[] args) throws Exception { return proceed.invoke(self, args); } }
A proxy factory caches and reuses proxy classes by default. It is possible to reset this default globally by setting static field
useCache
to false. Caching may also be configured for a specific factory by calling instance methodsetUseCache(boolean)
. It is strongly recommended that new clients of class ProxyFactory enable caching. Failure to do so may lead to exhaustion of the heap memory area used to store classes.Caching is automatically disabled for any given proxy factory if deprecated instance method
setHandler(MethodHandler)
is called. This method was used to specify a default handler which newly created proxy classes should install when they create their instances. It is only retained to provide backward compatibility with previous releases of javassist. Unfortunately,this legacy behaviour makes caching and reuse of proxy classes impossible. The current programming model expects javassist clients to set the handler of a proxy instance explicitly by calling methodProxy.setHandler(MethodHandler)
as shown in the sample code above. New clients are strongly recommended to use this model rather than callingsetHandler(MethodHandler)
.A proxy object generated by
ProxyFactory
is serializable if its super class or any of its interfaces implementjava.io.Serializable
. However, a serialized proxy object may not be compatible with future releases. The serialization support should be used for short-term storage or RMI.For compatibility with older releases serialization of proxy objects is implemented by adding a writeReplace method to the proxy class. This allows a proxy to be serialized to a conventional
ObjectOutputStream
and deserialized from a correspondingObjectInputStream
. However this method suffers from several problems, the most notable one being that it fails to serialize state inherited from the proxy's superclass.An alternative method of serializing proxy objects is available which fixes these problems. It requires inhibiting generation of the writeReplace method and instead using instances of
ProxyObjectOutputStream
andProxyObjectInputStream
(which are subclasses ofObjectOutputStream
andObjectInputStream
) to serialize and deserialize, respectively, the proxy. These streams recognise javassist proxies and ensure that they are serialized and deserialized without the need for the proxy class to implement special methods such as writeReplace. Generation of the writeReplace method can be disabled globally by setting static fielduseWriteReplace
to false. Alternatively, it may be configured per factory by calling instance methodsetUseWriteReplace(boolean)
.- Since:
- 3.1
- See Also:
MethodHandler
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
ProxyFactory.ClassLoaderProvider
A provider of class loaders.(package private) static class
ProxyFactory.Find2MethodsArgs
(package private) static class
ProxyFactory.ProxyDetails
used to store details of a specific proxy class in the second tier of the proxy cache.static interface
ProxyFactory.UniqueName
A unique class name generator.
-
Field Summary
Fields Modifier and Type Field Description private java.lang.String
basename
static ProxyFactory.ClassLoaderProvider
classLoaderProvider
A provider used bycreateClass()
for obtaining a class loader.private java.lang.String
classname
private static java.lang.String
DEFAULT_INTERCEPTOR
private boolean
factoryUseCache
per factory setting initialised from current setting for useCache but able to be reset before each create callprivate boolean
factoryWriteReplace
per factory setting initialised from current setting for useWriteReplace but able to be reset before each create callprivate static java.lang.String
FILTER_SIGNATURE_FIELD
private static java.lang.String
FILTER_SIGNATURE_TYPE
private java.lang.String
genericSignature
private MethodHandler
handler
private static java.lang.String
HANDLER
private static java.lang.String
HANDLER_GETTER
private static java.lang.String
HANDLER_GETTER_KEY
private static java.lang.String
HANDLER_GETTER_TYPE
private static java.lang.String
HANDLER_SETTER
private static java.lang.String
HANDLER_SETTER_TYPE
private static java.lang.String
HANDLER_TYPE
private boolean
hasGetHandler
private static char[]
hexDigits
private static java.lang.String
HOLDER
private static java.lang.String
HOLDER_TYPE
private java.lang.Class<?>[]
interfaces
private MethodFilter
methodFilter
static ProxyFactory.UniqueName
nameGenerator
A unique class name generator.private static java.lang.String
NULL_INTERCEPTOR_HOLDER
private static java.lang.Class<?>
OBJECT_TYPE
static boolean
onlyPublicMethods
If true, only public/protected methods are forwarded to a proxy object.private static java.lang.String
packageForJavaBase
private static java.util.Map<java.lang.ClassLoader,java.util.Map<java.lang.String,ProxyFactory.ProxyDetails>>
proxyCache
private static java.lang.String
SERIAL_VERSION_UID_FIELD
private static java.lang.String
SERIAL_VERSION_UID_TYPE
private static long
SERIAL_VERSION_UID_VALUE
private byte[]
signature
private java.util.List<java.util.Map.Entry<java.lang.String,java.lang.reflect.Method>>
signatureMethods
private static java.util.Comparator<java.util.Map.Entry<java.lang.String,java.lang.reflect.Method>>
sorter
private java.lang.Class<?>
superClass
private java.lang.String
superName
private java.lang.Class<?>
thisClass
static boolean
useCache
If true, a generated proxy class is cached and it will be reused when generating the proxy class with the same properties is requested.static boolean
useWriteReplace
If true, a generated proxy class will implement method writeReplace enabling serialization of its proxies to a conventional ObjectOutputStream.java.lang.String
writeDirectory
If the value of this variable is not null, the class file of the generated proxy class is written under the directory specified by this variable.
-
Constructor Summary
Constructors Constructor Description ProxyFactory()
Constructs a factory of proxy class.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description private static void
addClassInitializer(ClassFile cf, ConstPool cp, java.lang.String classname, int size, java.util.List<ProxyFactory.Find2MethodsArgs> forwarders)
private static void
addGetter(java.lang.String classname, ClassFile cf, ConstPool cp)
private static int
addLoad(Bytecode code, int n, java.lang.Class<?> type)
private static int
addLoadParameters(Bytecode code, java.lang.Class<?>[] params, int offset)
private static int
addReturn(Bytecode code, java.lang.Class<?> type)
private static void
addSetter(java.lang.String classname, ClassFile cf, ConstPool cp)
private static void
addUnwrapper(Bytecode code, java.lang.Class<?> type)
private void
allocateClassName()
private static boolean
areParametersSame(java.lang.reflect.Method method, java.lang.reflect.Method targetMethod)
private static void
callFind2Methods(Bytecode code, java.lang.String superMethod, java.lang.String thisMethod, int index, java.lang.String desc, int classVar, int arrayVar)
private void
checkClassAndSuperName()
private void
computeSignature(MethodFilter filter)
java.lang.Object
create(java.lang.Class<?>[] paramTypes, java.lang.Object[] args)
Creates a proxy class and returns an instance of that class.java.lang.Object
create(java.lang.Class<?>[] paramTypes, java.lang.Object[] args, MethodHandler mh)
Creates a proxy class and returns an instance of that class.java.lang.Class<?>
createClass()
Generates a proxy class using the current filter.(package private) java.lang.Class<?>
createClass(byte[] signature)
Generates a proxy class with a specific signature.java.lang.Class<?>
createClass(java.lang.invoke.MethodHandles.Lookup lookup)
Generates a proxy class using the current filter.(package private) java.lang.Class<?>
createClass(java.lang.invoke.MethodHandles.Lookup lookup, byte[] signature)
Generates a proxy class with a specific signature.java.lang.Class<?>
createClass(java.lang.invoke.MethodHandles.Lookup lookup, MethodFilter filter)
Generates a proxy class using the supplied filter.java.lang.Class<?>
createClass(MethodFilter filter)
Generates a proxy class using the supplied filter.private java.lang.Class<?>
createClass1(java.lang.invoke.MethodHandles.Lookup lookup)
private void
createClass2(java.lang.ClassLoader cl, java.lang.invoke.MethodHandles.Lookup lookup)
private void
createClass3(java.lang.ClassLoader cl, java.lang.invoke.MethodHandles.Lookup lookup)
private java.lang.Class<?>
getClassInTheSamePackage()
Obtains a class belonging to the same package that the created proxy class belongs to.protected java.lang.ClassLoader
getClassLoader()
protected java.lang.ClassLoader
getClassLoader0()
protected java.security.ProtectionDomain
getDomain()
private static java.lang.Object
getField(java.lang.Class<?> clazz, java.lang.String fieldName)
(package private) static byte[]
getFilterSignature(java.lang.Class<?> clazz)
static MethodHandler
getHandler(Proxy p)
Obtains the method handler of the given proxy object.java.lang.Class<?>[]
getInterfaces()
Obtains the interfaces set bysetInterfaces
.java.lang.String
getKey(java.lang.Class<?> superClass, java.lang.Class<?>[] interfaces, byte[] signature, boolean useWriteReplace)
private java.util.Map<java.lang.String,java.lang.reflect.Method>
getMethods(java.lang.Class<?> superClass, java.lang.Class<?>[] interfaceTypes)
private void
getMethods(java.util.Map<java.lang.String,java.lang.reflect.Method> hash, java.lang.Class<?> clazz, java.util.Set<java.lang.Class<?>> visitedClasses)
private static java.lang.String
getPackageName(java.lang.String name)
java.lang.Class<?>
getSuperclass()
Obtains the super class set bysetSuperclass()
.private void
installSignature(byte[] signature)
private java.lang.Class<?>
invokespecialTarget(java.lang.Class<?> declClass)
private static boolean
isBridge(java.lang.reflect.Method m)
private static boolean
isDuplicated(int index, java.lang.reflect.Method[] methods)
static boolean
isProxyClass(java.lang.Class<?> cl)
determine if a class is a javassist proxy classboolean
isUseCache()
test whether this factory uses the proxy cacheboolean
isUseWriteReplace()
test whether this factory installs a writeReplace method in created classesprivate static boolean
isVisible(int mod, java.lang.String from, java.lang.reflect.Member meth)
Returns true if the method is visible from the package.private static java.lang.String
keyToDesc(java.lang.String key, java.lang.reflect.Method m)
private ClassFile
make()
private static MethodInfo
makeConstructor(java.lang.String thisClassName, java.lang.reflect.Constructor<?> cons, ConstPool cp, java.lang.Class<?> superClass, boolean doHandlerInit)
private void
makeConstructors(java.lang.String thisClassName, ClassFile cf, ConstPool cp, java.lang.String classname)
private MethodInfo
makeDelegator(java.lang.reflect.Method meth, java.lang.String desc, ConstPool cp, java.lang.Class<?> declClass, java.lang.String delegatorName)
private static MethodInfo
makeForwarder(java.lang.String thisClassName, java.lang.reflect.Method meth, java.lang.String desc, ConstPool cp, java.lang.Class<?> declClass, java.lang.String delegatorName, int index, java.util.List<ProxyFactory.Find2MethodsArgs> forwarders)
private static void
makeParameterList(Bytecode code, java.lang.Class<?>[] params)
private static java.lang.String
makeProxyName(java.lang.String classname)
private void
makeSortedMethodList()
private static java.lang.String
makeUniqueName(java.lang.String name, java.util.List<java.util.Map.Entry<java.lang.String,java.lang.reflect.Method>> sortedMethods)
private static boolean
makeUniqueName0(java.lang.String name, java.util.Iterator<java.util.Map.Entry<java.lang.String,java.lang.reflect.Method>> it)
private static int
makeWrapper(Bytecode code, java.lang.Class<?> type, int regno)
private static MethodInfo
makeWriteReplace(ConstPool cp)
private void
override(java.lang.String thisClassname, java.lang.reflect.Method meth, java.lang.String prefix, int index, java.lang.String desc, ClassFile cf, ConstPool cp, java.util.List<ProxyFactory.Find2MethodsArgs> forwarders)
private int
overrideMethods(ClassFile cf, ConstPool cp, java.lang.String className, java.util.List<ProxyFactory.Find2MethodsArgs> forwarders)
private void
setBit(byte[] signature, int idx)
private void
setField(java.lang.String fieldName, java.lang.Object value)
void
setFilter(MethodFilter mf)
Sets a filter that selects the methods that will be controlled by a handler.void
setGenericSignature(java.lang.String sig)
Sets the generic signature for the proxy class.void
setHandler(MethodHandler mi)
Deprecated.since 3.12 use of this method is incompatible with proxy class caching.void
setInterfaces(java.lang.Class<?>[] ifs)
Sets the interfaces of a proxy class.private static void
setInterfaces(ClassFile cf, java.lang.Class<?>[] interfaces, java.lang.Class<?> proxyClass)
void
setSuperclass(java.lang.Class<?> clazz)
Sets the super class of a proxy class.private static void
setThrows(MethodInfo minfo, ConstPool cp, java.lang.Class<?>[] exceptions)
private static void
setThrows(MethodInfo minfo, ConstPool cp, java.lang.reflect.Method orig)
void
setUseCache(boolean useCache)
configure whether this factory should use the proxy cachevoid
setUseWriteReplace(boolean useWriteReplace)
configure whether this factory should add a writeReplace method to created classesprivate boolean
testBit(byte[] signature, int idx)
-
-
-
Field Detail
-
superClass
private java.lang.Class<?> superClass
-
interfaces
private java.lang.Class<?>[] interfaces
-
methodFilter
private MethodFilter methodFilter
-
handler
private MethodHandler handler
-
signatureMethods
private java.util.List<java.util.Map.Entry<java.lang.String,java.lang.reflect.Method>> signatureMethods
-
hasGetHandler
private boolean hasGetHandler
-
signature
private byte[] signature
-
classname
private java.lang.String classname
-
basename
private java.lang.String basename
-
superName
private java.lang.String superName
-
thisClass
private java.lang.Class<?> thisClass
-
genericSignature
private java.lang.String genericSignature
-
factoryUseCache
private boolean factoryUseCache
per factory setting initialised from current setting for useCache but able to be reset before each create call
-
factoryWriteReplace
private boolean factoryWriteReplace
per factory setting initialised from current setting for useWriteReplace but able to be reset before each create call
-
onlyPublicMethods
public static boolean onlyPublicMethods
If true, only public/protected methods are forwarded to a proxy object. The class for that proxy object is loaded by the
defineClass
method injava.lang.invoke.MethodHandles.Lookup
, which is available in Java 9 or later. This works even whensun.misc.Unsafe
is not available for some reasons (it is already deprecated in Java 9).To load a class, Javassist first tries to use
sun.misc.Unsafe
and, if not available, it uses aprotected
method injava.lang.ClassLoader
viaPrivilegedAction
. Since the latter approach is not available any longer by default in Java 9 or later, the JVM argument--add-opens java.base/java.lang=ALL-UNNAMED
must be given to the JVM when it is used (because of lack ofsun.misc.Unsafe
). If this argument cannot be given to the JVM,onlyPublicMethods
should be set totrue
. Javassist will try to load by usingjava.lang.invoke.MethodHandles.Lookup
.The default value is
false
.- Since:
- 3.22
- See Also:
DefineClassHelper.toClass(String, Class, ClassLoader, ProtectionDomain, byte[])
-
writeDirectory
public java.lang.String writeDirectory
If the value of this variable is not null, the class file of the generated proxy class is written under the directory specified by this variable. For example, if the value is"."
, then the class file is written under the current directory. This method is for debugging.The default value is null.
-
OBJECT_TYPE
private static final java.lang.Class<?> OBJECT_TYPE
-
HOLDER
private static final java.lang.String HOLDER
- See Also:
- Constant Field Values
-
HOLDER_TYPE
private static final java.lang.String HOLDER_TYPE
- See Also:
- Constant Field Values
-
FILTER_SIGNATURE_FIELD
private static final java.lang.String FILTER_SIGNATURE_FIELD
- See Also:
- Constant Field Values
-
FILTER_SIGNATURE_TYPE
private static final java.lang.String FILTER_SIGNATURE_TYPE
- See Also:
- Constant Field Values
-
HANDLER
private static final java.lang.String HANDLER
- See Also:
- Constant Field Values
-
NULL_INTERCEPTOR_HOLDER
private static final java.lang.String NULL_INTERCEPTOR_HOLDER
- See Also:
- Constant Field Values
-
DEFAULT_INTERCEPTOR
private static final java.lang.String DEFAULT_INTERCEPTOR
- See Also:
- Constant Field Values
-
HANDLER_TYPE
private static final java.lang.String HANDLER_TYPE
-
HANDLER_SETTER
private static final java.lang.String HANDLER_SETTER
- See Also:
- Constant Field Values
-
HANDLER_SETTER_TYPE
private static final java.lang.String HANDLER_SETTER_TYPE
-
HANDLER_GETTER
private static final java.lang.String HANDLER_GETTER
- See Also:
- Constant Field Values
-
HANDLER_GETTER_TYPE
private static final java.lang.String HANDLER_GETTER_TYPE
-
SERIAL_VERSION_UID_FIELD
private static final java.lang.String SERIAL_VERSION_UID_FIELD
- See Also:
- Constant Field Values
-
SERIAL_VERSION_UID_TYPE
private static final java.lang.String SERIAL_VERSION_UID_TYPE
- See Also:
- Constant Field Values
-
SERIAL_VERSION_UID_VALUE
private static final long SERIAL_VERSION_UID_VALUE
- See Also:
- Constant Field Values
-
useCache
public static volatile boolean useCache
If true, a generated proxy class is cached and it will be reused when generating the proxy class with the same properties is requested. The default value is true. Note that this value merely specifies the initial setting employed by any newly created proxy factory. The factory setting may be overwritten by calling factory instance methodsetUseCache(boolean)
- Since:
- 3.4
-
useWriteReplace
public static volatile boolean useWriteReplace
If true, a generated proxy class will implement method writeReplace enabling serialization of its proxies to a conventional ObjectOutputStream. this (default) setting retains the old javassist behaviour which has the advantage that it retains compatibility with older releases and requires no extra work on the part of the client performing the serialization. However, it has the disadvantage that state inherited from the superclasses of the proxy is lost during serialization. if false then serialization/deserialization of the proxy instances will preserve all fields. However, serialization must be performed via aProxyObjectOutputStream
and deserialization must be viaProxyObjectInputStream
. Any attempt to serialize proxies whose class was created with useWriteReplace set to false via a normalObjectOutputStream
will fail. Note that this value merely specifies the initial setting employed by any newly created proxy factory. The factory setting may be overwritten by calling factory instance methodsetUseWriteReplace(boolean)
- Since:
- 3.4
-
proxyCache
private static java.util.Map<java.lang.ClassLoader,java.util.Map<java.lang.String,ProxyFactory.ProxyDetails>> proxyCache
-
hexDigits
private static char[] hexDigits
-
classLoaderProvider
public static ProxyFactory.ClassLoaderProvider classLoaderProvider
A provider used bycreateClass()
for obtaining a class loader.get()
on thisClassLoaderProvider
object is called to obtain a class loader.The value of this field can be updated for changing the default implementation.
Example:
ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() { public ClassLoader get(ProxyFactory pf) { return Thread.currentThread().getContextClassLoader(); } };
- Since:
- 3.4
-
nameGenerator
public static ProxyFactory.UniqueName nameGenerator
A unique class name generator. Replacing this generator changes the algorithm to generate a unique name. Theget
method does not have to be asynchronized
method since the access to this field is mutually exclusive and thus thread safe.
-
packageForJavaBase
private static final java.lang.String packageForJavaBase
- See Also:
- Constant Field Values
-
sorter
private static java.util.Comparator<java.util.Map.Entry<java.lang.String,java.lang.reflect.Method>> sorter
-
HANDLER_GETTER_KEY
private static final java.lang.String HANDLER_GETTER_KEY
- See Also:
- Constant Field Values
-
-
Method Detail
-
isUseCache
public boolean isUseCache()
test whether this factory uses the proxy cache- Returns:
- true if this factory uses the proxy cache otherwise false
-
setUseCache
public void setUseCache(boolean useCache)
configure whether this factory should use the proxy cache- Parameters:
useCache
- true if this factory should use the proxy cache and false if it should not use the cache- Throws:
java.lang.RuntimeException
- if a default interceptor has been set for the factory
-
isUseWriteReplace
public boolean isUseWriteReplace()
test whether this factory installs a writeReplace method in created classes- Returns:
- true if this factory installs a writeReplace method in created classes otherwise false
-
setUseWriteReplace
public void setUseWriteReplace(boolean useWriteReplace)
configure whether this factory should add a writeReplace method to created classes- Parameters:
useWriteReplace
- true if this factory should add a writeReplace method to created classes and false if it should not add a writeReplace method
-
isProxyClass
public static boolean isProxyClass(java.lang.Class<?> cl)
determine if a class is a javassist proxy class- Parameters:
cl
-- Returns:
- true if the class is a javassist proxy class otherwise false
-
setSuperclass
public void setSuperclass(java.lang.Class<?> clazz)
Sets the super class of a proxy class.
-
getSuperclass
public java.lang.Class<?> getSuperclass()
Obtains the super class set bysetSuperclass()
.- Since:
- 3.4
-
setInterfaces
public void setInterfaces(java.lang.Class<?>[] ifs)
Sets the interfaces of a proxy class.
-
getInterfaces
public java.lang.Class<?>[] getInterfaces()
Obtains the interfaces set bysetInterfaces
.- Since:
- 3.4
-
setFilter
public void setFilter(MethodFilter mf)
Sets a filter that selects the methods that will be controlled by a handler.
-
setGenericSignature
public void setGenericSignature(java.lang.String sig)
Sets the generic signature for the proxy class.For example,
class NullPtr<T> { T get() { return null; } }
The following code makes a proxy for
NullPtr<String>
:ProxyFactory factory = new ProxyFactory(); factory.setSuperclass(NullPtr.class); factory.setGenericSignature("LNullPtr<Ljava/lang/String;>;"); NullPtr<?> np = (NullPtr<?>)factory.create(null, null); java.lang.reflect.Type[] x = ((java.lang.reflect.ParameterizedType)np.getClass().getGenericSuperclass()) .getActualTypeArguments(); // x[0] == String.class
- Parameters:
sig
- a generic signature.- Since:
- 3.26
- See Also:
CtClass.setGenericSignature(String)
-
createClass
public java.lang.Class<?> createClass()
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 Also:
createClass(Lookup)
-
createClass
public java.lang.Class<?> createClass(MethodFilter filter)
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.
-
createClass
java.lang.Class<?> createClass(byte[] signature)
Generates a proxy class with a specific signature. access is package local so ProxyObjectInputStream can use this- Parameters:
signature
-
-
createClass
public java.lang.Class<?> createClass(java.lang.invoke.MethodHandles.Lookup lookup)
Generates a proxy class using the current filter. It loads a class file by the givenjava.lang.invoke.MethodHandles.Lookup
object, which can be obtained byMethodHandles.lookup()
called from somewhere in the package that the loaded class belongs to.- Parameters:
lookup
- used for loading the proxy class. It needs an appropriate right to invokedefineClass
for the proxy class.- Since:
- 3.24
-
createClass
public java.lang.Class<?> createClass(java.lang.invoke.MethodHandles.Lookup lookup, MethodFilter filter)
Generates a proxy class using the supplied filter.- Parameters:
lookup
- used for loading the proxy class. It needs an appropriate right to invokedefineClass
for the proxy class.filter
- the filter.- Since:
- 3.24
- See Also:
createClass(Lookup)
-
createClass
java.lang.Class<?> createClass(java.lang.invoke.MethodHandles.Lookup lookup, byte[] signature)
Generates a proxy class with a specific signature. access is package local so ProxyObjectInputStream can use this.- Parameters:
lookup
- used for loading the proxy class. It needs an appropriate right to invokedefineClass
for the proxy class.signature
- the signature.
-
createClass1
private java.lang.Class<?> createClass1(java.lang.invoke.MethodHandles.Lookup lookup)
-
getKey
public java.lang.String getKey(java.lang.Class<?> superClass, java.lang.Class<?>[] interfaces, byte[] signature, boolean useWriteReplace)
-
createClass2
private void createClass2(java.lang.ClassLoader cl, java.lang.invoke.MethodHandles.Lookup lookup)
-
createClass3
private void createClass3(java.lang.ClassLoader cl, java.lang.invoke.MethodHandles.Lookup lookup)
-
getClassInTheSamePackage
private java.lang.Class<?> getClassInTheSamePackage()
Obtains a class belonging to the same package that the created proxy class belongs to. It is used to obtain an appropriatejava.lang.invoke.MethodHandles.Lookup
.
-
setField
private void setField(java.lang.String fieldName, java.lang.Object value)
-
getFilterSignature
static byte[] getFilterSignature(java.lang.Class<?> clazz)
-
getField
private static java.lang.Object getField(java.lang.Class<?> clazz, java.lang.String fieldName)
-
getHandler
public static MethodHandler getHandler(Proxy p)
Obtains the method handler of the given proxy object.- Parameters:
p
- a proxy object.- Returns:
- the method handler.
- Since:
- 3.16
-
getClassLoader
protected java.lang.ClassLoader getClassLoader()
-
getClassLoader0
protected java.lang.ClassLoader getClassLoader0()
-
getDomain
protected java.security.ProtectionDomain getDomain()
-
create
public java.lang.Object create(java.lang.Class<?>[] paramTypes, java.lang.Object[] args, MethodHandler mh) throws java.lang.NoSuchMethodException, java.lang.IllegalArgumentException, java.lang.InstantiationException, java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException
Creates a proxy class and returns an instance of that class.- Parameters:
paramTypes
- parameter types for a constructor.args
- arguments passed to a constructor.mh
- the method handler for the proxy class.- Throws:
java.lang.NoSuchMethodException
java.lang.IllegalArgumentException
java.lang.InstantiationException
java.lang.IllegalAccessException
java.lang.reflect.InvocationTargetException
- Since:
- 3.4
-
create
public java.lang.Object create(java.lang.Class<?>[] paramTypes, java.lang.Object[] args) throws java.lang.NoSuchMethodException, java.lang.IllegalArgumentException, java.lang.InstantiationException, java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException
Creates a proxy class and returns an instance of that class.- Parameters:
paramTypes
- parameter types for a constructor.args
- arguments passed to a constructor.- Throws:
java.lang.NoSuchMethodException
java.lang.IllegalArgumentException
java.lang.InstantiationException
java.lang.IllegalAccessException
java.lang.reflect.InvocationTargetException
-
setHandler
@Deprecated public void setHandler(MethodHandler mi)
Deprecated.since 3.12 use of this method is incompatible with proxy class caching. instead clients should call methodProxy.setHandler(MethodHandler)
to set the handler for each newly created proxy instance. calling this method will automatically disable caching of classes created by the proxy factory.Sets the default invocation handler. This invocation handler is shared among all the instances of a proxy class unless another is explicitly specified.
-
makeProxyName
private static java.lang.String makeProxyName(java.lang.String classname)
-
make
private ClassFile make() throws CannotCompileException
- Throws:
CannotCompileException
-
checkClassAndSuperName
private void checkClassAndSuperName()
-
allocateClassName
private void allocateClassName()
-
makeSortedMethodList
private void makeSortedMethodList()
-
computeSignature
private void computeSignature(MethodFilter filter)
-
installSignature
private void installSignature(byte[] signature)
-
testBit
private boolean testBit(byte[] signature, int idx)
-
setBit
private void setBit(byte[] signature, int idx)
-
setInterfaces
private static void setInterfaces(ClassFile cf, java.lang.Class<?>[] interfaces, java.lang.Class<?> proxyClass)
-
addClassInitializer
private static void addClassInitializer(ClassFile cf, ConstPool cp, java.lang.String classname, int size, java.util.List<ProxyFactory.Find2MethodsArgs> forwarders) throws CannotCompileException
- Throws:
CannotCompileException
-
callFind2Methods
private static void callFind2Methods(Bytecode code, java.lang.String superMethod, java.lang.String thisMethod, int index, java.lang.String desc, int classVar, int arrayVar)
- Parameters:
thisMethod
- might be null.
-
addSetter
private static void addSetter(java.lang.String classname, ClassFile cf, ConstPool cp) throws CannotCompileException
- Throws:
CannotCompileException
-
addGetter
private static void addGetter(java.lang.String classname, ClassFile cf, ConstPool cp) throws CannotCompileException
- Throws:
CannotCompileException
-
overrideMethods
private int overrideMethods(ClassFile cf, ConstPool cp, java.lang.String className, java.util.List<ProxyFactory.Find2MethodsArgs> forwarders) throws CannotCompileException
- Throws:
CannotCompileException
-
isBridge
private static boolean isBridge(java.lang.reflect.Method m)
-
override
private void override(java.lang.String thisClassname, java.lang.reflect.Method meth, java.lang.String prefix, int index, java.lang.String desc, ClassFile cf, ConstPool cp, java.util.List<ProxyFactory.Find2MethodsArgs> forwarders) throws CannotCompileException
- Throws:
CannotCompileException
-
makeConstructors
private void makeConstructors(java.lang.String thisClassName, ClassFile cf, ConstPool cp, java.lang.String classname) throws CannotCompileException
- Throws:
CannotCompileException
-
makeUniqueName
private static java.lang.String makeUniqueName(java.lang.String name, java.util.List<java.util.Map.Entry<java.lang.String,java.lang.reflect.Method>> sortedMethods)
-
makeUniqueName0
private static boolean makeUniqueName0(java.lang.String name, java.util.Iterator<java.util.Map.Entry<java.lang.String,java.lang.reflect.Method>> it)
-
isVisible
private static boolean isVisible(int mod, java.lang.String from, java.lang.reflect.Member meth)
Returns true if the method is visible from the package.- Parameters:
mod
- the modifiers of the method.
-
getPackageName
private static java.lang.String getPackageName(java.lang.String name)
-
getMethods
private java.util.Map<java.lang.String,java.lang.reflect.Method> getMethods(java.lang.Class<?> superClass, java.lang.Class<?>[] interfaceTypes)
-
getMethods
private void getMethods(java.util.Map<java.lang.String,java.lang.reflect.Method> hash, java.lang.Class<?> clazz, java.util.Set<java.lang.Class<?>> visitedClasses)
-
isDuplicated
private static boolean isDuplicated(int index, java.lang.reflect.Method[] methods)
-
areParametersSame
private static boolean areParametersSame(java.lang.reflect.Method method, java.lang.reflect.Method targetMethod)
-
keyToDesc
private static java.lang.String keyToDesc(java.lang.String key, java.lang.reflect.Method m)
-
makeConstructor
private static MethodInfo makeConstructor(java.lang.String thisClassName, java.lang.reflect.Constructor<?> cons, ConstPool cp, java.lang.Class<?> superClass, boolean doHandlerInit)
-
makeDelegator
private MethodInfo makeDelegator(java.lang.reflect.Method meth, java.lang.String desc, ConstPool cp, java.lang.Class<?> declClass, java.lang.String delegatorName)
-
invokespecialTarget
private java.lang.Class<?> invokespecialTarget(java.lang.Class<?> declClass)
-
makeForwarder
private static MethodInfo makeForwarder(java.lang.String thisClassName, java.lang.reflect.Method meth, java.lang.String desc, ConstPool cp, java.lang.Class<?> declClass, java.lang.String delegatorName, int index, java.util.List<ProxyFactory.Find2MethodsArgs> forwarders)
- Parameters:
delegatorName
- null if the original method is abstract.
-
setThrows
private static void setThrows(MethodInfo minfo, ConstPool cp, java.lang.reflect.Method orig)
-
setThrows
private static void setThrows(MethodInfo minfo, ConstPool cp, java.lang.Class<?>[] exceptions)
-
addLoadParameters
private static int addLoadParameters(Bytecode code, java.lang.Class<?>[] params, int offset)
-
addLoad
private static int addLoad(Bytecode code, int n, java.lang.Class<?> type)
-
addReturn
private static int addReturn(Bytecode code, java.lang.Class<?> type)
-
makeParameterList
private static void makeParameterList(Bytecode code, java.lang.Class<?>[] params)
-
makeWrapper
private static int makeWrapper(Bytecode code, java.lang.Class<?> type, int regno)
-
addUnwrapper
private static void addUnwrapper(Bytecode code, java.lang.Class<?> type)
-
makeWriteReplace
private static MethodInfo makeWriteReplace(ConstPool cp)
-
-