Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Change the way cached fields are read

  • Loading branch information...
commit 50f76053ee9183ec80ff92198923ef1f1ba705b1 1 parent 6691926
Stuart Douglas authored August 05, 2011
116  src/main/java/org/jboss/invocation/proxy/AbstractProxyFactory.java
@@ -22,6 +22,13 @@
22 22
 
23 23
 package org.jboss.invocation.proxy;
24 24
 
  25
+import org.jboss.classfilewriter.AccessFlag;
  26
+import org.jboss.classfilewriter.ClassMethod;
  27
+import org.jboss.classfilewriter.code.BranchEnd;
  28
+import org.jboss.classfilewriter.code.CodeAttribute;
  29
+import org.jboss.classfilewriter.code.CodeLocation;
  30
+import org.jboss.classfilewriter.util.DescriptorUtils;
  31
+
25 32
 import java.lang.reflect.Field;
26 33
 import java.lang.reflect.InvocationHandler;
27 34
 import java.lang.reflect.Method;
@@ -30,13 +37,7 @@
30 37
 import java.security.ProtectionDomain;
31 38
 import java.util.HashMap;
32 39
 import java.util.Map;
33  
-
34  
-import org.jboss.classfilewriter.AccessFlag;
35  
-import org.jboss.classfilewriter.ClassMethod;
36  
-import org.jboss.classfilewriter.code.BranchEnd;
37  
-import org.jboss.classfilewriter.code.CodeAttribute;
38  
-import org.jboss.classfilewriter.code.CodeLocation;
39  
-import org.jboss.classfilewriter.util.DescriptorUtils;
  40
+import java.util.concurrent.atomic.AtomicInteger;
40 41
 
41 42
 /**
42 43
  * A subclass factory specializing in proxy generation.
@@ -55,11 +56,15 @@
55 56
 
56 57
     private ClassMethod staticConstructor;
57 58
 
  59
+    private volatile Method[] cachedMethods;
  60
+
  61
+    private static final AtomicInteger count = new AtomicInteger();
  62
+
58 63
     /**
59 64
      * Construct a new instance.
60 65
      *
61  
-     * @param className the class name
62  
-     * @param superClass the superclass
  66
+     * @param className   the class name
  67
+     * @param superClass  the superclass
63 68
      * @param classLoader the defining class loader
64 69
      */
