This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git


The following commit(s) were added to refs/heads/master by this push:
     new 6eeb025cf OPENJPA-2911 migrate InterfaceImplGenerator wip
6eeb025cf is described below

commit 6eeb025cf3e771da8461633813e1926d912d2aab
Author: Mark Struberg <strub...@apache.org>
AuthorDate: Wed Jul 19 17:25:52 2023 +0200

    OPENJPA-2911 migrate InterfaceImplGenerator wip
    
    Still not really there. There is still some very weirdo
    ClassLoader mixup which gets 'fixed' as sideeffect of using a roundtrip to 
BCClass.
    Not yet 100% sure yet, still digging
---
 .../org/apache/openjpa/enhance/PCEnhancer.java     |  58 ++---
 .../apache/openjpa/enhance/SerpPrivacyHelper.java  |  37 ---
 .../openjpa/meta/InterfaceImplGenerator.java       | 122 +++++-----
 .../org/apache/openjpa/util/asm/AsmHelper.java     |  63 +++---
 .../openjpa/util/asm/EnhancementClassLoader.java   |  10 -
 .../openjpa/util/asm/EnhancementProject.java       |   2 -
 .../openjpa/enhance/TestSubclassValidator.java     |   9 +-
 .../openjpa/persistence/test/ClassSelector.java    | 247 ---------------------
 8 files changed, 115 insertions(+), 433 deletions(-)

diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
index bf852f34a..c3ebe76f8 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
@@ -849,7 +849,7 @@ public class PCEnhancer {
 
             // default: throw new IllegalArgumentException ()
             instructions.add(defLbl);
-            instructions.add(throwException(IllegalArgumentException.class));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class));
         }
         else {
             // In mixed access mode, property indexes are not +1 incremental
@@ -1401,7 +1401,7 @@ public class PCEnhancer {
         final InsnList instructions = newInstance.instructions;
 
         if ((pc.getClassNode().access & Opcodes.ACC_ABSTRACT) > 0) {
-            instructions.add(throwException(USEREXCEP));
+            instructions.add(AsmHelper.throwException(USEREXCEP));
             return;
         }
 
@@ -1503,7 +1503,7 @@ public class PCEnhancer {
         FieldMetaData[] fmds = getCreateSubclass() ? _meta.getFields()
                 : _meta.getDeclaredFields();
         if (fmds.length == 0) {
-            instructions.add(throwException(IllegalArgumentException.class));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class));
         }
         else {
             // switch (val)
@@ -1542,7 +1542,7 @@ public class PCEnhancer {
             }
 
             instructions.add(defaultCase);
-            instructions.add(throwException(IllegalArgumentException.class));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class));
         }
 
         addMultipleFieldsMethodVersion(classNode, provideFieldsMeth, false);
@@ -1565,7 +1565,7 @@ public class PCEnhancer {
         FieldMetaData[] fmds = getCreateSubclass() ? _meta.getFields()
                 : _meta.getDeclaredFields();
         if (fmds.length == 0) {
-            instructions.add(throwException(IllegalArgumentException.class));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class));
         }
         else {
             // switch (val)
@@ -1614,7 +1614,7 @@ public class PCEnhancer {
             }
 
             instructions.add(defaultCase);
-            instructions.add(throwException(IllegalArgumentException.class));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class));
         }
 
         addMultipleFieldsMethodVersion(classNode, replaceFieldMeth, false);
@@ -1639,7 +1639,7 @@ public class PCEnhancer {
         FieldMetaData[] fmds = getCreateSubclass() ? _meta.getFields()
                 : _meta.getDeclaredFields();
         if (fmds.length == 0) {
-            instructions.add(throwException(IllegalArgumentException.class));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class));
         }
         else {
             instructions.add(new VarInsnNode(Opcodes.ILOAD, relLocal));
@@ -1666,7 +1666,7 @@ public class PCEnhancer {
             }
 
             instructions.add(defaultCase);
-            instructions.add(throwException(IllegalArgumentException.class));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class));
         }
 
         addMultipleFieldsMethodVersion(classNode, copyFieldMeth, true);
@@ -1719,7 +1719,7 @@ public class PCEnhancer {
             instructions.add(new InsnNode(Opcodes.RETURN));
         }
         else {
-            instructions.add(throwException(IllegalArgumentException.class));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class));
         }
         instructions.add(afterRelCheck);
 
