You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2022/08/08 15:00:50 UTC

[struts] branch WW-5207-asm-9 created (now 86b45e96f)

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

lukaszlenart pushed a change to branch WW-5207-asm-9
in repository https://gitbox.apache.org/repos/asf/struts.git


      at 86b45e96f WW-5207 Uses ASM 9 by default

This branch includes the following new commits:

     new 86b45e96f WW-5207 Uses ASM 9 by default

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[struts] 01/01: WW-5207 Uses ASM 9 by default

Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-5207-asm-9
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 86b45e96fcd4155b68c3d18e18719fba9584d66e
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Mon Aug 8 17:00:42 2022 +0200

    WW-5207 Uses ASM 9 by default
---
 .../xwork2/util/finder/ClassFinder.java            |  55 +++----
 .../struts2/convention/DefaultClassFinder.java     | 170 +++++++--------------
 2 files changed, 80 insertions(+), 145 deletions(-)

diff --git a/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassFinder.java b/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassFinder.java
index fcbd08e4e..92e213655 100644
--- a/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassFinder.java
+++ b/core/src/main/java/com/opensymphony/xwork2/util/finder/ClassFinder.java
@@ -29,11 +29,11 @@ import java.util.List;
 /**
  * ClassFinder searches the classpath of the specified ClassLoaderInterface for
  * packages, classes, constructors, methods, or fields with specific annotations.
- *
+ * <p>
  * For security reasons ASM is used to find the annotations.  Classes are not
  * loaded unless they match the requirements of a called findAnnotated* method.
  * Once loaded, these classes are cached.
- *
+ * <p>
  * The getClassesNotLoaded() method can be used immediately after any find*
  * method to get a list of classes which matched the find requirements (i.e.
  * contained the annotation), but were unable to be loaded.
@@ -67,32 +67,32 @@ public interface ClassFinder {
 
     List<Package> findAnnotatedPackages(Class<? extends Annotation> annotation);
 
-    List<Class> findAnnotatedClasses(Class<? extends Annotation> annotation);
+    List<Class<?>> findAnnotatedClasses(Class<? extends Annotation> annotation);
 
     List<Method> findAnnotatedMethods(Class<? extends Annotation> annotation);
 
-    List<Constructor> findAnnotatedConstructors(Class<? extends Annotation> annotation);
+    List<Constructor<?>> findAnnotatedConstructors(Class<? extends Annotation> annotation);
 
     List<Field> findAnnotatedFields(Class<? extends Annotation> annotation);
 
-    List<Class> findClassesInPackage(String packageName, boolean recursive);
+    List<Class<?>> findClassesInPackage(String packageName, boolean recursive);
 
-    List<Class> findClasses(Test<ClassInfo> test);
+    List<Class<?>> findClasses(Test<ClassInfo> test);
 
-    List<Class> findClasses();
+    List<Class<?>> findClasses();
 
     ClassLoaderInterface getClassLoaderInterface();
 
-    public static interface Info {
+    interface Info {
         String getName();
 
         List<AnnotationInfo> getAnnotations();
     }
 
-    public class AnnotationInfo extends Annotatable implements Info {
+    class AnnotationInfo extends Annotatable implements Info {
         private final String name;
 
-        public AnnotationInfo(Annotation annotation){
+        public AnnotationInfo(Annotation annotation) {
             this(annotation.getClass().getName());
         }
 
@@ -116,7 +116,7 @@ public interface ClassFinder {
         }
     }
 
-    public class Annotatable {
+    class Annotatable {
         private final List<AnnotationInfo> annotations = new ArrayList<>();
 
         public Annotatable(AnnotatedElement element) {
@@ -134,12 +134,12 @@ public interface ClassFinder {
 
     }
 
-    public class PackageInfo extends Annotatable implements Info {
+    class PackageInfo extends Annotatable implements Info {
         private final String name;
         private final ClassInfo info;
         private final Package pkg;
 
-        public PackageInfo(Package pkg){
+        public PackageInfo(Package pkg) {
             super(pkg);
             this.pkg = pkg;
             this.name = pkg.getName();
@@ -157,11 +157,11 @@ public interface ClassFinder {
         }
 
         public Package get() throws ClassNotFoundException {
-            return (pkg != null)?pkg:info.get().getPackage();
+            return (pkg != null) ? pkg : info.get().getPackage();
         }
     }
 
-    public class ClassInfo extends Annotatable implements Info {
+    class ClassInfo extends Annotatable implements Info {
         private final String name;
         private final List<MethodInfo> methods = new ArrayList<>();
         private final List<MethodInfo> constructors = new ArrayList<>();
@@ -169,17 +169,18 @@ public interface ClassFinder {
         private final List<String> interfaces = new ArrayList<>();
         private final List<String> superInterfaces = new ArrayList<>();
         private final List<FieldInfo> fields = new ArrayList<>();
+        private final ClassFinder classFinder;
+
         private Class<?> clazz;
-        private ClassFinder classFinder;
         private ClassNotFoundException notFound;
 
-        public ClassInfo(Class clazz, ClassFinder classFinder) {
+        public ClassInfo(Class<?> clazz, ClassFinder classFinder) {
             super(clazz);
             this.clazz = clazz;
             this.classFinder = classFinder;
             this.name = clazz.getName();
-            Class superclass = clazz.getSuperclass();
-            this.superType = superclass != null ? superclass.getName(): null;
+            Class<?> superclass = clazz.getSuperclass();
+            this.superType = superclass != null ? superclass.getName() : null;
         }
 
         public ClassInfo(String name, String superType, ClassFinder classFinder) {
@@ -188,8 +189,8 @@ public interface ClassFinder {
             this.classFinder = classFinder;
         }
 
-        public String getPackageName(){
-            return name.indexOf('.') > 0 ? name.substring(0, name.lastIndexOf('.')) : "" ;
+        public String getPackageName() {
+            return name.indexOf('.') > 0 ? name.substring(0, name.lastIndexOf('.')) : "";
         }
 
         public List<MethodInfo> getConstructors() {
@@ -220,7 +221,7 @@ public interface ClassFinder {
             return superType;
         }
 
-        public Class get() throws ClassNotFoundException {
+        public Class<?> get() throws ClassNotFoundException {
             if (clazz != null) return clazz;
             if (notFound != null) throw notFound;
             try {
@@ -239,20 +240,20 @@ public interface ClassFinder {
         }
     }
 
-    public class MethodInfo extends Annotatable implements Info {
+    class MethodInfo extends Annotatable implements Info {
         private final ClassInfo declaringClass;
         private final String returnType;
         private final String name;
         private final List<List<AnnotationInfo>> parameterAnnotations = new ArrayList<>();
 
-        public MethodInfo(ClassInfo info, Constructor constructor){
+        public MethodInfo(ClassInfo info, Constructor<?> constructor) {
             super(constructor);
             this.declaringClass = info;
             this.name = "<init>";
             this.returnType = Void.TYPE.getName();
         }
 
-        public MethodInfo(ClassInfo info, Method method){
+        public MethodInfo(ClassInfo info, Method method) {
             super(method);
             this.declaringClass = info;
             this.name = method.getName();
@@ -297,12 +298,12 @@ public interface ClassFinder {
         }
     }
 
-    public class FieldInfo extends Annotatable implements Info {
+    class FieldInfo extends Annotatable implements Info {
         private final String name;
         private final String type;
         private final ClassInfo declaringClass;
 
-        public FieldInfo(ClassInfo info, Field field){
+        public FieldInfo(ClassInfo info, Field field) {
             super(field);
             this.declaringClass = info;
             this.name = field.getName();
diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultClassFinder.java b/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultClassFinder.java
index 54d535811..9b6fdb86d 100644
--- a/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultClassFinder.java
+++ b/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultClassFinder.java
@@ -38,6 +38,7 @@ import org.objectweb.asm.Opcodes;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
@@ -45,7 +46,15 @@ import java.lang.reflect.Method;
 import java.net.JarURLConnection;
 import java.net.URL;
 import java.net.URLDecoder;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 
@@ -57,9 +66,9 @@ public class DefaultClassFinder implements ClassFinder {
 
     private final List<String> classesNotLoaded = new ArrayList<>();
 
-    private boolean extractBaseInterfaces;
-    private ClassLoaderInterface classLoaderInterface;
-    private FileManager fileManager;
+    private final ClassLoaderInterface classLoaderInterface;
+    private final boolean extractBaseInterfaces;
+    private final FileManager fileManager;
 
     public DefaultClassFinder(ClassLoaderInterface classLoaderInterface, Collection<URL> urls, boolean extractBaseInterfaces, Set<String> protocols, Test<String> classNameFilter) {
         this.classLoaderInterface = classLoaderInterface;
@@ -97,46 +106,6 @@ public class DefaultClassFinder implements ClassFinder {
         }
     }
 
-    public DefaultClassFinder(Class... classes){
-        this(Arrays.asList(classes));
-    }
-
-    public DefaultClassFinder(List<Class> classes){
-        this.classLoaderInterface = null;
-        List<Info> infos = new ArrayList<>();
-        List<Package> packages = new ArrayList<>();
-        for (Class clazz : classes) {
-
-            Package aPackage = clazz.getPackage();
-            if (aPackage != null && !packages.contains(aPackage)){
-                infos.add(new PackageInfo(aPackage));
-                packages.add(aPackage);
-            }
-
-            ClassInfo classInfo = new ClassInfo(clazz, this);
-            infos.add(classInfo);
-            classInfos.put(classInfo.getName(), classInfo);
-            for (Method method : clazz.getDeclaredMethods()) {
-                infos.add(new MethodInfo(classInfo, method));
-            }
-
-            for (Constructor constructor : clazz.getConstructors()) {
-                infos.add(new MethodInfo(classInfo, constructor));
-            }
-
-            for (Field field : clazz.getDeclaredFields()) {
-                infos.add(new FieldInfo(classInfo, field));
-            }
-        }
-
-        for (Info info : infos) {
-            for (AnnotationInfo annotation : info.getAnnotations()) {
-                List<Info> annotationInfos = getAnnotationInfos(annotation.getName());
-                annotationInfos.add(info);
-            }
-        }
-    }
-
     public ClassLoaderInterface getClassLoaderInterface() {
         return classLoaderInterface;
     }
@@ -171,15 +140,15 @@ public class DefaultClassFinder implements ClassFinder {
         return packages;
     }
 
-    public List<Class> findAnnotatedClasses(Class<? extends Annotation> annotation) {
+    public List<Class<?>> findAnnotatedClasses(Class<? extends Annotation> annotation) {
         classesNotLoaded.clear();
-        List<Class> classes = new ArrayList<>();
+        List<Class<?>> classes = new ArrayList<>();
         List<Info> infos = getAnnotationInfos(annotation.getName());
         for (Info info : infos) {
             if (info instanceof ClassInfo) {
                 ClassInfo classInfo = (ClassInfo) info;
                 try {
-                    Class clazz = classInfo.get();
+                    Class<?> clazz = classInfo.get();
                     // double check via proper reflection
                     if (clazz.isAnnotationPresent(annotation)) {
                         classes.add(clazz);
@@ -208,7 +177,7 @@ public class DefaultClassFinder implements ClassFinder {
                 seen.add(classInfo);
 
                 try {
-                    Class clazz = classInfo.get();
+                    Class<?> clazz = classInfo.get();
                     for (Method method : clazz.getDeclaredMethods()) {
                         if (method.isAnnotationPresent(annotation)) {
                             methods.add(method);
@@ -223,10 +192,10 @@ public class DefaultClassFinder implements ClassFinder {
         return methods;
     }
 
-    public List<Constructor> findAnnotatedConstructors(Class<? extends Annotation> annotation) {
+    public List<Constructor<?>> findAnnotatedConstructors(Class<? extends Annotation> annotation) {
         classesNotLoaded.clear();
         List<ClassInfo> seen = new ArrayList<>();
-        List<Constructor> constructors = new ArrayList<>();
+        List<Constructor<?>> constructors = new ArrayList<>();
         List<Info> infos = getAnnotationInfos(annotation.getName());
         for (Info info : infos) {
             if (info instanceof MethodInfo && "<init>".equals(info.getName())) {
@@ -238,8 +207,8 @@ public class DefaultClassFinder implements ClassFinder {
                 seen.add(classInfo);
 
                 try {
-                    Class clazz = classInfo.get();
-                    for (Constructor constructor : clazz.getConstructors()) {
+                    Class<?> clazz = classInfo.get();
+                    for (Constructor<?> constructor : clazz.getConstructors()) {
                         if (constructor.isAnnotationPresent(annotation)) {
                             constructors.add(constructor);
                         }
@@ -270,7 +239,7 @@ public class DefaultClassFinder implements ClassFinder {
                 seen.add(classInfo);
 
                 try {
-                    Class clazz = classInfo.get();
+                    Class<?> clazz = classInfo.get();
                     for (Field field : clazz.getDeclaredFields()) {
                         if (field.isAnnotationPresent(annotation)) {
                             fields.add(field);
@@ -285,14 +254,14 @@ public class DefaultClassFinder implements ClassFinder {
         return fields;
     }
 
-    public List<Class> findClassesInPackage(String packageName, boolean recursive) {
+    public List<Class<?>> findClassesInPackage(String packageName, boolean recursive) {
         classesNotLoaded.clear();
-        List<Class> classes = new ArrayList<>();
+        List<Class<?>> classes = new ArrayList<>();
         for (ClassInfo classInfo : classInfos.values()) {
             try {
-                if (recursive && classInfo.getPackageName().startsWith(packageName)){
+                if (recursive && classInfo.getPackageName().startsWith(packageName)) {
                     classes.add(classInfo.get());
-                } else if (classInfo.getPackageName().equals(packageName)){
+                } else if (classInfo.getPackageName().equals(packageName)) {
                     classes.add(classInfo.get());
                 }
             } catch (Throwable e) {
@@ -303,9 +272,9 @@ public class DefaultClassFinder implements ClassFinder {
         return classes;
     }
 
-    public List<Class> findClasses(Test<ClassInfo> test) {
+    public List<Class<?>> findClasses(Test<ClassInfo> test) {
         classesNotLoaded.clear();
-        List<Class> classes = new ArrayList<>();
+        List<Class<?>> classes = new ArrayList<>();
         for (ClassInfo classInfo : classInfos.values()) {
             try {
                 if (test.test(classInfo)) {
@@ -319,9 +288,9 @@ public class DefaultClassFinder implements ClassFinder {
         return classes;
     }
 
-    public List<Class> findClasses() {
+    public List<Class<?>> findClasses() {
         classesNotLoaded.clear();
-        List<Class> classes = new ArrayList<>();
+        List<Class<?>> classes = new ArrayList<>();
         for (ClassInfo classInfo : classInfos.values()) {
             try {
                 classes.add(classInfo.get());
@@ -333,9 +302,9 @@ public class DefaultClassFinder implements ClassFinder {
         return classes;
     }
 
-    private List<String> file(URL location) {
+    private List<String> file(URL location) throws UnsupportedEncodingException {
         List<String> classNames = new ArrayList<>();
-        File dir = new File(URLDecoder.decode(location.getPath()));
+        File dir = new File(URLDecoder.decode(location.getPath(), "UTF-8"));
         if ("META-INF".equals(dir.getName())) {
             dir = dir.getParentFile(); // Scrape "META-INF" off
         }
@@ -347,15 +316,17 @@ public class DefaultClassFinder implements ClassFinder {
 
     private void scanDir(File dir, List<String> classNames, String packageName) {
         File[] files = dir.listFiles();
-        for (File file : files) {
-            if (file.isDirectory()) {
-                scanDir(file, classNames, packageName + file.getName() + ".");
-            } else if (file.getName().endsWith(".class")) {
-                String name = file.getName();
-                name = name.replaceFirst(".class$", "");
-                // Classes packaged in an exploded .war (e.g. in a VFS file system) should not
-                // have WEB-INF.classes in their package name.
-                classNames.add(StringUtils.removeStart(packageName, "WEB-INF.classes.") + name);
+        if (files != null) {
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    scanDir(file, classNames, packageName + file.getName() + ".");
+                } else if (file.getName().endsWith(".class")) {
+                    String name = file.getName();
+                    name = name.replaceFirst(".class$", "");
+                    // Classes packaged in an exploded .war (e.g. in a VFS file system) should not
+                    // have WEB-INF.classes in their package name.
+                    classNames.add(StringUtils.removeStart(packageName, "WEB-INF.classes.") + name);
+                }
             }
         }
     }
@@ -363,12 +334,9 @@ public class DefaultClassFinder implements ClassFinder {
     private List<String> jar(URL location) throws IOException {
         URL url = fileManager.normalizeToFileProtocol(location);
         if (url != null) {
-            InputStream in = url.openStream();
-            try {
+            try (InputStream in = url.openStream()) {
                 JarInputStream jarStream = new JarInputStream(in);
                 return jar(jarStream);
-            } finally {
-                in.close();
             }
         } else {
             LOG.debug("Unable to read [{}]", location.toExternalForm());
@@ -388,7 +356,7 @@ public class DefaultClassFinder implements ClassFinder {
             className = className.replaceFirst(".class$", "");
 
             //war files are treated as .jar files, so takeout WEB-INF/classes
-            className = StringUtils.removeStart(className, "WEB-INF/classes/"); 
+            className = StringUtils.removeStart(className, "WEB-INF/classes/");
 
             className = className.replace('/', '.');
             classNames.add(className);
@@ -397,40 +365,8 @@ public class DefaultClassFinder implements ClassFinder {
         return classNames;
     }
 
-    public class PackageInfo extends Annotatable implements Info {
-        private final String name;
-        private final ClassInfo info;
-        private final Package pkg;
-
-        public PackageInfo(Package pkg){
-            super(pkg);
-            this.pkg = pkg;
-            this.name = pkg.getName();
-            this.info = null;
-        }
-
-        public PackageInfo(String name, ClassFinder classFinder) {
-            info = new ClassInfo(name, null, classFinder);
-            this.name = name;
-            this.pkg = null;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public Package get() throws ClassNotFoundException {
-            return (pkg != null)?pkg:info.get().getPackage();
-        }
-    }
-
     private List<Info> getAnnotationInfos(String name) {
-        List<Info> infos = annotated.get(name);
-        if (infos == null) {
-            infos = new ArrayList<>();
-            annotated.put(name, infos);
-        }
-        return infos;
+        return annotated.computeIfAbsent(name, k -> new ArrayList<>());
     }
 
     private void readClassDef(String className) {
@@ -454,19 +390,16 @@ public class DefaultClassFinder implements ClassFinder {
     }
 
     public class InfoBuildingVisitor extends ClassVisitor {
+
+        private final ClassFinder classFinder;
+
         private Info info;
-        private ClassFinder classFinder;
 
         public InfoBuildingVisitor(ClassFinder classFinder) {
-            super(Opcodes.ASM7);
+            super(Opcodes.ASM9);
             this.classFinder = classFinder;
         }
 
-        public InfoBuildingVisitor(Info info, ClassFinder classFinder) {
-            this(classFinder);
-            this.info = info;
-        }
-
         @Override
         public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
             if (name.endsWith("package-info")) {
@@ -480,8 +413,9 @@ public class DefaultClassFinder implements ClassFinder {
                 info = classInfo;
                 classInfos.put(classInfo.getName(), classInfo);
 
-                if (extractBaseInterfaces)
+                if (extractBaseInterfaces) {
                     extractSuperInterfaces(classInfo);
+                }
             }
         }