You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mb...@apache.org on 2013/04/05 20:38:39 UTC

svn commit: r1465091 - in /commons/sandbox/weaver/trunk: ./ example/ example/src/main/java/org/apache/commons/weaver/privilizer/example/ example/src/test/java/org/apache/commons/weaver/privilizer/example/ example/src/test/resources/ modules/privilizer/...

Author: mbenson
Date: Fri Apr  5 18:38:39 2013
New Revision: 1465091

URL: http://svn.apache.org/r1465091
Log:
reintegrate fields branch

Added:
    commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/utils/Assistant.java
      - copied unchanged from r1465080, commons/sandbox/weaver/branches/fields/processor/src/main/java/org/apache/commons/weaver/utils/Assistant.java
Modified:
    commons/sandbox/weaver/trunk/   (props changed)
    commons/sandbox/weaver/trunk/example/pom.xml
    commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java
    commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java
    commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java
    commons/sandbox/weaver/trunk/example/src/test/resources/java.policy
    commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml
    commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java
    commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java
    commons/sandbox/weaver/trunk/pom.xml
    commons/sandbox/weaver/trunk/processor/pom.xml

Propchange: commons/sandbox/weaver/trunk/
------------------------------------------------------------------------------
  Merged /commons/sandbox/weaver/branches/fields:r1460191-1460199,1460201-1465080

Modified: commons/sandbox/weaver/trunk/example/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/pom.xml?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/pom.xml (original)
+++ commons/sandbox/weaver/trunk/example/pom.xml Fri Apr  5 18:38:39 2013
@@ -27,12 +27,18 @@
   <name>Commons Weaver Privilizer Example</name>
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <privilizer.policy>ON_INIT</privilizer.policy>
   </properties>
   <dependencies>
     <dependency>
       <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
       <artifactId>commons-weaver-privilizer-api</artifactId>
       <version>${project.version}</version>
+      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
@@ -49,7 +55,7 @@
         <configuration>
           <weaverConfig>
             <privilizer.accessLevel>PACKAGE</privilizer.accessLevel>
-            <privilizer.policy>ON_INIT</privilizer.policy>
+            <privilizer.policy>${privilizer.policy}</privilizer.policy>
           </weaverConfig>
         </configuration>
         <executions>
@@ -104,6 +110,11 @@
             </lifecycleMappingMetadata>
           </configuration>
         </plugin>
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>exec-maven-plugin</artifactId>
+          <version>1.2.1</version>
+        </plugin>
       </plugins>
     </pluginManagement>
   </build>

