build/annotationProcessors/classloader/JarClassIterator.java

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 package org.mozilla.gecko.annotationProcessors.classloader;
     7 import java.lang.annotation.Annotation;
     8 import java.lang.reflect.InvocationTargetException;
     9 import java.lang.reflect.Method;
    10 import java.util.Iterator;
    12 /**
    13  * Class for iterating over an IterableJarLoadingURLClassLoader's classes.
    14  */
    15 public class JarClassIterator implements Iterator<ClassWithOptions> {
    16     private IterableJarLoadingURLClassLoader mTarget;
    17     private Iterator<String> mTargetClassListIterator;
    19     public JarClassIterator(IterableJarLoadingURLClassLoader aTarget) {
    20         mTarget = aTarget;
    21         mTargetClassListIterator = aTarget.classNames.iterator();
    22     }
    24     @Override
    25     public boolean hasNext() {
    26         return mTargetClassListIterator.hasNext();
    27     }
    29     @Override
    30     public ClassWithOptions next() {
    31         String className = mTargetClassListIterator.next();
    32         try {
    33             Class<?> ret = mTarget.loadClass(className);
    34             final String canonicalName;
    36             // Incremental builds can leave stale classfiles in the jar. Such classfiles will cause
    37             // an exception at this point. We can safely ignore these classes - they cannot possibly
    38             // ever be loaded as they conflict with their parent class and will be killed by Proguard
    39             // later on anyway.
    40             try {
    41                 canonicalName = ret.getCanonicalName();
    42             } catch (IncompatibleClassChangeError e) {
    43                 return next();
    44             }
    46             if (canonicalName == null || "null".equals(canonicalName)) {
    47                 // Anonymous inner class - unsupported.
    48                 return next();
    49             } else {
    50                 String generateName = null;
    51                 for (Annotation annotation : ret.getAnnotations()) {
    52                     Class<?> annotationType = annotation.annotationType();
    53                     if (annotationType.getCanonicalName().equals("org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions")) {
    54                         try {
    55                             // Determine the explicitly-given name of the stub to generate, if any.
    56                             final Method generateNameMethod = annotationType.getDeclaredMethod("generatedClassName");
    57                             generateNameMethod.setAccessible(true);
    58                             generateName = (String) generateNameMethod.invoke(annotation);
    59                             break;
    60                         } catch (NoSuchMethodException e) {
    61                             System.err.println("Unable to find expected field on GeneratorOptions annotation. Did the signature change?");
    62                             e.printStackTrace(System.err);
    63                             System.exit(3);
    64                         } catch (IllegalAccessException e) {
    65                             System.err.println("IllegalAccessException reading fields on GeneratorOptions annotation. Seems the semantics of Reflection have changed...");
    66                             e.printStackTrace(System.err);
    67                             System.exit(4);
    68                         } catch (InvocationTargetException e) {
    69                             System.err.println("InvocationTargetException reading fields on GeneratorOptions annotation. This really shouldn't happen.");
    70                             e.printStackTrace(System.err);
    71                             System.exit(5);
    72                         }
    73                     }
    74                 }
    75                 if (generateName == null) {
    76                     generateName = ret.getSimpleName();
    77                 }
    78                 return new ClassWithOptions(ret, generateName);
    79             }
    80         } catch (ClassNotFoundException e) {
    81             System.err.println("Unable to enumerate class: " + className + ". Corrupted jar file?");
    82             e.printStackTrace();
    83             System.exit(2);
    84         }
    85         return null;
    86     }
    88     @Override
    89     public void remove() {
    90         throw new UnsupportedOperationException("Removal of classes from iterator not supported.");
    91     }
    92 }

mercurial