Permalink
Browse files

Change the way cached fields are read

  • Loading branch information...
1 parent 6691926 commit 50f76053ee9183ec80ff92198923ef1f1ba705b1 @stuartwdouglas stuartwdouglas committed Aug 5, 2011
Showing with 41 additions and 75 deletions.
  1. +41 −75 src/main/java/org/jboss/invocation/proxy/AbstractProxyFactory.java
View
116 src/main/java/org/jboss/invocation/proxy/AbstractProxyFactory.java
@@ -22,6 +22,13 @@
package org.jboss.invocation.proxy;
+import org.jboss.classfilewriter.AccessFlag;
+import org.jboss.classfilewriter.ClassMethod;
+import org.jboss.classfilewriter.code.BranchEnd;
+import org.jboss.classfilewriter.code.CodeAttribute;
+import org.jboss.classfilewriter.code.CodeLocation;
+import org.jboss.classfilewriter.util.DescriptorUtils;
+
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@@ -30,13 +37,7 @@
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Map;
-
-import org.jboss.classfilewriter.AccessFlag;
-import org.jboss.classfilewriter.ClassMethod;
-import org.jboss.classfilewriter.code.BranchEnd;
-import org.jboss.classfilewriter.code.CodeAttribute;
-import org.jboss.classfilewriter.code.CodeLocation;
-import org.jboss.classfilewriter.util.DescriptorUtils;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* A subclass factory specializing in proxy generation.
@@ -55,11 +56,15 @@
private ClassMethod staticConstructor;
+ private volatile Method[] cachedMethods;
+
+ private static final AtomicInteger count = new AtomicInteger();
+
/**
* Construct a new instance.
*
- * @param className the class name
- * @param superClass the superclass
+ * @param className the class name
+ * @param superClass the superclass
* @param classLoader the defining class loader
*/
protected AbstractProxyFactory(String className, Class<T> superClass, ClassLoader classLoader) {
@@ -70,21 +75,21 @@ protected AbstractProxyFactory(String className, Class<T> superClass, ClassLoade
/**
* Construct a new instance.
*
- * @param className the class name
- * @param superClass the superclass
- * @param classLoader the defining class loader
+ * @param className the class name
+ * @param superClass the superclass
+ * @param classLoader the defining class loader
* @param protectionDomain the protection domain
*/
protected AbstractProxyFactory(String className, Class<T> superClass, ClassLoader classLoader,
- ProtectionDomain protectionDomain) {
+ ProtectionDomain protectionDomain) {
super(className, superClass, classLoader, protectionDomain);
staticConstructor = classFile.addMethod(AccessFlag.of(AccessFlag.PUBLIC, AccessFlag.STATIC), "<clinit>", "V");
}
/**
* Construct a new instance.
*
- * @param className the class name
+ * @param className the class name
* @param superClass the superclass
*/
protected AbstractProxyFactory(String className, Class<T> superClass) {
@@ -105,34 +110,23 @@ protected void finalizeStaticConstructor() {
@Override
public void afterClassLoad(Class<?> clazz) {
super.afterClassLoad(clazz);
- AccessController.doPrivileged(new MethodAccessibilitySetter());
+ cachedMethods = AccessController.doPrivileged(new CachedMethodGetter());
}
/**
* Returns all Method objects that are cached by the proxy. These Methods objects are passed to the proxies
* {@link InvocationHandler} when the corresponding proxy action is invoked
- *
+ *
* @return The cached methods
*/
public Method[] getCachedMethods() {
- return getCachedMethods(defineClass());
+ defineClass();
+ return cachedMethods;
}
/**
- * Returns all Method objects that are cached by the proxy. These Methods objects are passed to the proxies
- * {@link InvocationHandler} when the corresponding proxy action is invoked.
- *
- * @throws IllegalArgumentException if the class is not a proxy generated by this factory
- * @return The cached methods
+ * {@inheritDoc}
*/
- public Method[] getCachedMethods(Class<?> clazz) {
- if (!getClassName().equals(clazz.getName())) {
- throw new IllegalArgumentException(clazz + " is not a proxy generated by this ProxyFactory: " + getClassName());
- }
- return AccessController.doPrivileged(new CachedMethodGetter());
- }
-
- /** {@inheritDoc} */
@Override
protected void cleanup() {
staticConstructor = null;
@@ -141,12 +135,12 @@ protected void cleanup() {
/**
* Writes the bytecode to load an instance of Method for the given method onto the stack
- * <p>
+ * <p/>
* If loadMethod has not already been called for the given method then a static field to hold the method is added to the
* class, and code is added to the static constructor to initialize the field to the correct Method.
- *
+ *
* @param methodToLoad the method to load
- * @param method the subclass method to populate
+ * @param method the subclass method to populate
*/
protected void loadMethodIdentifier(Method methodToLoad, ClassMethod method) {
if (!methodIdentifiers.containsKey(methodToLoad)) {
@@ -212,7 +206,7 @@ protected void loadMethodIdentifier(Method methodToLoad, ClassMethod method) {
ca.pop();
BranchEnd gotoEnd = ca.gotoInstruction(); // we have found the method, goto the pointwhere we write it to a static
- // field
+ // field
// throw runtime exception as we could not find the method.
// this will only happen if the proxy isloaded into the wrong classloader
@@ -234,56 +228,27 @@ protected void loadMethodIdentifier(Method methodToLoad, ClassMethod method) {
}
/**
- * {@link PrivilegedAction} that sets all loaded {@link Method} objects to accessibile by calling
- * {@link Method#setAccessible(boolean)} for every generated Method field on the proxy.
- *
- * @see AbstractProxyFactory#loadMethodIdentifier(Method, ClassMethod)
- * @author Stuart Douglas
- *
- */
- private class MethodAccessibilitySetter implements PrivilegedAction<Void> {
-
- @Override
- public Void run() {
- Class<?> clazz = defineClass();
- for (int i = 0; i < identifierCount; ++i) {
- try {
- Field field = clazz.getDeclaredField(METHOD_FIELD_PREFIX + i);
- field.setAccessible(true);
- Method method = (Method) field.get(null);
- method.setAccessible(true);
- } catch (NoSuchFieldException e) {
- throw new RuntimeException(e);
- } catch (IllegalArgumentException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
- return null;
- }
- }
-
- /**
* {@link PrivilegedAction} that loads all cached {@link Method} objects from a proxy class
- *
- * @see AbstractProxyFactory#loadMethodIdentifier(Method, ClassMethod)
+ *
* @author Stuart Douglas
- *
+ * @see AbstractProxyFactory#loadMethodIdentifier(Method, ClassMethod)
*/
private class CachedMethodGetter implements PrivilegedAction<Method[]> {
@Override
public Method[] run() {
+ System.out.println("COUNT: " + count.incrementAndGet());
@jaikiran
jaikiran Aug 6, 2011

Looks like an oversight

Method[] methods = new Method[identifierCount];
Class<?> clazz = defineClass();
- for (int i = 0; i < identifierCount; ++i) {
+ int i = 0;
+ for (Field field : clazz.getDeclaredFields()) {
try {
- Field field = clazz.getDeclaredField(METHOD_FIELD_PREFIX + i);
- field.setAccessible(true);
- methods[i] = (Method) field.get(null);
- } catch (NoSuchFieldException e) {
- throw new RuntimeException(e);
+ if (field.getName().startsWith(METHOD_FIELD_PREFIX)) {
+ field.setAccessible(true);
+ methods[i] = (Method) field.get(null);
+ methods[i].setAccessible(true);
+ i++;
+ }
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
@@ -292,6 +257,7 @@ public Void run() {
}
return methods;
}
- }
+ }
}
+

0 comments on commit 50f7605

Please sign in to comment.