@@ -1798,7 +1798,7 @@ public class PCEnhancer {
             instructions.add(new FieldInsnNode(Opcodes.GETFIELD, 
classNode.name, SM, Type.getDescriptor(SMTYPE)));
             LabelNode toEndSmCmp = new LabelNode();
             instructions.add(new JumpInsnNode(Opcodes.IF_ACMPEQ, toEndSmCmp));
-            instructions.add(throwException(IllegalArgumentException.class));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class));
             instructions.add(toEndSmCmp);
 
             // if (pcStateManager == null)
@@ -1807,7 +1807,7 @@ public class PCEnhancer {
             instructions.add(new FieldInsnNode(Opcodes.GETFIELD, 
classNode.name, SM, Type.getDescriptor(SMTYPE)));
             LabelNode toEndSmNull = new LabelNode();
             instructions.add(new JumpInsnNode(Opcodes.IFNONNULL, toEndSmNull));
-            instructions.add(throwException(IllegalStateException.class));
+            
instructions.add(AsmHelper.throwException(IllegalStateException.class));
             instructions.add(toEndSmNull);
         }
 
@@ -2179,7 +2179,7 @@ public class PCEnhancer {
 
         // single field identity always throws exception
         if (_meta.isOpenJPAIdentity()) {
-            instructions.add(throwException(INTERNEXCEP));
+            instructions.add(AsmHelper.throwException(INTERNEXCEP));
             return;
         }
 
@@ -3078,7 +3078,7 @@ public class PCEnhancer {
             // throw new IllegalArgumentException (...);
             String msg = _loc.get("str-cons", oidType, 
_meta.getDescribedType()).getMessage();
 
-            instructions.add(throwException(IllegalArgumentException.class, 
msg));
+            
instructions.add(AsmHelper.throwException(IllegalArgumentException.class, msg));
             return;
         }
 
@@ -3247,38 +3247,6 @@ public class PCEnhancer {
         }
     }
 
-
-    /**
-     * Helper method to add the code necessary to throw the given
-     * exception type, sans message.
-     */
-    private InsnList throwException(Class type) {
-        return throwException(type, null);
-    }
-
-    /**
-     * Helper method to add the code necessary to throw the given
-     * exception type, sans message.
-     */
-    private InsnList throwException(Class type, String msg) {
-        InsnList instructions = new InsnList();
-        instructions.add(new TypeInsnNode(Opcodes.NEW, 
Type.getInternalName(type)));
-        instructions.add(new InsnNode(Opcodes.DUP));
-        if (msg != null) {
-            instructions.add(AsmHelper.getLoadConstantInsn(msg));
-        }
-        String desc = msg != null
-                ? Type.getMethodDescriptor(Type.VOID_TYPE, 
Type.getType(String.class))
-                : Type.getMethodDescriptor(Type.VOID_TYPE);
-        instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
-                                            Type.getInternalName(type),
-                                            "<init>",
-                                            desc));
-        instructions.add(new InsnNode(Opcodes.ATHROW));
-
-        return instructions;
-    }
-
     /**
      * Adds the PersistenceCapable interface to the class being
      * enhanced, and adds a default constructor for use by OpenJPA
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/SerpPrivacyHelper.java
 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/SerpPrivacyHelper.java
index 7ffdab287..5e984e3cf 100644
--- 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/SerpPrivacyHelper.java
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/SerpPrivacyHelper.java
@@ -20,9 +20,7 @@ import java.security.PrivilegedAction;
 
 import org.apache.openjpa.lib.util.J2DoPrivHelper;
 
-import serp.bytecode.BCClass;
 import serp.bytecode.BCClassLoader;
-import serp.bytecode.BCField;
 import serp.bytecode.Project;
 
 /**
@@ -59,39 +57,4 @@ public class SerpPrivacyHelper extends J2DoPrivHelper {
         };
     }
 
-    /**
-     * Return a PrivilegeAction object for BCClass.getFields().
-     *
-     * Requires security policy:
-     *   'permission java.lang.RuntimePermission "getClassLoader";'
-     *
-     * @return BCField
-     */
-    public static PrivilegedAction<BCField[]> getBCClassFieldsAction(
-            final BCClass bcClass, final String fieldName) {
-        return new PrivilegedAction<BCField []>() {
-            @Override
-            public BCField [] run() {
-                return bcClass.getFields(fieldName);
-            }
-        };
-    }
-
-    /**
-     * Return a PrivilegeAction object for Project.loadClass().
-     *
-     * Requires security policy:
-     *   'permission java.lang.RuntimePermission "createClassLoader";'
-     *
-     * @return BCClass
-     */
-    public static PrivilegedAction<BCClass> loadProjectClassAction(
-        final Project project, final Class<?> clazz) {
-        return new PrivilegedAction<BCClass>() {
-            @Override
-            public BCClass run() {
-                return project.loadClass(clazz);
-            }
-        };
-    }
 }
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InterfaceImplGenerator.java
 
