User: user57
Date: 02/04/05 20:53:36
Modified: src/main/org/jboss/proxy/compiler Proxies.java
ProxyCompiler.java ProxyImplementationFactory.java
Runtime.java
Removed: src/main/org/jboss/proxy/compiler ProxyProxy.java
Replaceable.java
Log:
o Removing unused ProxyProxy and Replacable
o Cleaned up formatting, added javadoc so I could understand what was
going on
o Fixed ProxyImplementationFactory.createProxyMethod(), it was not
properly handling long and double parameter arguments and was also
not properly sizing the Object[] passed to invoke.
This should fix bug: [ 527328 ] unexpected error in proxy compiler
o Removed any ProxyProxy specific fluff
Revision Changes Path
1.3 +105 -172 jboss/src/main/org/jboss/proxy/compiler/Proxies.java
Index: Proxies.java
===================================================================
RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/proxy/compiler/Proxies.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Proxies.java 7 Mar 2002 17:03:53 -0000 1.2
+++ Proxies.java 6 Apr 2002 04:53:36 -0000 1.3
@@ -4,23 +4,36 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
+
package org.jboss.proxy.compiler;
-import java.lang.reflect.*;
-import java.io.*;
-import java.util.Hashtable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Member;
-import org.jboss.logging.Logger;
+import java.io.Serializable;
+
+import java.util.Hashtable;
/**
* Routines for converting between strongly-typed interfaces and
* generic InvocationHandler objects.
+ *
+ * @version <tt>$Revision: 1.3 $</tt>
+ * @author Unknown
+ * @author <a href="mailto:[EMAIL PROTECTED]">Jason Dillon</a>
*/
public final class Proxies
{
- private static Logger log = Logger.getLogger(Proxies.class);
+ /**
+ * Disallow creation of Proxyies instances.
+ */
private Proxies()
- {}
+ {
+ super();
+ }
/**
* Create a new target object <em>x</em> which is a proxy for
@@ -54,24 +67,22 @@
* // x1 == x2
* MyInterface x3 = (MyInterface) Proxies.newTarget(i);
* // x1 != x3, but calls to x3 are forwarded via i to x1
- * </code> */
+ * </code>
+ */
public static ProxyTarget newTarget(ClassLoader parent,
InvocationHandler invocationHandler,
Class targetTypes[])
+ throws Exception
{
return Impl.getImpl(targetTypes).newTarget(invocationHandler, parent);
}
- // public static ProxyTarget newTarget(InvocationHandler invocationHandler) {
- // return newTarget(InvocationHandler, InvocationHandler.getTargetTypes());
- // }
-
/**
* A common interface shared by all objects created
* by <tt>Proxies.newTarget</tt>.
*/
public interface ProxyTarget
- extends Serializable
+ extends Serializable
{
/**
* Recover the original InvocationHandler object around which this
@@ -107,13 +118,13 @@
* </code>
*/
public static ProxyInvocationHandler newInvocationHandler(Object target,
- Class targetType)
+ Class targetType)
{
return Impl.getImpl(targetType).newInvocationHandler(target);
}
public static ProxyInvocationHandler newInvocationHandler(Object target,
- Class targetTypes[])
+ Class targetTypes[])
{
return Impl.getImpl(targetTypes).newInvocationHandler(target);
}
@@ -123,7 +134,7 @@
* by <tt>Proxies.newInvocationHandler</tt>.
*/
public interface ProxyInvocationHandler
- extends InvocationHandler, Serializable
+ extends InvocationHandler, Serializable
{
/**
* Recover the original target object around which this
@@ -144,17 +155,6 @@
*/
public static Object getTarget(InvocationHandler invocationHandler)
{
- // if (InvocationHandler instanceof ProxyTargetMemo) {
- // // this kind of InvocationHandler is able to memoize the
ProxyTarget we build
- // ProxyTargetMemo imemo = (ProxyTargetMemo)InvocationHandler;
- // ProxyTarget target = imemo.getProxyTarget();
- // if (target == null) {
- // target = newTarget(imemo);
- // imemo.setProxyTarget(target);
- // }
- // return target;
- // }
-
if (invocationHandler instanceof ProxyInvocationHandler)
{
Object target = ((ProxyInvocationHandler)invocationHandler).getTarget();
@@ -165,7 +165,6 @@
// and fall through...
}
- //return newTarget(invocationHandler);
return null;
}
@@ -173,6 +172,7 @@
* Utility built on top of <tt>newInvocationHandler</tt> to find
* or create a proxy for the given target object.
* It is the inverse of <tt>getTarget</tt>.
+ *
* <p>
* If the target implements <tt>ProxyTarget</tt>, it is a proxy
* for some original InvocationHandler; extract and return that
@@ -181,7 +181,7 @@
* @see #newInvocationHandler
*/
public static InvocationHandler getInvocationHandler(Object target,
- Class targetTypes[])
+ Class targetTypes[])
{
if (target instanceof ProxyTarget)
{
@@ -198,15 +198,15 @@
}
public static InvocationHandler getInvocationHandler(Object target,
- Class targetType)
+ Class targetType)
{
// (should this be optimized?)
if (targetType == null)
{
return getInvocationHandler(target, (Class[])null);
}
- return getInvocationHandler(target, new Class[]
- { targetType });
+
+ return getInvocationHandler(target, new Class[] { targetType });
}
/**
@@ -235,7 +235,7 @@
* ???
*/
static class Impl
- implements Serializable
+ implements Serializable
{
static Hashtable impls = new Hashtable();
@@ -254,13 +254,26 @@
Constructor proxyConstructor;
+ Impl(Class targetTypes[])
+ {
+ this.targetTypes = targetTypes;
+
+ Method methodLists[][] = new Method[targetTypes.length][];
+ for (int i = 0; i < targetTypes.length; i++)
+ {
+ methodLists[i] = checkTargetType(targetTypes[i]);
+ }
+
+ checkSuperclass();
+ this.methods = combineMethodLists(methodLists);
+ }
+
static synchronized Impl getImpl(Class targetType)
{
Impl impl = (Impl) impls.get(targetType);
if (impl == null)
{
- impl = new Impl(new Class[]
- { targetType });
+ impl = new Impl(new Class[] { targetType });
impls.put(targetType, impl);
}
return impl;
@@ -277,8 +290,7 @@
// this requires extra searching, which is not a big deal
for (int i = 0; i < n; ++i)
{
- for (Impl impl = (Impl) impls.get(targetTypes[i]);
- impl != null; impl = impl.more)
+ for (Impl impl = (Impl) impls.get(targetTypes[i]); impl != null; impl =
impl.more)
{
if (sameTypes(targetTypes, impl.targetTypes))
return impl;
@@ -287,8 +299,7 @@
// now link it into the table
targetTypes = copyAndUniquify(targetTypes);
- Impl impl1 = getImpl(new Class[]
- { targetTypes[0] });
+ Impl impl1 = getImpl(new Class[] { targetTypes[0] });
Impl impl = new Impl(targetTypes);
impl.more = impl1.more;
impl1.more = impl;
@@ -326,6 +337,7 @@
++seen2;
}
}
+
if (seen2 == 0)
{
// c does not occur in tt2
@@ -375,27 +387,26 @@
if (targetType.isArray())
{
throw new IllegalArgumentException
- ("cannot subclass an array type: "
- +targetType.getName());
+ ("cannot subclass an array type: " + targetType.getName());
}
+
if (targetType.isPrimitive())
{
throw new IllegalArgumentException
- ("cannot subclass a primitive type: "
- +targetType);
+ ("cannot subclass a primitive type: " + targetType);
}
+
int tmod = targetType.getModifiers();
if (Modifier.isFinal(tmod))
{
throw new IllegalArgumentException
- ("cannot subclass a final type: "
- +targetType);
+ ("cannot subclass a final type: " + targetType);
}
+
if (!Modifier.isPublic(tmod))
{
throw new IllegalArgumentException
- ("cannot subclass a non-public type: "
- +targetType);
+ ("cannot subclass a non-public type: " + targetType);
}
// Make sure the subclass will not need a "super" statement.
@@ -406,11 +417,10 @@
if (superclass.isAssignableFrom(targetType))
{
superclass = targetType;
- } else
- {
+ }
+ else {
throw new IllegalArgumentException
- ("inconsistent superclass: "
- +targetType);
+ ("inconsistent superclass: " + targetType);
}
}
}
@@ -426,6 +436,7 @@
methodList[nm++] = m; // (reuse the method array)
}
}
+
while (nm < methodList.length)
{
methodList[nm++] = null; // (pad the reused method array)
@@ -442,14 +453,15 @@
Constructor c = constructors[i];
int mod = c.getModifiers();
if (Modifier.isPublic(mod)
- && c.getParameterTypes().length == 0)
+ && c.getParameterTypes().length == 0)
{
return; // OK
}
}
+
throw new IllegalArgumentException
- ("cannot subclass without nullary constructor: "
- +superclass.getName());
+ ("cannot subclass without nullary constructor: "
+ +superclass.getName());
}
/**
@@ -458,21 +470,27 @@
*/
static boolean eligibleForInvocationHandler(Method m)
{
-
int mod = m.getModifiers();
+
if (Modifier.isStatic(mod) || Modifier.isFinal(mod))
{
// can't override these
return false;
}
+
if (!Modifier.isAbstract(mod))
{
// do not support methods with "super"
return false;
}
+
return true;
}
-
+
+ /**
+ * Combine the given list of method[]'s into one method[],
+ * removing any methods duplicates.
+ */
static Method[] combineMethodLists(Method methodLists[][])
{
int nm = 0;
@@ -496,10 +514,11 @@
{
continue;
}
+
// make sure the same method hasn't already appeared
for (int k = 0; k < prev; k++)
{
- if (checkSameMethod(m, methods[k]))
+ if (m.equals(methods[k]))
{
continue each_method;
}
@@ -518,97 +537,34 @@
return methodsCopy;
}
- /**
- * Return true if they have the same name and signature
- */
- static boolean checkSameMethod(Method m1, Method m2)
- {
-
- if (!m1.getName().equals(m2.getName()))
- {
- return false;
- }
- Class p1[] = m1.getParameterTypes();
- Class p2[] = m2.getParameterTypes();
- if (p1.length != p2.length)
- {
- return false;
- }
- for (int i = 0; i < p1.length; i++)
- {
- if (p1[i] != p2[i])
- {
- return false;
- }
- }
- return true;
- }
-
Method[] copyMethods()
{
- try
- {
- return (Method[]) methods.clone();
- } catch (IllegalArgumentException ee)
- {
- return new Method[0];
- }
+ return (Method[])methods.clone();
}
+
Class[] copyTargetTypes()
{
- try
- {
- return (Class[]) targetTypes.clone();
- } catch (IllegalArgumentException ee)
- {
- return new Class[0];
- }
- }
-
- Impl(Class targetTypes[])
- {
- this.targetTypes = targetTypes;
-
- Method methodLists[][] = new Method[targetTypes.length][];
- for (int i = 0; i < targetTypes.length; i++)
- {
- methodLists[i] = checkTargetType(targetTypes[i]);
- }
- checkSuperclass();
- this.methods = combineMethodLists(methodLists);
+ return (Class[])targetTypes.clone();
}
-
ProxyTarget newTarget(InvocationHandler invocationHandler,
- ClassLoader parent)
+ ClassLoader parent)
+ throws Exception
{
if (proxyConstructor == null)
{
- try
- {
- makeProxyConstructor( parent ); // do class loader stuff
- } catch (LinkageError ee)
- {
- log.error("unexpected error", ee);
- throw new RuntimeException("unexpected: "+ee);
- }
- }
-
- try
- {
- Object arg[] =
- { invocationHandler };
- return (ProxyTarget) proxyConstructor.newInstance(arg);
- } catch (InvocationTargetException ee)
- {
- throw new RuntimeException("unexpected: "+ee);
- } catch (InstantiationException ee)
- {
- throw new RuntimeException("unexpected: "+ee);
- } catch (IllegalAccessException ee)
- {
- throw new RuntimeException("unexpected: "+ee);
+ // make the proxy constructor
+ ProxyCompiler pc = new ProxyCompiler(parent,
+ superclass,
+ targetTypes,
+ methods);
+
+ Class type[] = { InvocationHandler.class };
+ proxyConstructor = pc.getProxyType().getConstructor(type);
}
+
+ Object args[] = { invocationHandler };
+ return (ProxyTarget)proxyConstructor.newInstance(args);
}
ProxyInvocationHandler newInvocationHandler(final Object target)
@@ -622,6 +578,7 @@
}
proxyString = s;
}
+
return new ProxyInvocationHandler()
{
// (ISSUE: Should this be made subclassable?)
@@ -641,21 +598,24 @@
}
public Object invoke(Object dummy,
- Method method,
- Object values[])
- throws Throwable
+ Method method,
+ Object values[])
+ throws Throwable
{
return Impl.this.invoke(target, method, values);
}
};
}
- // the heart of a ProxyInvocationHandler:
+ /**
+ * The heart of a ProxyInvocationHandler.
+ */
Object invoke(Object target, Member method, Object values[])
- throws Throwable
+ throws Throwable
{
-
- // Note: We will not invoke the method unless we are expecting it.
+ // Note:
+ //
+ // We will not invoke the method unless we are expecting it.
// Thus, we cannot blindly call Method.invoke, but must first
// check our list of allowed methods.
@@ -691,40 +651,13 @@
}
}
- } catch (IllegalAccessException ee)
- {
- throw new IllegalArgumentException("method access "+method);
- } catch (InvocationTargetException ee)
+ }
+ catch (InvocationTargetException e)
{
- Throwable te = ee.getTargetException();
- if (te instanceof Error)
- {
- throw (Error)te;
- }
- if (te instanceof RuntimeException)
- {
- throw (RuntimeException)te;
- }
- throw te;
+ throw e.getTargetException();
}
throw new IllegalArgumentException("method unexpected "+method);
- }
-
- void makeProxyConstructor(ClassLoader parent)
- {
- ProxyCompiler pc = new ProxyCompiler(parent, superclass,
- targetTypes, methods);
- try
- {
- Class type[] =
- { InvocationHandler.class };
- proxyConstructor = pc.getProxyType().getConstructor(type);
- } catch (NoSuchMethodException ee)
- {
- log.error("unexpected error", ee);
- throw new RuntimeException("unexpected: "+ee);
- }
}
}
}
1.3 +83 -66 jboss/src/main/org/jboss/proxy/compiler/ProxyCompiler.java
Index: ProxyCompiler.java
===================================================================
RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/proxy/compiler/ProxyCompiler.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ProxyCompiler.java 7 Mar 2002 17:03:53 -0000 1.2
+++ ProxyCompiler.java 6 Apr 2002 04:53:36 -0000 1.3
@@ -4,75 +4,83 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
+
package org.jboss.proxy.compiler;
-import org.jboss.logging.Logger;
+import java.lang.reflect.Method;
import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.BasicType;
import org.apache.bcel.generic.Type;
+import org.jboss.logging.Logger;
+
/**
* Manages bytecode assembly for dynamic proxy generation.
*
+ * @version <tt>$Revision: 1.3 $</tt>
* @author Unknown
- * @version $Revision: 1.2 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Jason Dillon</a>
*/
public class ProxyCompiler
{
+ /** Class logger. */
+ private static final Logger log = Logger.getLogger(ProxyCompiler.class);
- // Constants -----------------------------------------------------
+ /** The path (if non-null) where generated classes will be dumped for debugging.
*/
+ public final static String CLASS_DUMP_PATH =
+ System.getProperty(ProxyCompiler.class.getName() + ".dumpPath", null);
- public final static String IMPL_SUFFIX = "$Proxy";
-
- // Attributes ----------------------------------------------------
-
- Class superclass;
+ /** The suffix for proxy implementation classnames. */
+ public final static String IMPL_SUFFIX = "$Proxy";
+
+ /** The Runtime classloader for the target proxy. */
Runtime runtime;
+
+ /** The superclass of the target proxy. */
+ Class superclass;
+
+ /** The implementing types of the target proxy. */
Class targetTypes[];
- java.lang.reflect.Method methods[];
+ /** The implementing methods of the target proxy. */
+ Method methods[];
+
+ /** The class of the targret proxy (set by runtime). */
Class proxyType;
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
/**
* Creates a new <code>ProxyCompiler</code> instance.
*
- * @param parent a <code>ClassLoader</code> value
- * @param superclass a <code>Class</code> value
- * @param targetTypes[] a <code>Class</code> value
- * @param methods[] a <code>java.lang.reflect.Method</code> value
+ * @param parent a <code>ClassLoader</code> value
+ * @param superclass a <code>Class</code> value
+ * @param targetTypes a <code>Class</code> value
+ * @param methods a <code>Method</code> value
*/
- ProxyCompiler(ClassLoader parent,
- Class superclass,
- Class targetTypes[],
- java.lang.reflect.Method methods[])
+ public ProxyCompiler(final ClassLoader parent,
+ final Class superclass,
+ final Class targetTypes[],
+ final Method methods[])
+ throws Exception
{
this.superclass = superclass;
this.targetTypes = targetTypes;
this.methods = methods;
- this.runtime = new Runtime( parent );
+ this.runtime = new Runtime(parent);
this.runtime.targetTypes = targetTypes;
this.runtime.methods = methods;
runtime.makeProxyType(this);
}
- // Public --------------------------------------------------------
-
-
- // Package protected ---------------------------------------------
-
- Class getProxyType() {
+ public Class getProxyType() {
return proxyType;
}
- String getProxyClassName() {
+ public String getProxyClassName() {
// Note: We could reasonably put the $Impl class in either
// of two packges: The package of Proxies, or the same package
// as the target type. We choose to put it in same package as
@@ -80,13 +88,8 @@
//
// Note that all infrastructure must be public, because the
// $Impl class is inside a different class loader.
- String tName = targetTypes[0].getName();
- /*
- String dName = Dispatch.class.getName();
- String pkg = dName.substring(0, 1 + dName.lastIndexOf('.'));
- return pkg + tName.substring(1 + tName.lastIndexOf('.')) + IMPL_SUFFIX;
- */
- return tName + IMPL_SUFFIX;
+
+ return targetTypes[0].getName() + IMPL_SUFFIX;
}
/**
@@ -94,17 +97,21 @@
*
* @return a <code>byte[]</code> value
*/
- byte[] getCode() {
+ public byte[] getCode()
+ {
+ boolean trace = log.isTraceEnabled();
final String proxyClassName = getProxyClassName();
final String superClassName = superclass.getName();
- int icount = 1; // don't forget ProxyTarget
+
+ int icount = 1; // don't forget ProxyTarget
for (int i = 0; i < targetTypes.length; i++) {
Class targetType = targetTypes[i];
if (targetType.isInterface()) {
icount++;
}
}
+
String interfaceNames[] = new String[icount];
interfaceNames[0] = Proxies.ProxyTarget.class.getName();
icount = 1;
@@ -112,7 +119,8 @@
Class targetType = targetTypes[i];
if (targetType.isInterface()) {
interfaceNames[icount++] = targetType.getName();
- } else if (!superclass.isAssignableFrom(targetType)) {
+ }
+ else if (!superclass.isAssignableFrom(targetType)) {
throw new RuntimeException("unexpected: " + targetType);
}
}
@@ -123,61 +131,73 @@
Constants.ACC_PUBLIC | Constants.ACC_FINAL,
interfaceNames);
- ProxyImplementationFactory factory = new
ProxyImplementationFactory(superClassName, proxyClassName, cg);
+ ProxyImplementationFactory factory =
+ new ProxyImplementationFactory(superClassName, proxyClassName, cg);
cg.addField(factory.createInvocationHandlerField());
cg.addField(factory.createRuntimeField());
-
-
cg.addMethod(factory.createConstructor());
// ProxyTarget implementation
cg.addMethod(factory.createGetInvocationHandler());
-
cg.addMethod(factory.createGetTargetTypes());
boolean haveToString = false;
+
+ if (trace) log.trace("Creating proxy methods...");
+
// Implement the methods of the target types.
- for (int i = 0; i < methods.length; i++) {
-
- java.lang.reflect.Method m = methods[i];
+ for (int i = 0; i < methods.length; i++)
+ {
+ Method m = methods[i];
+ if (trace) log.trace("Reflected method: " + m);
+
String name = m.getName();
Class rTypeClass = m.getReturnType();
String rTypeName = rTypeClass.getName();
Type rType = Utility.getType(rTypeClass);
Type[] pTypes = Utility.getTypes(m.getParameterTypes());
-
String[] exceptionNames = getNames(m.getExceptionTypes());
if (name.equals("toString") && pTypes.length == 0) {
haveToString = true;
- }
+ }
+
+ org.apache.bcel.classfile.Method proxyMethod =
+ factory.createProxyMethod(name, i, rType, pTypes, exceptionNames);
- cg.addMethod(factory.createProxyMethod(name,
- i,
- rType,
- pTypes,
- exceptionNames));
+ if (trace) log.trace("Created proxy method: " + proxyMethod);
+
+ cg.addMethod(proxyMethod);
}
if (!haveToString) {
cg.addMethod(factory.createToString());
}
- /*
- try {
- cg.getJavaClass().dump("/tmp/" + proxyClassName + ".class");
- } catch ( java.io.IOException e ) {
+ JavaClass jclass = cg.getJavaClass();
+ if (trace) log.trace("Generated Java class: " + jclass);
+
+ // dump the class if we have been configured todo so
+ if (CLASS_DUMP_PATH != null) {
+ try {
+ String filename = CLASS_DUMP_PATH + java.io.File.separator +
proxyClassName + ".class";
+ log.info("Dumping generated proxy class to " + filename);
+ jclass.dump(filename);
+ }
+ catch (Exception e) {
+ log.error("Failed to dump class file", e);
+ }
}
- */
-
- return cg.getJavaClass().getBytes();
+
+ return jclass.getBytes();
}
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
+ /**
+ * Returns an array of class names for the given array
+ * of classes.
+ */
private String[] getNames(Class[] classes) {
String[] names = new String[classes.length];
for ( int i = 0; i < classes.length; i++ ) {
@@ -186,7 +206,4 @@
return names;
}
-
- // Inner classes -------------------------------------------------
-
}
1.2 +134 -112
jboss/src/main/org/jboss/proxy/compiler/ProxyImplementationFactory.java
Index: ProxyImplementationFactory.java
===================================================================
RCS file:
/cvsroot/jboss/jboss/src/main/org/jboss/proxy/compiler/ProxyImplementationFactory.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ProxyImplementationFactory.java 7 Mar 2002 17:03:53 -0000 1.1
+++ ProxyImplementationFactory.java 6 Apr 2002 04:53:36 -0000 1.2
@@ -4,11 +4,13 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
+
package org.jboss.proxy.compiler;
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.classfile.Method;
+
import org.apache.bcel.generic.ArrayType;
import org.apache.bcel.generic.BasicType;
import org.apache.bcel.generic.ConstantPoolGen;
@@ -25,33 +27,31 @@
/**
* Factory to create the bytecode implementation of various methods
- * required by the ProxyCompiler
+ * required by the ProxyCompiler.
*
+ * @version <tt>$Revision: 1.2 $</tt>
* @author <a href="mailto:[EMAIL PROTECTED]">Neale Swinnerton</a>
- * @version $Revision: 1.1 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Jason Dillon</a>
*/
-public class ProxyImplementationFactory {
-
- // Constants -----------------------------------------------------
-
+public class ProxyImplementationFactory
+{
// Class Names
- private final static String RUNTIME_CN = Runtime.class.getName();
- private final static String INVOCATION_HANDLER_CN =
InvocationHandler.class.getName();
- private final static String STRING_BUFFER_CN =
StringBuffer.class.getName();
-
- //Types
- private final static ObjectType RUNTIME_T =
(ObjectType)Utility.getType(Runtime.class);
- private final static ObjectType INVOCATION_HANDLER_T =
(ObjectType)Utility.getType(InvocationHandler.class);
- private final static ArrayType ARRAY_OF_CLASS_T = new
ArrayType("java.lang.Class", 1);
- private final static ObjectType OBJECT_T = new
ObjectType("java.lang.Object");
- private final static ArrayType ARRAY_OF_OBJECT_T = new
ArrayType("java.lang.Object", 1);
- private final static ObjectType STRING_T = new
ObjectType("java.lang.String");
- private final static ObjectType STRING_BUFFER_T = new
ObjectType("java.lang.StringBuffer");
- private final static ObjectType PROXY_TARGET_T = new
ObjectType(Proxies.ProxyTarget.class.getName());
- private final static Type[] INVOKE_ARGS = new
Type[]{INVOCATION_HANDLER_T,
- Type.INT,
-
ARRAY_OF_OBJECT_T};
-
+ private final static String RUNTIME_CN = Runtime.class.getName();
+ private final static String INVOCATION_HANDLER_CN =
InvocationHandler.class.getName();
+ private final static String STRING_BUFFER_CN = StringBuffer.class.getName();
+
+ // Types
+ private final static ObjectType RUNTIME_T =
(ObjectType)Utility.getType(Runtime.class);
+ private final static ObjectType INVOCATION_HANDLER_T =
(ObjectType)Utility.getType(InvocationHandler.class);
+ private final static ArrayType ARRAY_OF_CLASS_T = new
ArrayType("java.lang.Class", 1);
+ private final static ObjectType OBJECT_T = new
ObjectType("java.lang.Object");
+ private final static ArrayType ARRAY_OF_OBJECT_T = new
ArrayType("java.lang.Object", 1);
+ private final static ObjectType STRING_T = new
ObjectType("java.lang.String");
+ private final static ObjectType STRING_BUFFER_T = new
ObjectType("java.lang.StringBuffer");
+ private final static ObjectType PROXY_TARGET_T = new
ObjectType(Proxies.ProxyTarget.class.getName());
+ private final static Type[] INVOKE_ARGS = { INVOCATION_HANDLER_T,
+ Type.INT,
+ ARRAY_OF_OBJECT_T };
// Method Names
private final static String GET_INVOCATION_HANDLER_MN = "getInvocationHandler";
private final static String GET_TARGET_TYPES_MN = "getTargetTypes";
@@ -59,11 +59,11 @@
private final static String APPEND_MN = "append";
private final static String CTOR_MN = "<init>";
- //Field Names
+ // Field Names
private final static String INVOCATION_HANDLER_FN = "invocationHandler";
- // Attributes ----------------------------------------------------
- private static Type PROXY_CLASS_T; // need to assign this in the
ctor
+ /** The proxy class type (assigned in the ctor) */
+ private static Type PROXY_CLASS_T;
private InstructionList il = new InstructionList();
private String proxyClassName;
@@ -71,29 +71,25 @@
private ConstantPoolGen constPool;
private InstructionFactory iFactory;
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
/**
* Creates a new <code>ProxyImplementationFactory</code> instance.
*
- * @param superClassName a <code>String</code> value
- * @param proxyClassName a <code>String</code> value
- * @param cg a <code>ClassGen</code> value
+ * @param superClassName a <code>String</code> value
+ * @param proxyClassName a <code>String</code> value
+ * @param cg a <code>ClassGen</code> value
*/
- public ProxyImplementationFactory(String superClassName, String proxyClassName,
ClassGen cg) {
+ public ProxyImplementationFactory(final String superClassName,
+ final String proxyClassName,
+ final ClassGen cg)
+ {
this.superClassName = superClassName;
this.proxyClassName = proxyClassName;
+
PROXY_CLASS_T = new ObjectType(proxyClassName);
constPool = cg.getConstantPool();
iFactory = new InstructionFactory(cg, constPool);
}
- // Public --------------------------------------------------------
-
-
-
/**
* generate an implementation of
* <pre>
@@ -106,8 +102,8 @@
*
* </pre>
*/
- public Method createGetInvocationHandler() {
-
+ public Method createGetInvocationHandler()
+ {
MethodGen mg = new MethodGen(Constants.ACC_PUBLIC,
INVOCATION_HANDLER_T,
Type.NO_ARGS,
@@ -116,7 +112,8 @@
il.append(iFactory.createLoad(PROXY_CLASS_T, 0));
il.append(iFactory.createGetField(proxyClassName, INVOCATION_HANDLER_FN,
INVOCATION_HANDLER_T));
il.append(iFactory.createReturn(INVOCATION_HANDLER_T));
-
+
+ mg.stripAttributes(true);
mg.setMaxStack();
mg.setMaxLocals();
@@ -138,8 +135,8 @@
* @return the method
*
*/
- public Method createGetTargetTypes() {
-
+ public Method createGetTargetTypes()
+ {
MethodGen mg = new MethodGen(Constants.ACC_PUBLIC,
ARRAY_OF_CLASS_T,
Type.NO_ARGS,
@@ -159,13 +156,11 @@
il.append(iFactory.createReturn(ARRAY_OF_CLASS_T));
+ mg.stripAttributes(true);
mg.setMaxStack(1);
mg.setMaxLocals();
- Method m = mg.getMethod();
-
- il.dispose();
- return m;
+ return getMethodAndTidyup(mg);
}
/**
@@ -174,7 +169,7 @@
*
* <code>
* public String toString() {
- * return "ProxyTarget[" + invocationHnadler + "]";
+ * return "ProxyTarget[" + invocationHandler + "]";
* }
* </code>
*
@@ -183,20 +178,11 @@
* @return the method
*
*/
- public Method createToString() {
-
+ public Method createToString()
+ {
MethodGen mg = new MethodGen(Constants.ACC_PUBLIC, STRING_T,
Type.NO_ARGS,
null, TO_STRING_MN, proxyClassName, il,
constPool);
- /*
- il.append(iFactory.createLoad(PROXY_CLASS_T, 0));
- il.append(iFactory.createInvoke(RUNTIME_CN,
- TO_STRING_MN,
- STRING_T,
- new Type[]{PROXY_TARGET_T},
- Constants.INVOKESTATIC));
- il.append(iFactory.createReturn(STRING_T));
- */
il.append(iFactory.createNew(STRING_BUFFER_T));
il.append(iFactory.createDup(1));
@@ -231,6 +217,7 @@
Constants.INVOKEVIRTUAL));
il.append(iFactory.createReturn(STRING_T));
+ mg.stripAttributes(true);
mg.setMaxStack();
mg.setMaxLocals();
@@ -241,23 +228,24 @@
* generate an implementation of
* <pre>
*
- * <code>
- * public <proxyClassName>(InvocationHandler h) {
+ * <xmp>
+ * public <proxyClassName> (InvocationHandler h) {
* this.invocationHandler = h;
* }
- * </code>
+ * </xmp>
*
* </pre>
*
* @return the method
*
*/
- public Method createConstructor() {
-
+ public Method createConstructor()
+ {
MethodGen mg = new MethodGen(Constants.ACC_PUBLIC,
Type.VOID,
new Type[]{INVOCATION_HANDLER_T},
- null, CTOR_MN,
+ null,
+ CTOR_MN,
proxyClassName,
il,
constPool);
@@ -273,24 +261,25 @@
il.append(iFactory.createPutField(proxyClassName, INVOCATION_HANDLER_FN,
INVOCATION_HANDLER_T));
il.append(iFactory.createReturn(Type.VOID));
+ mg.stripAttributes(true);
mg.setMaxStack();
mg.setMaxLocals();
return getMethodAndTidyup(mg);
-
}
/**
* generate an implementation of...
* <pre>
*
- * <code>
- * public <return type> <method name>(<p0 type> p0, <p1
type> p1, ...)
- * throws e0, e1 ... {
- * return runtme.invoke(invocatioHandler, <method index>,
- * new Object[]{p0, p1, ...)};
+ * <xmp>
+ * public <return type> <method name>(<p0 type> p0, <p1 type> p1, ...)
+ * throws e0, e1 ...
+ * {
+ * return runtme.invoke(invocatioHandler, <method index>,
+ * new Object[]{boxed p0, boxed p1, ...)};
* }
- * </code>
+ * </xmp>
*
* </pre>
*
@@ -300,8 +289,8 @@
int methodNum,
Type rType,
Type[] pTypes,
- String[] exceptionNames) {
-
+ String[] exceptionNames)
+ {
MethodGen mg = new MethodGen(Constants.ACC_PUBLIC,
rType,
pTypes,
@@ -311,48 +300,77 @@
il,
constPool);
- for ( int j = 0; j < exceptionNames.length; j++ ) {
+ for (int j = 0; j < exceptionNames.length; j++) {
mg.addException(exceptionNames[j]);
}
-
+
// implementation of this.invocationHandler.invoke<Type>(InvocationHandler,
i, new Object[]{ ... })
il.append(iFactory.createGetStatic(proxyClassName, Runtime.RUNTIME_FN,
RUNTIME_T));
il.append(iFactory.createLoad(RUNTIME_T, 0));
+
+ // load the first method param (the ih)
il.append(iFactory.createGetField(proxyClassName, INVOCATION_HANDLER_FN,
INVOCATION_HANDLER_T));
+ // load the second method param (the method id)
il.append(new PUSH(constPool, methodNum));
-
- il.append(new PUSH(constPool, 1));
+
+ // create a new array to hold param values
+ il.append(new PUSH(constPool, pTypes.length));
il.append((Instruction)iFactory.createNewArray(OBJECT_T, (short)1));
if (pTypes.length > 0) {
-
+ // the register index
+ int i = 1; // register 0 loaded with runtime ?
+
for (int j = 0; j < pTypes.length; j++) {
Type t = pTypes[j];
+
+ // not sure what this does
il.append(iFactory.createDup(1));
+
+ // load the index of the array element
il.append(new PUSH(constPool, j));
+
+ // box basic types into wrapped versions
if (t instanceof BasicType) {
// do a e.g new Boolean(b)
String wrappedClassName =
Utility.getObjectEquivalentClassName((BasicType)t);
ObjectType wrappedType = new ObjectType(wrappedClassName);
il.append(iFactory.createNew(wrappedType));
+
+ // again, what does this do?
il.append(iFactory.createDup(1));
- il.append(iFactory.createLoad(t, 1 + j));
+
+ // load the parameter value from the register index
+ il.append(iFactory.createLoad(t, i));
il.append(iFactory.createInvoke(wrappedClassName,
CTOR_MN,
Type.VOID,
- new Type[]{t},
+ new Type[] { t },
Constants.INVOKESPECIAL));
+
+ // increment register index for long & double
+ switch (t.getType()) {
+ case Constants.T_DOUBLE: // 7
+ case Constants.T_LONG: // 11
+ i++;
+ }
+
+ // type is now wrapped type
t = wrappedType;
-
- } else {
- il.append(iFactory.createLoad(t, 1 + j));
+ }
+ else {
+ // just load the value in to the register slot
+ il.append(iFactory.createLoad(t, i));
}
+ // increment register index for everything
+ // (makes += 2 for long & double) with above ++
+ i++;
+
+ // store the value into the array
il.append(iFactory.createArrayStore(t));
-
}
-
}
il.append(iFactory.createInvoke(RUNTIME_CN,
@@ -361,10 +379,17 @@
INVOKE_ARGS,
Constants.INVOKEVIRTUAL));
- if (rType instanceof ReferenceType ) {
+ // handle the return value
+ if (rType instanceof ReferenceType) {
il.append(iFactory.createCheckCast((ReferenceType)rType));
- } else if (rType instanceof BasicType) {
- if (rType != Type.VOID) {
+ }
+ else if (rType instanceof BasicType) {
+ if (rType == Type.VOID) {
+ // Chuck away returned value if it's void
+ il.append(iFactory.createPop(1));
+ }
+ else {
+ // unbox the return value of a primitive wrapper...
// we've got an Object and need the equivalent primitive
// do a e.g. (Boolean)obj.booleanValue();
String wrappedClassName =
Utility.getObjectEquivalentClassName((BasicType)rType);
@@ -378,18 +403,12 @@
rType,
Type.NO_ARGS,
Constants.INVOKEVIRTUAL));
-
- } else {
- //Chuck away returned value if it's void
- il.append(iFactory.createPop(1));
- }
+ }
}
-
-
-
il.append(iFactory.createReturn(rType));
+ mg.stripAttributes(true);
mg.setMaxStack();
mg.setMaxLocals();
@@ -409,8 +428,12 @@
* @return the method
*
*/
- public Field createInvocationHandlerField() {
- FieldGen fg = new FieldGen(Constants.ACC_PRIVATE, INVOCATION_HANDLER_T,
INVOCATION_HANDLER_FN, constPool);
+ public Field createInvocationHandlerField()
+ {
+ FieldGen fg = new FieldGen(Constants.ACC_PRIVATE,
+ INVOCATION_HANDLER_T,
+ INVOCATION_HANDLER_FN,
+ constPool);
return fg.getField();
}
@@ -427,25 +450,24 @@
* @return the method
*
*/
- public Field createRuntimeField() {
- FieldGen fg = new FieldGen(Constants.ACC_PUBLIC|Constants.ACC_STATIC,
RUNTIME_T, Runtime.RUNTIME_FN, constPool);
+ public Field createRuntimeField()
+ {
+ FieldGen fg = new FieldGen(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
+ RUNTIME_T,
+ Runtime.RUNTIME_FN,
+ constPool);
return fg.getField();
}
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- private Method getMethodAndTidyup(MethodGen mg) {
-
+ /**
+ * A helper to return the method from MethodGen and clean up the
+ * instruction list.
+ */
+ private Method getMethodAndTidyup(final MethodGen mg)
+ {
Method m = mg.getMethod();
il.dispose();
return m;
}
-
- // Inner classes -------------------------------------------------
-
}
1.3 +60 -55 jboss/src/main/org/jboss/proxy/compiler/Runtime.java
Index: Runtime.java
===================================================================
RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/proxy/compiler/Runtime.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Runtime.java 5 Apr 2002 00:40:24 -0000 1.2
+++ Runtime.java 6 Apr 2002 04:53:36 -0000 1.3
@@ -4,119 +4,124 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
+
package org.jboss.proxy.compiler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+
+import java.io.InputStream;
+
+import java.net.URL;
+
+import org.jboss.util.NestedRuntimeException;
+
/**
* Manages bytecode assembly for dynamic proxy generation.
*
* <p>This is the only data needed at runtime.
*
+ * @version <tt>$Revision: 1.3 $</tt>
* @author Unknown
- * @version $Revision: 1.2 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Jason Dillon</a>
*/
public class Runtime
extends ClassLoader
{
+ /** The field name of the runtime target proxies Runtime object. */
public final static String RUNTIME_FN = "runtime";
+ /**
+ * Construct a new <tt>Runtime</tt>
+ *
+ * @param parent The parent classloader to delegate to.
+ */
+ public Runtime(ClassLoader parent)
+ {
+ super(parent);
+ }
+
// These members are common utilities used by ProxyTarget classes.
// They are all public so they can be linked to from generated code.
// I.e., they are the runtime support for the code compiled below.
- private ClassLoader parent;
-
- public Runtime( ClassLoader parent )
- {
- super( parent );
- this.parent = parent;
- }
Class targetTypes[];
- java.lang.reflect.Method methods[];
- ProxyCompiler compiler; // temporary!
+ Method methods[];
+ ProxyCompiler compiler;// temporary!
public Class[] copyTargetTypes() {
- try {
- return (Class[]) targetTypes.clone();
- } catch (IllegalArgumentException ee) {
- return new Class[0];
- }
+ return (Class[])targetTypes.clone();
}
public Object invoke(InvocationHandler invocationHandler, int methodNum, Object
values[])
- throws Throwable {
- java.lang.reflect.Method method = methods[methodNum];
- if (method.getName().equals( "writeReplace" ))
- {
- return new ProxyProxy( invocationHandler, copyTargetTypes() );
-
- }
-
+ throws Throwable
+ {
return invocationHandler.invoke(null, methods[methodNum], values);
}
-
- // the class loading part
-
- void makeProxyType(ProxyCompiler compiler) {
-
+ void makeProxyType(ProxyCompiler compiler)
+ throws Exception
+ {
this.compiler = compiler; // temporary, for use during loading
-
byte code[] = compiler.getCode();
compiler.proxyType = super.defineClass(compiler.getProxyClassName(), code, 0,
code.length);
super.resolveClass(compiler.proxyType);
+
// set the Foo$Impl.info pointer to myself
- try {
- java.lang.reflect.Field infoField =
compiler.proxyType.getField(RUNTIME_FN);
- infoField.set(null, this);
- } catch (IllegalAccessException ee) {
- throw new RuntimeException("unexpected: "+ee);
- } catch (NoSuchFieldException ee) {
- throw new RuntimeException("unexpected: "+ee);
- }
+ Field field = compiler.proxyType.getField(RUNTIME_FN);
+ field.set(null, this);
+
compiler = null;
}
- ClassLoader getTargetClassLoader() {
- return parent;
- /* for (int i = 0; i < targetTypes.length; i++) {
- ClassLoader cl = targetTypes[i].getClassLoader();
- if (cl != null) {
- return cl;
- }
- }
- return null; */
+ ClassLoader getTargetClassLoader()
+ {
+ return getParent();
}
public synchronized Class loadClass(String name, boolean resolve)
- throws ClassNotFoundException {
- if (name.endsWith("$Proxy")
- && name.equals(compiler.getProxyClassName())) {
+ throws ClassNotFoundException
+ {
+ // isn't this redundant?
+ if (name.endsWith("$Proxy") && name.equals(compiler.getProxyClassName())) {
return compiler.proxyType;
}
+
// delegate to the original class loader
ClassLoader cl = getTargetClassLoader();
if (cl == null) {
return super.findSystemClass(name);
}
+
return cl.loadClass(name);
}
- public java.io.InputStream getResourceAsStream(String name) {
- // delegate to the original class loader
+ /**
+ * Delegate to the original class loader.
+ */
+ public InputStream getResourceAsStream(String name)
+ {
ClassLoader cl = getTargetClassLoader();
+
if (cl == null) {
- return parent.getSystemResourceAsStream(name);
+ return super.getSystemResourceAsStream(name);
}
+
return cl.getResourceAsStream(name);
}
- public java.net.URL getResource(String name) {
- // delegate to the original class loader
+ /**
+ * Delegate to the original class loader.
+ */
+ public URL getResource(String name)
+ {
ClassLoader cl = getTargetClassLoader();
+
if (cl == null) {
- return parent.getSystemResource(name);
+ return super.getSystemResource(name);
}
+
return cl.getResource(name);
}
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development