Modified: commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java (original)
+++ commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java Fri Apr  5 18:38:39 2013
@@ -21,6 +21,10 @@ import org.apache.commons.weaver.privili
 @Privilizing({ @CallTo(Utils.class), @CallTo(value = Utils.More.class, methods = "getProperty") })
 public class UsingBlueprints {
 
+    public String utilsReadPublicConstant() {
+        return Utils.readPublicConstant();
+    }
+
     public String utilsGetProperty() {
         return Utils.getProperty();
     }
@@ -40,7 +44,4 @@ public class UsingBlueprints {
     public String moreGetTopStackElementClassName() {
         return Utils.More.getTopStackElementClassName();
     }
-
-    private void foo() {
-    }
 }

Modified: commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java (original)
+++ commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java Fri Apr  5 18:38:39 2013
@@ -32,6 +32,12 @@ public class Utils {
     private Utils() {
     }
 
+    public static final String FOO = "foo".intern();
+
+    public static String readPublicConstant() {
+        return FOO;
+    }
+
     public static String getProperty() {
         return getProperty("foo");
     }

Modified: commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java (original)
+++ commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java Fri Apr  5 18:38:39 2013
@@ -42,6 +42,11 @@ public class UsingBlueprintsTest {
     }
 
     @Test
+    public void testUtilsReadPublicConstant() {
+        assertEquals(Utils.FOO, usingBlueprints.utilsReadPublicConstant());
+    }
+
+    @Test
     public void testUtilsGetProperty() {
         assertEquals("foo-value", usingBlueprints.utilsGetProperty());
     }

Modified: commons/sandbox/weaver/trunk/example/src/test/resources/java.policy
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/src/test/resources/java.policy?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/src/test/resources/java.policy (original)
+++ commons/sandbox/weaver/trunk/example/src/test/resources/java.policy Fri Apr  5 18:38:39 2013
@@ -42,4 +42,5 @@ grant codeBase "file:${user.dir}/target/
   permission java.util.PropertyPermission "foo", "read";
   permission java.util.PropertyPermission "bar", "read";
   permission java.util.PropertyPermission "baz", "read";
+  #permission java.lang.RuntimePermission "getClassLoader";
 };

Modified: commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml (original)
+++ commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml Fri Apr  5 18:38:39 2013
@@ -47,7 +47,6 @@
     <dependency>
       <groupId>org.javassist</groupId>
       <artifactId>javassist</artifactId>
-      <version>3.17.1-GA</version>
     </dependency>
   </dependencies>
 

Modified: commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java (original)
+++ commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java Fri Apr  5 18:38:39 2013
@@ -41,17 +41,27 @@ import javassist.CtPrimitiveType;
 import javassist.NotFoundException;
 import javassist.bytecode.Descriptor;
 import javassist.expr.ExprEditor;
+import javassist.expr.FieldAccess;
 import javassist.expr.MethodCall;
 
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.mutable.MutableBoolean;
 import org.apache.commons.lang3.text.StrBuilder;
 import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+import org.apache.commons.weaver.utils.Assistant;
 import org.apache.commons.weaver.utils.Body;
 
 /**
- * Handles weaving of methods annotated with {@link Privileged}.
+ * Handles:
+ * <ul>
+ * <li>weaving of methods annotated with {@link Privileged}</li>
+ * <li>weaving of blueprint annotation methods</li>
+ * </ul>
+ * 
+ * @see Privileged
+ * @see Privilizing
  */
 public abstract class Privilizer {
     public interface ClassFileWriter {
@@ -150,6 +160,8 @@ public abstract class Privilizer {
         return result;
     }
 
+    private final Assistant assistant;
+
     public Privilizer(ClassPool classPool) {
         this(Policy.DYNAMIC, classPool);
     }
@@ -157,10 +169,12 @@ public abstract class Privilizer {
     public Privilizer(Policy policy, ClassPool classPool) {
         this.policy = Validate.notNull(policy, "policy");
         this.classPool = Validate.notNull(classPool, "classPool");
+        this.assistant = new Assistant(classPool, "__privilizer_");
     }
 
     /**
-     * Weave all {@link Privileged} methods found.
+     * Weave the specified class. Handles all {@link Privileged} methods as well as calls described by
+     * {@code privilizing}.
      * 
      * @param privilizing
      * 
@@ -170,7 +184,7 @@ public abstract class Privilizer {
      * @throws ClassNotFoundException
      */
     public boolean weaveClass(Class<?> clazz, Privilizing privilizing) throws NotFoundException, IOException,
-        CannotCompileException, ClassNotFoundException, IllegalAccessException {
+            CannotCompileException, ClassNotFoundException, IllegalAccessException {
         return weave(classPool.get(clazz.getName()), privilizing);
     }
 
@@ -186,7 +200,7 @@ public abstract class Privilizer {
      * @throws ClassNotFoundException
      */
     private boolean weave(CtClass type, Privilizing privilizing) throws NotFoundException, IOException,
-        CannotCompileException, ClassNotFoundException, IllegalAccessException {
+            CannotCompileException, ClassNotFoundException, IllegalAccessException {
         reportSettings();
         final String policyName = generateName(POLICY_NAME);
         final String policyValue = toString(type.getAttribute(policyName));
@@ -205,7 +219,8 @@ public abstract class Privilizer {
             }
 
             if (policy == Policy.ON_INIT) {
-                debug("Initializing field %s to %s", policy.condition, HAS_SECURITY_MANAGER_CONDITION);
+                debug("Initializing field %s.%s to %s", type.getName(), policy.condition,
+                        HAS_SECURITY_MANAGER_CONDITION);
 
                 CtField securityManager = new CtField(CtClass.booleanType, policy.condition, type);
                 securityManager.setModifiers(Modifier.STATIC | Modifier.PRIVATE | Modifier.FINAL);
@@ -227,13 +242,13 @@ public abstract class Privilizer {
     }
 
     private boolean privilizeBlueprints(CtClass type, Privilizing annotation) throws CannotCompileException,
-        ClassNotFoundException, NotFoundException, IOException, IllegalAccessException {
+            ClassNotFoundException, NotFoundException, IOException, IllegalAccessException {
         boolean result = false;
         if (annotation != null) {
             final CallTo[] blueprintCalls = annotation.value();
             for (CallTo callTo : blueprintCalls) {
                 Validate.isTrue(!callTo.value().equals(type.getName()),
-                    "Type %s cannot use itself as a privilizer blueprint", callTo.value());
+                        "Type %s cannot use itself as a privilizer blueprint", callTo.value());
             }
             for (CtMethod method : type.getDeclaredMethods()) {
                 result = privilizeBlueprints(type, method, blueprintCalls) | result;
@@ -243,11 +258,11 @@ public abstract class Privilizer {
     }
 
     private boolean privilizeBlueprints(final CtClass type, final CtMethod method, final CallTo[] blueprintCalls)
-        throws CannotCompileException, ClassNotFoundException, NotFoundException, IOException, IllegalAccessException {
-        boolean result = false;
+            throws CannotCompileException, ClassNotFoundException, NotFoundException, IOException,
+            IllegalAccessException {
+        final MutableBoolean result = new MutableBoolean();
 
-        final List<CtMethod> blueprints = new ArrayList<CtMethod>();
-        class CollectBlueprints extends ExprEditor {
+        method.instrument(new ExprEditor() {
             @Override
             public void edit(MethodCall call) throws CannotCompileException {
                 super.edit(call);
@@ -257,49 +272,63 @@ public abstract class Privilizer {
                     if (!Modifier.isStatic(called.getModifiers())) {
                         return;
                     }
-                } catch (NotFoundException e) {
+                }
+                catch (NotFoundException e) {
                     return;
                 }
+                boolean found = false;
                 for (CallTo callTo : blueprintCalls) {
                     final Class<?> owner = callTo.value();
                     if (owner.getName().equals(call.getClassName())) {
-                        if (callTo.methods().length > 0) {
-                            boolean found = false;
-                            for (String m : callTo.methods()) {
-                                found = StringUtils.equals(call.getMethodName(), m);
-                                if (found) {
-                                    break;
-                                }
-                            }
-                            if (!found) {
-                                continue;
+                        if (callTo.methods().length == 0) {
+                            found = true;
+                            break;
+                        }
+                        for (String m : callTo.methods()) {
+                            found = StringUtils.equals(call.getMethodName(), m);
+                            if (found) {
+                                break;
                             }
                         }
-                        blueprints.add(called);
-                        break;
                     }
                 }
-            }
-        }
-        method.instrument(new CollectBlueprints());
+                if (found) {
+                    final String name = importedMethodName(called);
 
-        for (CtMethod blueprint : blueprints) {
-            final String name = importedMethodName(blueprint);
-
-            CtMethod copy = copyBlueprintTo(type, name, blueprint, blueprintCalls);
-            method.instrument(redirect(blueprint, copy));
-            result = true;
-        }
-        return result;
+                    CtMethod copy;
+                    try {
+                        copy = copyBlueprintTo(type, name, called, blueprintCalls);
+                    }
+                    catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                    if (copy == null) {
+                        debug("Unable to use %s as blueprint method in %s", Privilizer.this.toString(called), Privilizer.this.toString(method));
+                        return;
+                    }
+                    Body redirect = new Body(Privilizer.this, "call %s", Privilizer.this.toString(called));
+                    if (Privilizer.this.policy.isConditional()) {
+                        redirect.startBlock("if (%s)", Privilizer.this.policy.condition);
+                    }
+                    redirect.appendLine("$_ = %s($$);", copy.getName());
+                    if (Privilizer.this.policy.isConditional()) {
+                        redirect.endBlock().startBlock("else").appendLine("$_ = $proceed($$);").endBlock();
+                    }
+                    call.replace(redirect.complete().toString());
+                    result.setValue(Boolean.TRUE);
+                }
+            }
+        });
+        return result.booleanValue();
     }
 
     private static String importedMethodName(CtMethod blueprint) {
         return new StringBuilder(blueprint.getDeclaringClass().getName().replace('.', '_')).append('$')
-            .append(blueprint.getName()).toString();
+                .append(blueprint.getName()).toString();
     }
 
     /*
-     * This design is almost certainly non-optimal. Basically, we have:
+     * This design is almost certainly suboptimal. Basically, we have:
      * 
      * for a declared method, look for calls to blueprint methods for each blueprint method, copy it when copying,
      * inspect blueprint method's code and recursively copy in methods from the source class of *that particular method*
@@ -310,8 +339,8 @@ public abstract class Privilizer {
      * my head around it right now. -MJB
      */
     private CtMethod copyBlueprintTo(final CtClass target, final String toName, final CtMethod method,
-        final CallTo[] blueprintCalls) throws ClassNotFoundException, NotFoundException, IOException,
-        IllegalAccessException {
+            final CallTo[] blueprintCalls) throws ClassNotFoundException, NotFoundException, IOException,
+            IllegalAccessException, CannotCompileException {
         if (!Modifier.isStatic(method.getModifiers())) {
             return null;
         }
@@ -319,59 +348,97 @@ public abstract class Privilizer {
         try {
             final CtMethod done = target.getDeclaredMethod(toName, method.getParameterTypes());
             return done;
-        } catch (NotFoundException e1) {
+        }
+        catch (NotFoundException e1) {
         }
         final CtClass declaring = method.getDeclaringClass();
 
+        final List<CtField> referencedFields = new ArrayList<CtField>();
         final List<CtMethod> ownBlueprints = new ArrayList<CtMethod>();
-        class CollectBlueprints extends ExprEditor {
+        class CollectOwnReferences extends ExprEditor {
             @Override
             public void edit(MethodCall m) throws CannotCompileException {
                 super.edit(m);
                 CtMethod called;
                 try {
                     called = m.getMethod();
-                } catch (NotFoundException e) {
+                }
+                catch (NotFoundException e) {
                     return;
                 }
                 if (called.getDeclaringClass().equals(declaring)) {
                     ownBlueprints.add(called);
                 }
             }
+
+            @Override
+            public void edit(FieldAccess f) throws CannotCompileException {
+                super.edit(f);
+                try {
+                    referencedFields.add(f.getField());
+                }
+                catch (NotFoundException e) {
+                }
+            }
         }
-        try {
-            method.instrument(new CollectBlueprints());
+        method.instrument(new CollectOwnReferences());
 
-            boolean isRecursive = false;
+        boolean isRecursive = false;
 
-            for (CtMethod blueprint : ownBlueprints) {
-                if (blueprint.equals(method)) {
-                    // recursive method call identified:
-                    isRecursive = true;
-                    continue;
-                }
-                CtMethod local = copyBlueprintTo(target, importedMethodName(blueprint), blueprint, blueprintCalls);
-                if (local != null) {
-                    method.instrument(redirect(blueprint, local));
-                }
-            }
-            final CtMethod result = CtNewMethod.copy(method, toName, target, null);
-            result.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
-            target.addMethod(result);
-            if (isRecursive) {
-                CodeConverter redirect = new CodeConverter();
-                redirect.redirectMethodCall(method.getName(), result);
-                result.instrument(redirect);
-            }
-            // privilize other classes' blueprint methods recursively:
-            privilizeBlueprints(target, result, blueprintCalls);
-            // privilize:
-            weave(target, result);
+        for (CtMethod blueprint : ownBlueprints) {
+            if (blueprint.equals(method)) {
+                // recursive method call identified:
+                isRecursive = true;
+                continue;
+            }
+            CtMethod local = copyBlueprintTo(target, importedMethodName(blueprint), blueprint, blueprintCalls);
+            if (local != null) {
+                method.instrument(redirect(blueprint, local));
+            }
+        }
 
-            return result;
-        } catch (CannotCompileException e) {
+        // we have code to handle non-public fields, but the generated code gets VerifyErrors at runtime;
+        // for now we must skip blueprinting such methods.
+        boolean referencesPublicFieldsOnly = true;
+        for (CtField refd : referencedFields) {
+            if (!Modifier.isPublic(refd.getModifiers())) {
+            	warn("Method %s references non-public field %s.%s", toString(method), refd.getDeclaringClass().getName(), refd.getName());
+                referencesPublicFieldsOnly = false;
+            }
+        }
+        if (!referencesPublicFieldsOnly) {
             return null;
         }
+
+        final CtMethod result = CtNewMethod.copy(method, toName, target, null);
+        result.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
+        target.addMethod(result);
+
+        if (!referencedFields.isEmpty()) {
+            handleReferencedFields(target, result, method, referencedFields);
+        }
+        if (isRecursive) {
+            CodeConverter redirectRecursive = new CodeConverter();
+            redirectRecursive.redirectMethodCall(method.getName(), result);
+            result.instrument(redirectRecursive);
+        }
+        // privilize other classes' blueprint methods recursively:
+        privilizeBlueprints(target, result, blueprintCalls);
+
+        if (!referencedFields.isEmpty()) {
+            // more referenced fields handling, but reduces the amount of generated code we read through
+            // when blueprinting recursively
+            makeAccessible(target, result, referencedFields);
+        }
+        // not really possible to check for what truly may throw a SecurityException and thus requires privilizing,
+        // but we'll assume any public method must be. As anything else, once copied,
+        // can only be called from something we have already privilized
+        // TODO? only privilize methods the instrumented class called originally, directly
+        if (Modifier.isPublic(method.getModifiers())) {
+            weave(target, result);
+        }
+
+        return result;
     }
 
     private static CodeConverter redirect(CtMethod origMethod, CtMethod substMethod) throws CannotCompileException {
@@ -380,6 +447,95 @@ public abstract class Privilizer {
         return result;
     }
 
+    private void handleReferencedFields(final CtClass target, final CtMethod method, final CtMethod source,
+            final List<CtField> referencedFields) throws CannotCompileException, NotFoundException {
+
+        for (CtField ctField : referencedFields) {
+            Validate.validState(!ctField.getDeclaringClass().equals(target),
+                    "Circular reference; cannot blueprint method %s", toString(source));
+        }
+
+        method.instrument(new ExprEditor() {
+            @Override
+            public void edit(FieldAccess f) throws CannotCompileException {
+                super.edit(f);
+                CtField fld;
+                boolean primitive;
+                try {
+                    fld = f.getField();
+                    primitive = fld.getType().isPrimitive();
+                }
+                catch (NotFoundException e) {
+                    // no such field implies a reference copied such that the field doesn't exist, probably the usual
+                    // case with blueprinted methods containing field refs
+
+                    fld = null;
+                    primitive = false;
+                    CtClass host = source.getDeclaringClass();
+                    while (host != null) {
+                        try {
+                            fld = host.getDeclaredField(f.getFieldName());
+                            primitive = fld.getType().isPrimitive();
+                            break;
+                        }
+                        catch (NotFoundException e1) {
+                        }
+                        try {
+                            host = host.getSuperclass();
+                        }
+                        catch (NotFoundException e1) {
+                            break;
+                        }
+                    }
+                    if (fld == null) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                final String replacement;
+                if (f.isReader()) {
+                    if (Modifier.isPublic(fld.getModifiers())) {
+                        replacement = String.format("$_ = %s.%s;", fld.getDeclaringClass().getName(), f.getFieldName());
+                    } else {
+                        replacement =
+                            String.format("$_ = ($%s) %s(%s.class, \"%s\", null);", primitive ? "w" : "r", assistant
+                                .fieldReader(target).getName(), fld.getDeclaringClass().getName(), f.getFieldName());
+                    }
+                } else {
+                    if (Modifier.isPublic(fld.getModifiers())) {
+                        replacement = String.format("%s.%s = $1;", fld.getDeclaringClass().getName(), f.getFieldName());
+                    } else {
+                        replacement =
+                            String.format("%s(%s.class, \"%s\", null, %s);", assistant.fieldWriter(target).getName(),
+                                fld.getDeclaringClass().getName(), f.getFieldName(), primitive ? "($w) $1" : "$1");
+                    }
+                }
+                debug("Replacing %s access of %s.%s", f.isReader() ? "read" : "write", fld.getDeclaringClass()
+                        .getName(), f.getFieldName());
+                debug(replacement);
+                f.replace(replacement);
+            }
+        });
+    }
+
+    private void makeAccessible(final CtClass target, final CtMethod method, final List<CtField> referencedFields)
+            throws CannotCompileException {
+        boolean allPublic = true;
+        for (CtField ctField : referencedFields) {
+            if (!Modifier.isPublic(ctField.getModifiers())) {
+                allPublic = false;
+                break;
+            }
+        }
+        if (allPublic) {
+            // no need to fiddle with access
+            return;
+        }
+        method.insertBefore(assistant.callPushFieldAccess(target, referencedFields));
+        final boolean asFinally = true;
+        method.insertAfter(new StringBuilder(assistant.popFieldAccess(target).getName()).append("();").toString(),
+                asFinally);
+    }
+
     protected void debug(String message, Object... args) {
         log.fine(String.format(message, args));
     }
@@ -407,7 +563,7 @@ public abstract class Privilizer {
     }
 
     private CtClass createAction(CtClass type, CtMethod impl, Class<?> iface) throws NotFoundException,
-        CannotCompileException, IOException {
+            CannotCompileException, IOException {
         final boolean exc = impl.getExceptionTypes().length > 0;
 
         final CtClass actionType = classPool.get(iface.getName());
@@ -420,7 +576,8 @@ public abstract class Privilizer {
         final CtField owner;
         if (Modifier.isStatic(impl.getModifiers())) {
             owner = null;
-        } else {
+        }
+        else {
             owner = new CtField(type, generateName("owner"), result);
             owner.setModifiers(Modifier.PRIVATE | Modifier.FINAL);
             debug("Adding owner field %s to %s", owner.getName(), simpleName);
@@ -445,13 +602,13 @@ public abstract class Privilizer {
             for (final CtField fld : result.getDeclaredFields()) {
                 if (sep) {
                     sig.append(", ");
-                } else {
+                }
+                else {
                     sep = true;
                 }
                 sig.append(fld.getType().getName()).append(' ').append(fld.getName());
                 body.appendLine("this.%1$s = %1$s;", fld.getName());
             }
-
             result.addConstructor(CtNewConstructor.make(sig.append(") ").append(body.complete()).toString(), result));
         }
         {
@@ -466,12 +623,13 @@ public abstract class Privilizer {
                 body.append("return ");
             }
             final String deref = Modifier.isStatic(impl.getModifiers()) ? type.getName() : owner.getName();
-            final String call =
-                String.format("%s.%s(%s)", deref, impl.getName(), StringUtils.join(propagatedParameters, ", "));
+            final String call = String.format("%s.%s(%s)", deref, impl.getName(),
+                    StringUtils.join(propagatedParameters, ", "));
 
             if (!isVoid && rt.isPrimitive()) {
                 body.appendLine("%2$s.valueOf(%1$s);", call, ((CtPrimitiveType) rt).getWrapperName());
-            } else {
+            }
+            else {
                 body.append(call).append(';').appendNewLine();
 
                 if (isVoid) {
@@ -479,12 +637,7 @@ public abstract class Privilizer {
                 }
             }
 
-            run.append(body.complete());
-
-            final String r = run.toString();
-            debug("Creating run method:");
-            debug(r);
-            result.addMethod(CtNewMethod.make(r, result));
+            result.addMethod(CtNewMethod.make(run.append(body.complete()).toString(), result));
         }
         getClassFileWriter().write(result);
         debug("Returning action type %s", result);
@@ -495,8 +648,8 @@ public abstract class Privilizer {
         final StringBuilder b = new StringBuilder(m.getName());
         if (m.getParameterTypes().length > 0) {
             b.append("$$").append(
-                StringUtils.strip(Descriptor.getParamDescriptor(m.getSignature()), "(;)").replace("[", "ARRAYOF_")
-                    .replace('/', '_').replace(';', '$'));
+                    StringUtils.strip(Descriptor.getParamDescriptor(m.getSignature()), "(;)").replace("[", "ARRAYOF_")
+                            .replace('/', '_').replace(';', '$'));
         }
         return b.append(ACTION_SUFFIX).toString();
     }
@@ -506,16 +659,16 @@ public abstract class Privilizer {
     }
 
     private boolean weave(CtClass type, CtMethod method) throws ClassNotFoundException, CannotCompileException,
-        NotFoundException, IOException, IllegalAccessException {
+            NotFoundException, IOException, IllegalAccessException {
         final AccessLevel accessLevel = AccessLevel.of(method.getModifiers());
         if (!permitMethodWeaving(accessLevel)) {
             throw new IllegalAccessException("Method " + type.getName() + "#" + toString(method)
-                + " must have maximum access level '" + getTargetAccessLevel() + "' but is defined wider ('"
-                + accessLevel + "')");
+                    + " must have maximum access level '" + getTargetAccessLevel() + "' but is defined wider ('"
+                    + accessLevel + "')");
         }
         if (AccessLevel.PACKAGE.compareTo(accessLevel) > 0) {
             warn("Possible security leak: granting privileges to %s method %s.%s", accessLevel, type.getName(),
-                toString(method));
+                    toString(method));
         }
         final String implName = generateName(method.getName());
 
@@ -523,9 +676,10 @@ public abstract class Privilizer {
         impl.setModifiers(AccessLevel.PRIVATE.merge(method.getModifiers()));
         type.addMethod(impl);
         debug("Copied %2$s %1$s.%3$s to %4$s %1$s.%5$s", type.getName(), accessLevel, toString(method),
-            AccessLevel.PRIVATE, toString(impl));
+                AccessLevel.PRIVATE, toString(impl));
 
         final Body body = new Body(this, "new body of %s", toString(method));
+
         if (policy.isConditional()) {
             body.startBlock("if (%s)", policy.condition);
         }
@@ -544,14 +698,16 @@ public abstract class Privilizer {
         boolean firstParam;
         if (Modifier.isStatic(impl.getModifiers())) {
             firstParam = true;
-        } else {
+        }
+        else {
             body.append("$0");
             firstParam = false;
         }
         for (int i = 1, sz = impl.getParameterTypes().length; i <= sz; i++) {
             if (firstParam) {
                 firstParam = false;
-            } else {
+            }
+            else {
                 body.append(", ");
             }
             body.append('$').append(Integer.toString(i));
@@ -567,7 +723,8 @@ public abstract class Privilizer {
             if (policy.isConditional()) {
                 body.appendLine("return;");
             }
-        } else {
+        }
+        else {
             final String cast = rt.isPrimitive() ? ((CtPrimitiveType) rt).getWrapperName() : rt.getName();
             // don't worry about wrapper NPEs because we should be simply
             // passing back an autoboxed value, then unboxing again
@@ -594,8 +751,8 @@ public abstract class Privilizer {
                 body.endBlock();
             }
             body.appendLine(
-                "throw %1$s instanceof RuntimeException ? (RuntimeException) %1$s : new RuntimeException(%1$s);",
-                wrapped);
+                    "throw %1$s instanceof RuntimeException ? (RuntimeException) %1$s : new RuntimeException(%1$s);",
+                    wrapped);
             body.endBlock();
         }
 

Modified: commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java (original)
+++ commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java Fri Apr  5 18:38:39 2013
@@ -23,10 +23,8 @@ public class PrivilizerWeaver implements
     public static final String CONFIG_ACCESS_LEVEL = CONFIG_WEAVER + "accessLevel";
     public static final String CONFIG_POLICY = CONFIG_WEAVER + "policy";
 
-    private FilesystemPrivilizer privilizer;
-
+    private Privilizer privilizer;
     private Privilizer.Policy policy;
-
     private AccessLevel targetAccessLevel;
 
     @Override

Modified: commons/sandbox/weaver/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/pom.xml?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/pom.xml (original)
+++ commons/sandbox/weaver/trunk/pom.xml Fri Apr  5 18:38:39 2013
@@ -25,7 +25,6 @@
     <version>10-SNAPSHOT</version>
   </parent>
 
-  <groupId>org.apache.commons</groupId>
   <artifactId>commons-weaver</artifactId>
   <version>0.1-SNAPSHOT</version>
   <packaging>pom</packaging>
@@ -95,6 +94,11 @@
         <version>3.1</version>
       </dependency>
       <dependency>
+        <groupId>org.javassist</groupId>
+        <artifactId>javassist</artifactId>
+        <version>3.17.1-GA</version>
+      </dependency>
+      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.11</version>

Modified: commons/sandbox/weaver/trunk/processor/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/processor/pom.xml?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/processor/pom.xml (original)
+++ commons/sandbox/weaver/trunk/processor/pom.xml Fri Apr  5 18:38:39 2013
@@ -43,6 +43,11 @@ under the License.
       <artifactId>commons-lang3</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.javassist</groupId>
+      <artifactId>javassist</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>