b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InterfaceImplGenerator.java
index 07fc7ee80..f6410eeb2 100644
--- 
a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InterfaceImplGenerator.java
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/InterfaceImplGenerator.java
@@ -35,13 +35,16 @@ import org.apache.openjpa.util.asm.AsmHelper;
 import org.apache.openjpa.util.asm.ClassNodeTracker;
 import org.apache.openjpa.util.asm.EnhancementClassLoader;
 import org.apache.openjpa.util.asm.EnhancementProject;
+import org.apache.xbean.asm9.Opcodes;
 import org.apache.xbean.asm9.Type;
+import org.apache.xbean.asm9.tree.ClassNode;
+import org.apache.xbean.asm9.tree.FieldInsnNode;
+import org.apache.xbean.asm9.tree.FieldNode;
+import org.apache.xbean.asm9.tree.InsnNode;
+import org.apache.xbean.asm9.tree.MethodNode;
+import org.apache.xbean.asm9.tree.VarInsnNode;
 
 import serp.bytecode.BCClass;
-import serp.bytecode.BCField;
-import serp.bytecode.BCMethod;
-import serp.bytecode.Code;
-import serp.bytecode.Constants;
 import serp.bytecode.Project;
 
 /**
@@ -90,32 +93,30 @@ class InterfaceImplGenerator {
         ClassMetaData sup = meta.getPCSuperclassMetaData();
         if (sup != null) {
             bc.getClassNode().superName = 
Type.getInternalName(sup.getInterfaceImpl());
-            //X enhLoader = new EnhancementClassLoader(_enhProject, 
sup.getInterfaceImpl().getClassLoader());
+            enhLoader = new EnhancementClassLoader(_enhProject, 
sup.getInterfaceImpl().getClassLoader());
         }
 
         FieldMetaData[] fields = meta.getDeclaredFields();
         Set<Method> methods = new HashSet<>();
 
-        //X TODO REMOVE
-        BCClass _bc = new Project().loadClass(getClassName(meta));
-        AsmHelper.readIntoBCClass(bc, _bc);
-
         for (FieldMetaData field : fields) {
-            addField(_bc, iface, field, methods);
+            addField(bc, iface, field, methods);
         }
-        invalidateNonBeanMethods(_bc, iface, methods);
+        invalidateNonBeanMethods(bc, iface, methods);
 
         // first load the base Class<?> as the enhancer requires the class
         // to be available
         try {
-            meta.setInterfaceImpl(Class.forName(_bc.getName(), true, loader));
+            
meta.setInterfaceImpl(Class.forName(bc.getClassNode().name.replace("/", "."), 
true, loader));
         } catch (Throwable t) {
-            throw new InternalException(_loc.get("interface-load", iface,
-                loader), t).setFatal(true);
+            throw new InternalException(_loc.get("interface-load", iface, 
loader), t).setFatal(true);
         }
 
         // copy the BCClass<?> into the enhancer project.
         //X bc = _enhProject.loadClass(new 
ByteArrayInputStream(_bc.toByteArray()), loader);
+        //X TODO REMOVE
+        BCClass _bc = new Project().loadClass(getClassName(meta));
+        AsmHelper.readIntoBCClass(bc, _bc);
         ClassNodeTracker bcEnh = AsmHelper.toClassNode(_enhProject, _bc);
         PCEnhancer enhancer = new PCEnhancer(_repos, bcEnh, meta);
 
@@ -125,8 +126,14 @@ class InterfaceImplGenerator {
                 iface)).setFatal(true);
         try {
             // load the Class<?> for real.
+            EnhancementProject finalProject = new EnhancementProject();
+            EnhancementClassLoader finalLoader = new 
EnhancementClassLoader(finalProject, parentLoader);
+            final byte[] classBytes2 = 
AsmHelper.toByteArray(enhancer.getPCBytecode());
+            ClassNodeTracker bcEnh2 = finalProject.loadClass(classBytes2, 
finalLoader);
+
             String pcClassName = 
enhancer.getPCBytecode().getClassNode().name.replace("/", ".");
-            impl = Class.forName(pcClassName, true, enhLoader);
+            impl = Class.forName(pcClassName, true, finalLoader);
+
         } catch (Throwable t) {
             //X throw new InternalException(_loc.get("interface-load2", iface, 
enhLoader), t).setFatal(true);
             throw new InternalException(_loc.get("interface-load2", iface, 
loader), t).setFatal(true);
@@ -140,63 +147,58 @@ class InterfaceImplGenerator {
      * Add bean getters and setters, also recording seen methods
      * into the given set.
      */
