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:dbros...@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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org