Tue, 06 Jan 2015 21:39:09 +0100
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 }