-    private void addField (BCClass bc, Class<?> iface, FieldMetaData fmd,
-        Set<Method> methods) {
-        String name = fmd.getName();
+    private void addField (ClassNodeTracker cnt, Class<?> iface, FieldMetaData 
fmd, Set<Method> methods) {
+        final ClassNode classNode = cnt.getClassNode();
+        String fieldName = fmd.getName();
         Class<?> type = fmd.getDeclaredType();
-        BCField field = bc.declareField(name, type);
-        field.setAccessFlags(Constants.ACCESS_PRIVATE);
+        FieldNode field = new FieldNode(Opcodes.ACC_PRIVATE, fieldName, 
Type.getDescriptor(type), null, null);
+        classNode.fields.add(field);
 
         // getter
-        name = StringUtil.capitalize(name);
-        String prefix = isGetter(iface, fmd) ? "get" : "is";
-        BCMethod meth = bc.declareMethod(prefix + name, type, null);
-        meth.makePublic();
-        Code code = meth.getCode(true);
-        code.aload().setThis();
-        code.getfield().setField(field);
-        code.xreturn().setType(type);
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-        methods.add(getMethodSafe(iface, meth.getName(), null));
+        String getterName = (isGetter(iface, fmd) ? "get" : "is") + 
StringUtil.capitalize(fieldName);
+        MethodNode meth = new MethodNode(Opcodes.ACC_PUBLIC,
+                                         getterName,
+                                         
Type.getMethodDescriptor(Type.getType(type)),
+                                         null, null);
+        classNode.methods.add(meth);
+        meth.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
+        meth.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, 
classNode.name, fieldName, Type.getDescriptor(type)));
+        meth.instructions.add(new InsnNode(AsmHelper.getReturnInsn(type)));
+        methods.add(getMethodSafe(iface, meth.name, null));
 
         // setter
-        meth = bc.declareMethod("set" + name, void.class, new Class[]{type});
-        meth.makePublic();
-        code = meth.getCode(true);
-        code.aload().setThis();
-        code.xload().setParam(0).setType(type);
-        code.putfield().setField(field);
-        code.vreturn();
-        code.calculateMaxStack();
-        code.calculateMaxLocals();
-        methods.add(getMethodSafe(iface, meth.getName(), type));
+        String setterName = "set" + StringUtil.capitalize(fieldName);
+        meth = new MethodNode(Opcodes.ACC_PUBLIC,
+                              setterName,
+                              Type.getMethodDescriptor(Type.VOID_TYPE, 
Type.getType(type)),
+                              null, null);
+        classNode.methods.add(meth);
+        meth.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
+        meth.instructions.add(new VarInsnNode(AsmHelper.getLoadInsn(type), 
1)); // 1st parameter
+        meth.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, 
classNode.name, fieldName, Type.getDescriptor(type)));
+        meth.instructions.add(new InsnNode(Opcodes.RETURN));
+        methods.add(getMethodSafe(iface, meth.name, type));
     }
 
     /**
      * Invalidate methods on the interface which are not managed.
      */
