|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.curjent.impl.agent.Factory
org.curjent.impl.agent.ProxyFactory
final class ProxyFactory
Factory for generating and creating an agent's proxy. Uses TypeInfo
to evaluate and gather bytecode generation information based on the agent's
interfaces and task type. Delegates message class generation to
MessageFactory
. Caches generated classes using ProxyCache
.
Agent.newInstance(AgentLoader, Class[], AgentTasks, Class)
Field Summary | |
---|---|
private static ProxyCache |
cache
Caches the generated proxies' constructors. |
private static String |
CALL_INFO_ARRAY_DESCRIPTOR
Internal JVM descriptor for array of CallInfo . |
private static String |
CALL_INFO_DESCRIPTOR
Internal JVM descriptor for CallInfo . |
private ClassLoader |
classLoader
ClassLoader from loader . |
private static Class<?>[] |
CONSTRUCTOR_PARAMS
Proxy constructor's parameter types. |
private static String |
CONTROLLER_DESCRIPTOR
Internal JVM descriptor for Controller . |
private static String |
CONTROLLER_INTERNAL
Internal JVM name for Controller . |
private static String |
DISPATCH_DESCRIPTOR
Internal JVM descriptor for the void dispatch(Message) and send methods. |
private static String |
GET_CONTEXT_DESCRIPTOR
Internal JVM descriptor for the MessageCall getCall() method. |
private static String |
INIT_DESCRIPTOR
Internal JVM descriptor for the generated proxy's constructor. |
private static String |
INSIDER_INTERNAL
Internal JVM name for Insider . |
private String[] |
interfaceNames
Names of the agent's interfaces. |
private Class<?>[] |
interfaces
Agent's interfaces. |
private AgentLoader |
loader
Creates and loads generated classes. |
private static String |
MESSAGE_CALL_DESCRIPTOR
Internal JVM descriptor for MessageCall . |
private static String |
MESSAGE_DESCRIPTOR
Internal JVM descriptor for Message . |
private static String |
MESSAGE_FUTURE_INIT_DESCRIPTOR
Internal JVM descriptor for the MessageFuture 's constructor. |
private static String |
MESSAGE_FUTURE_INTERNAL
Internal JVM name for MessageFuture . |
private static String |
MESSAGE_INIT_DESCRIPTOR
Internal JVM descriptor for the generated message constructors. |
private String |
proxyKey
Unique caching key for this proxy. |
private static String |
SUPER_INIT_DESCRIPTOR
Internal JVM descriptor for the base Proxy constructor. |
private static String |
SUPER_PROXY_INTERNAL
Internal JVM name for Proxy . |
private String |
taskName
Name of the task type. |
private AgentTasks |
tasks
Source of tasks for the agent. |
private Class<?> |
taskType
Agent's task type. |
private TypeInfo |
typeInfo
Information for bytecode generation. |
Constructor Summary | |
---|---|
ProxyFactory(AgentLoader loader,
ClassLoader classLoader,
Class<?>[] interfaces,
AgentTasks tasks,
Class<?> taskType)
Initializes the factory. |
Method Summary | |
---|---|
private void |
addConstructor(ClassWriter cw)
Generates the proxy's constructor. |
private void |
addMethod(ClassWriter cw,
MethodInfo method,
int index)
Generates a method for the proxy. |
private ProxyInfo |
createClass()
Generates and creates the proxy and message classes. |
private AgentException |
evaluate(Throwable exception)
Wraps a checked exception as the cause of an AgentException . |
private static String[] |
getNames(Class<?>[] types)
Returns the class names for the given types . |
(package private) Object |
newInstance()
Returns a new proxy. |
private ClassWriter |
startClass()
Creates the ASM ClassWriter and starts generation of the
proxy class. |
private void |
validateArguments()
Validates the arguments to Agent.newInstance() . |
Methods inherited from class org.curjent.impl.agent.Factory |
---|
save |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
private static final ProxyCache cache
private static final String SUPER_PROXY_INTERNAL
Proxy
.
private static final String CONTROLLER_INTERNAL
Controller
.
private static final String CONTROLLER_DESCRIPTOR
Controller
.
private static final String MESSAGE_DESCRIPTOR
Message
.
private static final String MESSAGE_CALL_DESCRIPTOR
MessageCall
.
private static final String CALL_INFO_DESCRIPTOR
CallInfo
.
private static final String CALL_INFO_ARRAY_DESCRIPTOR
CallInfo
.
private static final String INSIDER_INTERNAL
Insider
.
private static final String MESSAGE_FUTURE_INTERNAL
MessageFuture
.
private static final Class<?>[] CONSTRUCTOR_PARAMS
private static final String INIT_DESCRIPTOR
private static final String SUPER_INIT_DESCRIPTOR
Proxy
constructor.
private static final String MESSAGE_INIT_DESCRIPTOR
private static final String DISPATCH_DESCRIPTOR
void dispatch(Message)
and send
methods.
private static final String GET_CONTEXT_DESCRIPTOR
MessageCall getCall()
method.
private static final String MESSAGE_FUTURE_INIT_DESCRIPTOR
MessageFuture
's constructor.
private final AgentLoader loader
private final ClassLoader classLoader
ClassLoader
from loader
. Used by this class for
caching purposes and to verify accessibility of agent's interfaces and
task type.
AgentLoader.getClassLoader()
private final Class<?>[] interfaces
private final String[] interfaceNames
Class.getName()
private final AgentTasks tasks
private final Class<?> taskType
private final String taskName
Class.getName()
private final String proxyKey
ProxyCache
private TypeInfo typeInfo
Constructor Detail |
---|
ProxyFactory(AgentLoader loader, ClassLoader classLoader, Class<?>[] interfaces, AgentTasks tasks, Class<?> taskType)
Method Detail |
---|
Object newInstance()
IllegalArgumentException
- Invalid or inaccessible argument.
AgentException
- Unexpected checked exception wrapped as the cause.private ProxyInfo createClass() throws Exception
The proxy's constructor is cached explicitly, but the message classes are not. In fact, the message classes are generated and created but not otherwise directly referenced. The JVM and class loader resolve dependencies between classes, and the message classes are not eligible for garbage collection until all classes for the class loader, and the class loader itself, are eligible.
Exception
MessageFactory
,
AgentLoader.defineClass(String, byte[])
private ClassWriter startClass()
ClassWriter
and starts generation of the
proxy class.
public final class {proxyName} extends Proxy implements {interfaceNames} { private final CallInfo call{i}; ... }
private void addConstructor(ClassWriter cw)
public {proxyName}(Controller controller, CallInfo[] calls) { super(controller); call{i} = calls[{i}]; }
private void addMethod(ClassWriter cw, MethodInfo method, int index)
public {returnType} {methodName}({paramType} paramName, ...) throws {exceptionType}, ... { {messageType} message = new {messageType}(call{index}); synchronized (message) { message.{paramName} = {paramName}; } // for each parameter try { controller.send(message); } // asynchronous, void try { controller.send(message); return new MessageFuture(message); } // asynchronous, future try { controller.send(message); return message.getCall(); } // asynchronous, agent call try { controller.send(message); message.await(); } // synchronous, void try { controller.dispatch(message); message.await(); } // synchronous, void, reentrant try { controller.send(message); message.await(); // synchronous, non-void try { controller.dispatch(message); message.await(); // synchronous, non-void, reentrant synchronized (message) { return message.result; } } catch ({exceptionType} e) { throw e; } // for each checked exception type catch (Throwable e) { throw Insider.evaluate(e); } }
private static String[] getNames(Class<?>[] types)
types
.
private AgentException evaluate(Throwable exception)
AgentException
.
Rethrows RuntimeException
and Error
exceptions.
Extracts the root cause of a reflection InvocationTargetException
.
private void validateArguments()
Agent.newInstance()
. Checks for
illegal arguments and verifies the interfaces and task type are
accessible by the given class loader.
Insider.newInstance()
performs a basic validation of
arguments sufficient for previously created and cached proxies. This
method is only used before creating a new proxy. It performs more
extensive and more expensive validations.
Agent.newInstance(AgentLoader, Class[], AgentTasks, Class)
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |