You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by kk...@apache.org on 2014/09/12 20:57:29 UTC

svn commit: r1624614 - in /tomcat/trunk/java/org/apache: catalina/startup/ tomcat/util/bcel/classfile/

Author: kkolinko
Date: Fri Sep 12 18:57:28 2014
New Revision: 1624614

URL: http://svn.apache.org/r1624614
Log:
Get rid of ArrayList arithmetics in JavaClass.getAnnotationEntries()
Note that this changes return value of getAnnotationEntries() to be null instead of zero-length array by default.

This is based on the following:
- All annotation entries come from a "RuntimeVisibleAnnotations" attribute on a class file
- According to JVM specification, ch.4.7.16
"Each ClassFile, field_info, and method_info structure may contain at most one RuntimeVisibleAnnotations attribute"

Thus there is no need to create an array of attributes and enumerate all those, as there is either zero or one such attribute.

Removed:
    tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/Attribute.java
Modified:
    tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
    tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/Annotations.java
    tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java
    tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/JavaClass.java

Modified: tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=1624614&r1=1624613&r2=1624614&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Fri Sep 12 18:57:28 2014
@@ -1993,17 +1993,18 @@ public class ContextConfig implements Li
         String className = clazz.getClassName();
 
         AnnotationEntry[] annotationsEntries = clazz.getAnnotationEntries();