-    private void invalidateNonBeanMethods(BCClass bc, Class<?> iface,
-        Set<Method> methods) {
-        Method[] meths = (Method[]) AccessController.doPrivileged(
-            J2DoPrivHelper.getDeclaredMethodsAction(iface));
-        BCMethod meth;
-        Code code;
-        Class<?> type = _repos.getMetaDataFactory().getDefaults().
-            getUnimplementedExceptionType();
+    private void invalidateNonBeanMethods(ClassNodeTracker cnt, Class<?> 
iface, Set<Method> methods) {
+        Method[] meths = 
AccessController.doPrivileged(J2DoPrivHelper.getDeclaredMethodsAction(iface));
+
+
+        Class<?> unimplementedExceptionType = 
_repos.getMetaDataFactory().getDefaults().getUnimplementedExceptionType();
+
         for (Method method : meths) {
-            if (methods.contains(method))
+            if (methods.contains(method)) {
                 continue;
-            meth = bc.declareMethod(method.getName(),
-                    method.getReturnType(), method.getParameterTypes());
-            meth.makePublic();
-            code = meth.getCode(true);
-            code.anew().setType(type);
-            code.dup();
-            code.invokespecial().setMethod(type, "<init>", void.class, null);
-            code.athrow();
-            code.calculateMaxLocals();
-            code.calculateMaxStack();
+            }
+            MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC,
+                                                   method.getName(),
+                                                   
Type.getMethodDescriptor(method),
+                                                   null, null);
+            
methodNode.instructions.add(AsmHelper.throwException(unimplementedExceptionType));
+            cnt.getClassNode().methods.add(methodNode);
         }
     }
 
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/AsmHelper.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/AsmHelper.java
index 0e1b007fe..d1ec64140 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/AsmHelper.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/AsmHelper.java
@@ -34,14 +34,16 @@ import org.apache.xbean.asm9.Type;
 import org.apache.xbean.asm9.tree.AbstractInsnNode;
 import org.apache.xbean.asm9.tree.ClassNode;
 import org.apache.xbean.asm9.tree.FieldInsnNode;
+import org.apache.xbean.asm9.tree.InsnList;
 import org.apache.xbean.asm9.tree.InsnNode;
 import org.apache.xbean.asm9.tree.IntInsnNode;
 import org.apache.xbean.asm9.tree.LdcInsnNode;
+import org.apache.xbean.asm9.tree.MethodInsnNode;
 import org.apache.xbean.asm9.tree.MethodNode;
+import org.apache.xbean.asm9.tree.TypeInsnNode;
 import org.apache.xbean.asm9.tree.VarInsnNode;
 
 import serp.bytecode.BCClass;