65 70
     protected AbstractProxyFactory(String className, Class<T> superClass, ClassLoader classLoader) {
@@ -70,13 +75,13 @@ protected AbstractProxyFactory(String className, Class<T> superClass, ClassLoade
70 75
     /**
71 76
      * Construct a new instance.
72 77
      *
73  
-     * @param className the class name
74  
-     * @param superClass the superclass
75  
-     * @param classLoader the defining class loader
  78
+     * @param className        the class name
  79
+     * @param superClass       the superclass
  80
+     * @param classLoader      the defining class loader
76 81
      * @param protectionDomain the protection domain
77 82
      */
78 83
     protected AbstractProxyFactory(String className, Class<T> superClass, ClassLoader classLoader,
79  
-            ProtectionDomain protectionDomain) {
  84
+                                   ProtectionDomain protectionDomain) {
80 85
         super(className, superClass, classLoader, protectionDomain);
81 86
         staticConstructor = classFile.addMethod(AccessFlag.of(AccessFlag.PUBLIC, AccessFlag.STATIC), "<clinit>", "V");
82 87
     }
@@ -84,7 +89,7 @@ protected AbstractProxyFactory(String className, Class<T> superClass, ClassLoade
84 89
     /**
85 90
      * Construct a new instance.
86 91
      *
87  
-     * @param className the class name
  92
+     * @param className  the class name
88 93
      * @param superClass the superclass
89 94
      */
90 95
     protected AbstractProxyFactory(String className, Class<T> superClass) {
@@ -105,34 +110,23 @@ protected void finalizeStaticConstructor() {
105 110
     @Override
106 111
     public void afterClassLoad(Class<?> clazz) {
107 112
         super.afterClassLoad(clazz);
108  
-        AccessController.doPrivileged(new MethodAccessibilitySetter());
  113
+        cachedMethods = AccessController.doPrivileged(new CachedMethodGetter());
109 114
     }
110 115
 
111 116
     /**
112 117
      * Returns all Method objects that are cached by the proxy. These Methods objects are passed to the proxies
113 118
      * {@link InvocationHandler} when the corresponding proxy action is invoked
114  
-     * 
  119
+     *
115 120
      * @return The cached methods
116 121
      */
117 122
     public Method[] getCachedMethods() {
118  
-        return getCachedMethods(defineClass());
  123
+        defineClass();
  124
+        return cachedMethods;
119 125
     }
120 126
 
121 127
     /**
122  
-     * Returns all Method objects that are cached by the proxy. These Methods objects are passed to the proxies
123  
-     * {@link InvocationHandler} when the corresponding proxy action is invoked.
124  
-     * 
125  
-     * @throws IllegalArgumentException if the class is not a proxy generated by this factory
126  
-     * @return The cached methods
  128
+     * {@inheritDoc}
127 129
      */
128  
-    public Method[] getCachedMethods(Class<?> clazz) {
129  
-        if (!getClassName().equals(clazz.getName())) {
130  
-            throw new IllegalArgumentException(clazz + " is not a proxy generated by this ProxyFactory: " + getClassName());
131  
-        }
132  
-        return AccessController.doPrivileged(new CachedMethodGetter());
133  
-    }
134  
-
135  
-    /** {@inheritDoc} */
136 130
     @Override
137 131
     protected void cleanup() {
138 132
         staticConstructor = null;
@@ -141,12 +135,12 @@ protected void cleanup() {
141 135
 
142 136
     /**
143 137
      * Writes the bytecode to load an instance of Method for the given method onto the stack
144  
-     * <p>
  138
+     * <p/>
145 139
      * If loadMethod has not already been called for the given method then a static field to hold the method is added to the
146 140
      * class, and code is added to the static constructor to initialize the field to the correct Method.
147  
-     * 
  141
+     *
148 142
      * @param methodToLoad the method to load
149  
-     * @param method the subclass method to populate
  143
+     * @param method       the subclass method to populate
150 144
      */
151 145
     protected void loadMethodIdentifier(Method methodToLoad, ClassMethod method) {
152 146
         if (!methodIdentifiers.containsKey(methodToLoad)) {
@@ -212,7 +206,7 @@ protected void loadMethodIdentifier(Method methodToLoad, ClassMethod method) {
212 206
             ca.pop();
213 207
 
214 208
             BranchEnd gotoEnd = ca.gotoInstruction(); // we have found the method, goto the pointwhere we write it to a static
215  
-                                                      // field
  209
+            // field
216 210
 
217 211
             // throw runtime exception as we could not find the method.
218 212
             // this will only happen if the proxy isloaded into the wrong classloader
@@ -234,56 +228,27 @@ protected void loadMethodIdentifier(Method methodToLoad, ClassMethod method) {
234 228
     }
235 229
 
236 230
     /**
237  
-     * {@link PrivilegedAction} that sets all loaded {@link Method} objects to accessibile by calling
238  
-     * {@link Method#setAccessible(boolean)} for every generated Method field on the proxy.
239  
-     * 
240  
-     * @see AbstractProxyFactory#loadMethodIdentifier(Method, ClassMethod)
241  
-     * @author Stuart Douglas
242  
-     * 
243  
-     */
244  
-    private class MethodAccessibilitySetter implements PrivilegedAction<Void> {
245  
-
246  
-        @Override
247  
-        public Void run() {
248  
-            Class<?> clazz = defineClass();
249  
-            for (int i = 0; i < identifierCount; ++i) {
250  
-                try {
251  
-                    Field field = clazz.getDeclaredField(METHOD_FIELD_PREFIX + i);
252  
-                    field.setAccessible(true);
253  
-                    Method method = (Method) field.get(null);
254  
-                    method.setAccessible(true);
255  
-                } catch (NoSuchFieldException e) {
256  
-                    throw new RuntimeException(e);
257  
-                } catch (IllegalArgumentException e) {
258  
-                    throw new RuntimeException(e);
259  
-                } catch (IllegalAccessException e) {
260  
-                    throw new RuntimeException(e);
261  
-                }
262  
-            }
263  
-            return null;
264  
-        }
265  
-    }
266  
-
267  
-    /**
268 231
      * {@link PrivilegedAction} that loads all cached {@link Method} objects from a proxy class
269  
-     * 
270  
-     * @see AbstractProxyFactory#loadMethodIdentifier(Method, ClassMethod)
  232
+     *
271 233
      * @author Stuart Douglas
272  
-     * 
  234
+     * @see AbstractProxyFactory#loadMethodIdentifier(Method, ClassMethod)
273 235
      */
274 236
     private class CachedMethodGetter implements PrivilegedAction<Method[]> {
275 237
 
276 238
         @Override
277 239
         public Method[] run() {
  240
+            System.out.println("COUNT: " + count.incrementAndGet());
278 241
             Method[] methods = new Method[identifierCount];
279 242
             Class<?> clazz = defineClass();
280  
-            for (int i = 0; i < identifierCount; ++i) {
  243
+            int i = 0;
  244
+            for (Field field : clazz.getDeclaredFields()) {
281 245
                 try {
282  
-                    Field field = clazz.getDeclaredField(METHOD_FIELD_PREFIX + i);
283  
-                    field.setAccessible(true);
284  
-                    methods[i] = (Method) field.get(null);
285  
-                } catch (NoSuchFieldException e) {
286  
-                    throw new RuntimeException(e);
  246
+                    if (field.getName().startsWith(METHOD_FIELD_PREFIX)) {
  247
+                        field.setAccessible(true);
  248
+                        methods[i] = (Method) field.get(null);
  249
+                        methods[i].setAccessible(true);
  250
+                        i++;
  251
+                    }
287 252
                 } catch (IllegalArgumentException e) {
288 253
                     throw new RuntimeException(e);
289 254
                 } catch (IllegalAccessException e) {
@@ -292,6 +257,7 @@ public Void run() {
292 257
             }
293 258
             return methods;
294 259
         }
295  
-    }
296 260
 
  261
+    }
297 262
 }
  263
+

0 notes on commit 50f7605

Please sign in to comment.
Something went wrong with that request. Please try again.