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.

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

mercurial