-import serp.bytecode.Project;
 
 /**
  * Utility methods to deal with ASM bytecode
@@ -100,21 +102,6 @@ public final class AsmHelper {
         return classNode;
     }
 
-    /**
-     * temporary helper class to convert BCClass to ASM ClassWriter
-     * @deprecated must get removed when done with migrating from Serp to ASM
-     */
-    public static ClassWriterTracker toClassWriter(BCClass bcClass) {
-        ClassReader cr = new ClassReader(bcClass.toByteArray());
-        ClassWriter cw = new BCClassWriter(ClassWriter.COMPUTE_FRAMES, 
bcClass.getClassLoader());
-        cr.accept(cw, ATTRS, 0);  // 0 -> don't skip anything
-        ClassWriterTracker cwt = new ClassWriterTracker(cw, 
bcClass.getClassLoader());
-        cwt.setName(bcClass.getName());
-
-        return cwt;
-    }
-
-
     public static byte[] getClassBytes(final String typeName)
     {
         final ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
@@ -149,17 +136,6 @@ public final class AsmHelper {
         return cw.toByteArray();
     }
 
-    /**
-     * temporary helper class to convert ClassWriterTracker to BCClass
-     * @deprecated must get removed when done with migrating from Serp to ASM
-     */
-    public static BCClass toBCClass(ClassWriterTracker cwt) {
-        final byte[] classBytes = cwt.getCw().toByteArray();
-        BCClass bcClass = new Project().loadClass(new 
ByteArrayInputStream(classBytes), cwt.getClassLoader());
-        bcClass.setName(cwt.getName());
-        return bcClass;
-    }
-
     /**
      * temporary helper class to convert BCClass to ASM ClassNode
      * @deprecated must get removed when done with migrating from Serp to ASM
@@ -689,6 +665,39 @@ public final class AsmHelper {
         }
     }
 
+
+    /**
+     * Helper method to add the code necessary to throw the given
+     * exception type, sans message.
+     */
+    public static InsnList throwException(Class type) {
+        return throwException(type, null);
+    }
+
+    /**
+     * Helper method to add the code necessary to throw the given
+     * exception type, sans message.
+     */
+    public static InsnList throwException(Class type, String msg) {
+        InsnList instructions = new InsnList();
+        instructions.add(new TypeInsnNode(Opcodes.NEW, 
Type.getInternalName(type)));
+        instructions.add(new InsnNode(Opcodes.DUP));
+        if (msg != null) {
+            instructions.add(AsmHelper.getLoadConstantInsn(msg));
+        }
+        String desc = msg != null
+                ? Type.getMethodDescriptor(Type.VOID_TYPE, 
Type.getType(String.class))
+                : Type.getMethodDescriptor(Type.VOID_TYPE);
+        instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
+                                            Type.getInternalName(type),
+                                            "<init>",
+                                            desc));
+        instructions.add(new InsnNode(Opcodes.ATHROW));
+
+        return instructions;
+    }
+
+
     public static Class<?> getClass(ClassLoader classLoader, String 
internalTypeName) {
         try {
             return Class.forName(internalTypeName.replace("/", "."), false, 
classLoader);
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/EnhancementClassLoader.java
 
b/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/EnhancementClassLoader.java
index 462eabc13..c58cecb91 100644
--- 
a/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/EnhancementClassLoader.java
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/EnhancementClassLoader.java
@@ -41,16 +41,6 @@ public class EnhancementClassLoader extends ClassLoader {
         return project;
     }
 
-    @Override
-    public Class<?> loadClass(String name) throws ClassNotFoundException {
-        return super.loadClass(name);
-    }
-
-    @Override
-    protected Class<?> loadClass(String name, boolean resolve) throws 
ClassNotFoundException {
-        return super.loadClass(name, resolve);
-    }
-
     protected Class findClass(String name) throws ClassNotFoundException {
         byte[] bytes;
         try {
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/EnhancementProject.java
 
b/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/EnhancementProject.java
index de93f1a18..0748274c4 100644
--- 
a/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/EnhancementProject.java
+++ 
b/openjpa-kernel/src/main/java/org/apache/openjpa/util/asm/EnhancementProject.java
@@ -124,8 +124,6 @@ public class EnhancementProject {
         ClassNode classNode = new ClassNode();
         cr.accept(classNode, AsmHelper.ATTRS, 0);
         ClassNodeTracker cnt = new ClassNodeTracker(this, classNode, loader);
-        String name = classNode.name.replace("/", ".");
-        classNodeTrackers.put(name, cnt);
         return cnt;
     }
 
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSubclassValidator.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSubclassValidator.java
index 0e774c015..52890cc63 100644
--- 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSubclassValidator.java
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSubclassValidator.java
@@ -26,6 +26,7 @@ import org.apache.openjpa.persistence.common.apps.Department;
 import org.apache.openjpa.persistence.common.apps.RuntimeTest2;
 import org.apache.openjpa.persistence.test.SingleEMFTestCase;
 import org.apache.openjpa.util.asm.AsmHelper;
+import org.apache.openjpa.util.asm.EnhancementProject;
 import org.apache.xbean.asm9.tree.ClassNode;
 import org.junit.Test;
 
@@ -34,8 +35,6 @@ import jakarta.persistence.AccessType;
 import jakarta.persistence.Basic;
 import jakarta.persistence.Entity;
 import jakarta.persistence.Id;
-import serp.bytecode.BCClass;
-import serp.bytecode.Project;
 
 public class TestSubclassValidator extends SingleEMFTestCase {
     @Override
@@ -50,7 +49,7 @@ public class TestSubclassValidator extends SingleEMFTestCase {
 
     @Test
     public void testBcSubclassValidator() throws Exception {
-        Project project = new Project();
+        EnhancementProject project = new EnhancementProject();
         TemporaryClassLoader tempCl = new 
TemporaryClassLoader(this.getClass().getClassLoader());
         final OpenJPAConfiguration conf = emf.getConfiguration();
 
@@ -61,7 +60,7 @@ public class TestSubclassValidator extends SingleEMFTestCase {
 
         {
             ClassNode classNode = 
AsmHelper.readClassNode(EnhanceableGetterEntity.class.getClassLoader(), 
EnhanceableGetterEntity.class.getName());
-            final BCClass bcClass = 
project.loadClass(EnhanceableGetterEntity.class.getName(), tempCl);
+            project.loadClass(EnhanceableGetterEntity.class.getName(), tempCl);
             final ClassMetaData meta = 
repos.getMetaData(tempCl.loadClass(EnhanceableGetterEntity.class.getName()), 
tempCl, false);
             PCSubclassValidator subclassValidator = new 
PCSubclassValidator(meta, classNode, log, true);
             subclassValidator.assertCanSubclass();
@@ -69,7 +68,7 @@ public class TestSubclassValidator extends SingleEMFTestCase {
 
         {
             ClassNode classNode = 
AsmHelper.readClassNode(UnenhancedPropertyAccess.class.getClassLoader(), 
UnenhancedPropertyAccess.class.getName());
-            final BCClass bcClass = 
project.loadClass(UnenhancedPropertyAccess.class.getName(), tempCl);
+            project.loadClass(UnenhancedPropertyAccess.class.getName(), 
tempCl);
             final ClassMetaData meta = 
repos.getMetaData(tempCl.loadClass(UnenhancedPropertyAccess.class.getName()), 
tempCl, false);
             PCSubclassValidator subclassValidator = new 
PCSubclassValidator(meta, classNode, log, true);
             subclassValidator.assertCanSubclass();
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/ClassSelector.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/ClassSelector.java
deleted file mode 100644
index e5c755196..000000000
--- 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/ClassSelector.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openjpa.persistence.test;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.List;
-
-import serp.bytecode.Annotations;
-import serp.bytecode.BCClass;
-import serp.bytecode.BCMethod;
-import serp.bytecode.Project;
-
-/**
- * List class names that match specific selection criteria based on 
inheritance,
- * implemented interface or annotations. The classes are scanned starting from
- * a root directory or a single file. Uses serp bytecode library for reading 
the
- * bytecode. The classes are not loaded in Java Virtual Machine and hence
- * dependent classes need not be in the classpath.
- *
- * @author Pinaki Poddar
- *
- */
-public class ClassSelector {
-       private List<String> _supers = new ArrayList<>();
-       private List<String> _interfaces = new ArrayList<>();
-       private List<String> _annotations = new ArrayList<>();
-
-       /**
-        * Prints the class names that satisfy the following criteria
-        *   extends org.apache.openjpa.persistence.test.SingleEMFTestCase or
-        *           junit.framework.TestCase
-        *   and annotated with org.apache.openjpa.persistence.test.AllowFailure
-        *
-     * @param args the root directory of the class files to be scanned. If no
-        * argument is given then assumes the current directory.
-        *
-        */
-       public static void main(String[] args) throws Exception {
-               String dir = (args.length == 0) ? System.getProperty("user.dir")
-                               : args[0];
-        ClassSelector reader = new ClassSelector()
-            .addSuper("org.apache.openjpa.persistence.test.SingleEMTestCase")
-            .addSuper("org.apache.openjpa.persistence.test.SingleEMFTestCase")
-            .addSuper("org.apache.openjpa.persistence.kernel.BaseKernelTest")
-            .addSuper("org.apache.openjpa.persistence.query.BaseQueryTest")
-            
.addSuper("org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest")
-            .addSuper(
-                "org.apache.openjpa.persistence.common.utils.AbstractTestCase")
-            .addAnnotation("org.apache.openjpa.persistence.test.AllowFailure");
-               List<String> names = reader.list(new File(dir), true);
-               String spec = reader.getSpecification();
-               System.err.println("Found " + names.size() + " classes under "
-                               + dir + (spec.length() > 0 ? " that" : ""));
-               System.err.println(spec);
-               for (String name : names)
-                       System.err.println(name);
-       }
-
-       /**
-        * List all the class names that match the selection.
-        *
-        * @param file a root file or directory
-        * @param recursive if true scans all directory recursively
-        * @return list of class names that match the selection.
-        */
-       public List<String> list(File file, boolean recursive) {
-               List<String> names = new ArrayList<>();
-               list(file, recursive, names);
-               return names;
-       }
-
-       private void list(File file, boolean recursive, List<String> names) {
-               if (file.isDirectory()) {
-                       if (recursive) {
-                String[] children = file.list(new FilenameFilter() {
-                    @Override
-                    public boolean accept(File dir, String name) {
-                                               return name.endsWith(".class");
-                                       }
-                               });
-                               for (String name : children)
-                    list(new File(file, name), recursive, names);
-                               String[] dirs = file.list(new FilenameFilter() {
-                    @Override
-                    public boolean accept(File dir, String name) {
-                        return new File(dir, name).isDirectory();
-                                       }
-                               });
-                               for (String name : dirs)
-                    list(new File(file, name), recursive, names);
-                       }
-               } else if (file.getName().endsWith(".class")) {
-                       String cls = select(file);
-                       if (cls != null)
-                               names.add(cls);
-               }
-       }
-
-       /**
-        * Adds fully-qualified name of a super class for selection.
-        */
-       public ClassSelector addSuper(String s) {
-               _supers.add(s);
-               return this;
-       }
-
-       /**
-        * Adds fully-qualified name of an interface for selection.
-        */
-       public ClassSelector addInterface(String s) {
-               _interfaces.add(s);
-               return this;
-       }
-
-       /**
-        * Adds fully-qualified name of an annotation for selection.
-        */
-       public ClassSelector addAnnotation(String s) {
-               _annotations.add(s);
-               return this;
-       }
-
-       private String select(File file) {
-               try {
-                       BCClass bcls = new Project().loadClass(file);
-                       if (applyInheritanceFilter(bcls)
-                        && applyInterfaceFilter(bcls)
-                        && applyAnnotationFilter(bcls))
-                               return bcls.getName();
-               } catch (Exception e) {
-            System.err.println("Error reading " + file.getAbsolutePath()
-                                       + " : " + e);
-               }
-               return null;
-       }
-
-       /**
-        * Affirms if super class of the given class matches any of the
-        * selection filter names. If no super class name has been set for
-        * selection then return true.
-        *
-        * @see #addSuper(String)
-        */
-       private boolean applyInheritanceFilter(BCClass bcls) {
-               if (_supers.isEmpty())
-                       return true;
-               String superc = bcls.getSuperclassName();
-               return _supers.contains(superc);
-       }
-
-       /**
-        * Affirms if interfaces of the given class match any of the
-        * selection filter names. If no interface name has been set for
-        * selection then return true.
-        *
-        * @see #addInterface(String)
-        */
-       private boolean applyInterfaceFilter(BCClass bcls) {
-               if (_interfaces.isEmpty())
-                       return true;
-               String[] ifaces = bcls.getInterfaceNames();
-               if (ifaces == null || ifaces.length == 0)
-                       return false;
-               for (String iface : ifaces)
-                       if (_interfaces.contains(iface))
-                               return true;
-               return false;
-       }
-
-       /**
-     * Affirms if annotations of the given class or its methods match any of 
the
-        * selection filter names. If no annotation name has been set for
-        * selection then return true.
-        *
-        * @see #addAnnotation(String)
-        */
-       private boolean applyAnnotationFilter(BCClass bcls) {
-               if (_annotations.isEmpty())
-                       return true;
-               Annotations annos = bcls.getDeclaredRuntimeAnnotations(false);
-               if (hasAnnotation(annos))
-                       return true;
-               BCMethod[] methods = bcls.getDeclaredMethods();
-               for (BCMethod m : methods) {
-                       annos = m.getDeclaredRuntimeAnnotations(false);
-                       if (hasAnnotation(annos))
-                               return true;
-               }
-               return false;
-       }
-
-       private boolean hasAnnotation(Annotations annos) {
-               if (annos == null)
-                       return false;
-               for (String anno : _annotations)
-                       if (annos.getAnnotation(anno) != null)
-                               return true;
-               return false;
-       }
-
-       /**
-        * Gets a printable description of the currently set selection criteria.
-        */
-       public String getSpecification() {
-               StringBuilder tmp = new StringBuilder();
-               String and = "";
-               if (!_supers.isEmpty()) {
-                       tmp.append("\textends ");
-                       and = "and ";
-                       for (int i=0; i<_supers.size(); i++)
-                tmp.append(_supers.get(i)).append(
-                    (i != _supers.size()-1 ? "\r\n\t     or " : "\r\n"));
-               }
-               if (!_interfaces.isEmpty()) {
-                       tmp.append("\t" + and + "implements ");
-                       and = "and ";
-                       for (int i=0; i<_interfaces.size(); i++)
-                tmp.append(_interfaces.get(i)).append(
-                    (i != _interfaces.size()-1 ? "\r\n\t        or " : 
"\r\n"));
-               }
-               if (!_annotations.isEmpty()) {
-                       tmp.append("\t" + and + "annotatated with ");
-                       for (int i=0; i<_annotations.size(); i++)
-                               tmp.append(_annotations.get(i))
-                    .append((i != _annotations.size()-1 ? " or " : "\r\n"));
-               }
-               return tmp.toString();
-       }
-}


Reply via email to