-
-        for (AnnotationEntry ae : annotationsEntries) {
-            String type = ae.getAnnotationType();
-            if ("Ljavax/servlet/annotation/WebServlet;".equals(type)) {
-                processAnnotationWebServlet(className, ae, fragment);
-            }else if ("Ljavax/servlet/annotation/WebFilter;".equals(type)) {
-                processAnnotationWebFilter(className, ae, fragment);
-            }else if ("Ljavax/servlet/annotation/WebListener;".equals(type)) {
-                fragment.addListener(className);
-            } else {
-                // Unknown annotation - ignore
+        if (annotationsEntries != null) {
+            for (AnnotationEntry ae : annotationsEntries) {
+                String type = ae.getAnnotationType();
+                if ("Ljavax/servlet/annotation/WebServlet;".equals(type)) {
+                    processAnnotationWebServlet(className, ae, fragment);
+                }else if ("Ljavax/servlet/annotation/WebFilter;".equals(type)) {
+                    processAnnotationWebFilter(className, ae, fragment);
+                }else if ("Ljavax/servlet/annotation/WebListener;".equals(type)) {
+                    fragment.addListener(className);
+                } else {
+                    // Unknown annotation - ignore
+                }
             }
         }
     }
@@ -2068,24 +2069,25 @@ public class ContextConfig implements Li
             for (Map.Entry<Class<?>, Set<ServletContainerInitializer>> entry :
                     typeInitializerMap.entrySet()) {
                 if (entry.getKey().isAnnotation()) {
-                    AnnotationEntry[] annotationEntries =
-                            javaClass.getAnnotationEntries();
-                    for (AnnotationEntry annotationEntry : annotationEntries) {
-                        if (entry.getKey().getName().equals(
-                                getClassName(annotationEntry.getAnnotationType()))) {
-                            if (clazz == null) {
-                                clazz = Introspection.loadClass(
-                                        context, className);
+                    AnnotationEntry[] annotationEntries = javaClass.getAnnotationEntries();
+                    if (annotationEntries != null) {
+                        for (AnnotationEntry annotationEntry : annotationEntries) {
+                            if (entry.getKey().getName().equals(
+                                    getClassName(annotationEntry.getAnnotationType()))) {
                                 if (clazz == null) {
-                                    // Can't load the class so no point
-                                    // continuing
-                                    return;
+                                    clazz = Introspection.loadClass(
+                                            context, className);
+                                    if (clazz == null) {
+                                        // Can't load the class so no point
+                                        // continuing
+                                        return;
+                                    }
                                 }
+                                for (ServletContainerInitializer sci : entry.getValue()) {
+                                    initializerClassMap.get(sci).add(clazz);
+                                }
+                                break;
                             }
-                            for (ServletContainerInitializer sci : entry.getValue()) {
-                                initializerClassMap.get(sci).add(clazz);
-                            }
-                            break;
                         }
                     }
                 }

Modified: tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/Annotations.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/Annotations.java?rev=1624614&r1=1624613&r2=1624614&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/Annotations.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/Annotations.java Fri Sep 12 18:57:28 2014
@@ -26,7 +26,7 @@ import java.io.IOException;
  * @author  <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
  * @since 6.0
  */
-public class Annotations extends Attribute {
+public class Annotations {
 
     private final AnnotationEntry[] annotation_table;
 

Modified: tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java?rev=1624614&r1=1624613&r2=1624614&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java Fri Sep 12 18:57:28 2014
@@ -48,7 +48,7 @@ public final class ClassParser {
     private int access_flags; // Access rights of parsed class
     private int[] interfaces; // Names of implemented interfaces
     private ConstantPool constant_pool; // collection of constants
-    private Attribute[] attributes; // attributes defined in the class
+    private Annotations runtimeVisibleAnnotations; // "RuntimeVisibleAnnotations" attribute defined in the class
     private static final int BUFSIZE = 8192;
 
 
@@ -99,24 +99,11 @@ public final class ClassParser {
         readMethods();
         // Read class attributes
         readAttributes();
-        // Check for unknown variables
-        //Unknown[] u = Unknown.getUnknownAttributes();
-        //for(int i=0; i < u.length; i++)
-        //  System.err.println("WARNING: " + u[i]);
-        // Everything should have been read now
-        //      if(file.available() > 0) {
-        //        int bytes = file.available();
-        //        byte[] buf = new byte[bytes];
-        //        file.read(buf);
-        //        if(!(is_zip && (buf.length == 1))) {
-        //          System.err.println("WARNING: Trailing garbage at end of " + file_name);
-        //          System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf));
-        //        }
-        //      }
 
         // Return the information we have gathered in a new object
         return new JavaClass(class_name_index, superclass_name_index,
-                access_flags, constant_pool, interfaces, attributes);
+                access_flags, constant_pool, interfaces,
+                runtimeVisibleAnnotations);
     }
 
 
@@ -128,9 +115,29 @@ public final class ClassParser {
     private void readAttributes() throws IOException, ClassFormatException {
         int attributes_count;
         attributes_count = file.readUnsignedShort();
-        attributes = new Attribute[attributes_count];
         for (int i = 0; i < attributes_count; i++) {
-            attributes[i] = Attribute.readAttribute(file, constant_pool);
+            ConstantUtf8 c;
+            String name;
+            int name_index;
+            int length;
+            // Get class name from constant pool via `name_index' indirection
+            name_index = file.readUnsignedShort();
+            c = (ConstantUtf8) constant_pool.getConstant(name_index,
+                    Constants.CONSTANT_Utf8);
+            name = c.getBytes();
+            // Length of data in bytes
+            length = file.readInt();
+
+            if (name.equals("RuntimeVisibleAnnotations")) {
+                if (runtimeVisibleAnnotations != null) {
+                    throw new ClassFormatException(
+                            "RuntimeVisibleAnnotations attribute is not allowed more than once in a class file");
+                }
+                runtimeVisibleAnnotations = new Annotations(file, constant_pool);
+            } else {
+                // All other attributes are skipped
+                Utility.skipFully(file, length);
+            }
         }
     }
 

Modified: tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/JavaClass.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/JavaClass.java?rev=1624614&r1=1624613&r2=1624614&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/JavaClass.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/JavaClass.java Fri Sep 12 18:57:28 2014
@@ -17,9 +17,6 @@
  */
 package org.apache.tomcat.util.bcel.classfile;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.tomcat.util.bcel.Constants;
 
 /**
@@ -37,12 +34,7 @@ public class JavaClass extends AccessFla
     private String class_name;
     private String superclass_name;
     private String[] interface_names;
-    private Attribute[] attributes; // attributes defined in the class
-    private AnnotationEntry[] annotations;   // annotations defined on the class
-
-
-    //  Annotations are collected from certain attributes, don't do it more than necessary!
-    private boolean annotationsOutOfDate = true;
+    private Annotations runtimeVisibleAnnotations; // "RuntimeVisibleAnnotations" attribute defined in the class
 
 
     /**
@@ -55,20 +47,16 @@ public class JavaClass extends AccessFla
      * @param access_flags Access rights defined by bit flags
      * @param constant_pool Array of constants
      * @param interfaces Implemented interfaces
-     * @param attributes Class attributes
+     * @param runtimeVisibleAnnotations "RuntimeVisibleAnnotations" attribute defined on the Class, or null
      */
     JavaClass(int class_name_index, int superclass_name_index,
             int access_flags, ConstantPool constant_pool, int[] interfaces,
-            Attribute[] attributes) {
+            Annotations runtimeVisibleAnnotations) {
         if (interfaces == null) {
             interfaces = new int[0];
         }
-        if (attributes == null) {
-            attributes = new Attribute[0];
-        }
         this.access_flags = access_flags;
-        this.attributes = attributes;
-        annotationsOutOfDate = true;
+        this.runtimeVisibleAnnotations = runtimeVisibleAnnotations;
 
         /* According to the specification the following entries must be of type
          * `ConstantClass' but we check that anyway via the
@@ -91,22 +79,17 @@ public class JavaClass extends AccessFla
         }
     }
 
-
+    /**
+     * Return annotations entries from "RuntimeVisibleAnnotations" attribute on
+     * the class, if there is any.
+     *
+     * @return An array of entries or {@code null}
+     */
     public AnnotationEntry[] getAnnotationEntries() {
-        if (annotationsOutOfDate) {
-            // Find attributes that contain annotation data
-            List<AnnotationEntry> accumulatedAnnotations = new ArrayList<>();
-            for (Attribute attribute : attributes) {
-                if (attribute instanceof Annotations) {
-                    Annotations runtimeAnnotations = (Annotations)attribute;
-                    for(int j = 0; j < runtimeAnnotations.getAnnotationEntries().length; j++)
-                        accumulatedAnnotations.add(runtimeAnnotations.getAnnotationEntries()[j]);
-                }
-            }
-            annotations = accumulatedAnnotations.toArray(new AnnotationEntry[accumulatedAnnotations.size()]);
-            annotationsOutOfDate = false;
+        if (runtimeVisibleAnnotations != null) {
+            return runtimeVisibleAnnotations.getAnnotationEntries();
         }
-        return annotations;
+        return null;
     }
 
     /**



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org