diff options
author | kmb <kmb@google.com> | 2017-08-04 19:28:56 +0200 |
---|---|---|
committer | Jakob Buchgraber <buchgr@google.com> | 2017-08-07 11:22:05 +0200 |
commit | ce61d638197251f71ed90db74843b55d9c2e9ae5 (patch) | |
tree | d377bf5c5366ad90fe9bcd1c2514bbd11779a852 | |
parent | 2266a6f88030e7121031db19fb5efc3fc7cb149c (diff) |
don't use methods and classes removed in upstream dx
RELNOTES: update dexing tools to Android SDK 26.0.1
PiperOrigin-RevId: 164278101
8 files changed, 63 insertions, 36 deletions
diff --git a/src/test/java/com/google/devtools/build/android/dexer/DexBuilderTest.java b/src/test/java/com/google/devtools/build/android/dexer/DexBuilderTest.java index 5adca31806..01236b3e4c 100644 --- a/src/test/java/com/google/devtools/build/android/dexer/DexBuilderTest.java +++ b/src/test/java/com/google/devtools/build/android/dexer/DexBuilderTest.java @@ -43,7 +43,7 @@ public class DexBuilderTest { options.outputZip = FileSystems.getDefault().getPath(System.getenv("TEST_TMPDIR"), "dex_builder_test.zip"); options.maxThreads = 1; - DexBuilder.buildDexArchive(options, new Dexing.DexingOptions()); + DexBuilder.buildDexArchive(options, new Dexing(new Dexing.DexingOptions())); assertThat(options.outputZip.toFile().exists()).isTrue(); HashSet<String> files = new HashSet<>(); diff --git a/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java b/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java index b71020740f..2c27f4b428 100644 --- a/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java +++ b/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.fail; import static org.mockito.Mockito.when; import com.android.dex.Dex; +import com.android.dx.command.dexer.DxContext; import com.android.dx.dex.DexOptions; import com.android.dx.dex.cf.CfOptions; import com.google.common.cache.Cache; @@ -64,7 +65,7 @@ public class DexConversionEnqueuerTest { new DexConversionEnqueuer( zip, newDirectExecutorService(), - new DexConverter(new Dexing(new DexOptions(), new CfOptions())), + new DexConverter(new Dexing(new DxContext(), new DexOptions(), new CfOptions())), cache); } diff --git a/src/test/java/com/google/devtools/build/android/dexer/DexFileAggregatorTest.java b/src/test/java/com/google/devtools/build/android/dexer/DexFileAggregatorTest.java index 7bc9ded10d..89b40aa372 100644 --- a/src/test/java/com/google/devtools/build/android/dexer/DexFileAggregatorTest.java +++ b/src/test/java/com/google/devtools/build/android/dexer/DexFileAggregatorTest.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import com.android.dex.Dex; +import com.android.dx.command.dexer.DxContext; import com.android.dx.dex.DexOptions; import com.android.dx.dex.cf.CfOptions; import com.android.dx.dex.file.DexFile; @@ -59,14 +60,15 @@ public class DexFileAggregatorTest { @Test public void testClose_emptyWritesNothing() throws Exception { DexFileAggregator dexer = - new DexFileAggregator(dest, MultidexStrategy.MINIMAL, DEX_LIMIT, WASTE); + new DexFileAggregator(new DxContext(), dest, MultidexStrategy.MINIMAL, DEX_LIMIT, WASTE); dexer.close(); verify(dest, times(0)).addFile(any(ZipEntry.class), any(Dex.class)); } @Test public void testAddAndClose_singleInputWritesThatInput() throws Exception { - DexFileAggregator dexer = new DexFileAggregator(dest, MultidexStrategy.MINIMAL, 0, WASTE); + DexFileAggregator dexer = + new DexFileAggregator(new DxContext(), dest, MultidexStrategy.MINIMAL, 0, WASTE); dexer.add(dex); dexer.close(); verify(dest).addFile(any(ZipEntry.class), eq(dex)); @@ -74,8 +76,8 @@ public class DexFileAggregatorTest { @Test public void testMultidex_underLimitWritesOneShard() throws Exception { - DexFileAggregator dexer = - new DexFileAggregator(dest, MultidexStrategy.BEST_EFFORT, DEX_LIMIT, WASTE); + DexFileAggregator dexer = new DexFileAggregator( + new DxContext(), dest, MultidexStrategy.BEST_EFFORT, DEX_LIMIT, WASTE); Dex dex2 = DexFiles.toDex(convertClass(ByteStreams.class)); dexer.add(dex); dexer.add(dex2); @@ -87,8 +89,8 @@ public class DexFileAggregatorTest { @Test public void testMultidex_overLimitWritesSecondShard() throws Exception { - DexFileAggregator dexer = new DexFileAggregator(dest, MultidexStrategy.BEST_EFFORT, - 2 /* dex has more than 2 methods and fields */, WASTE); + DexFileAggregator dexer = new DexFileAggregator(new DxContext(), dest, + MultidexStrategy.BEST_EFFORT, 2 /* dex has more than 2 methods and fields */, WASTE); Dex dex2 = DexFiles.toDex(convertClass(ByteStreams.class)); dexer.add(dex); // classFile is already over limit but we take anything in empty shard dexer.add(dex2); // this should start a new shard @@ -101,7 +103,7 @@ public class DexFileAggregatorTest { @Test public void testMonodex_alwaysWritesSingleShard() throws Exception { - DexFileAggregator dexer = new DexFileAggregator(dest, MultidexStrategy.OFF, + DexFileAggregator dexer = new DexFileAggregator(new DxContext(), dest, MultidexStrategy.OFF, 2 /* dex has more than 2 methods and fields */, WASTE); Dex dex2 = DexFiles.toDex(convertClass(ByteStreams.class)); dexer.add(dex); @@ -116,7 +118,7 @@ public class DexFileAggregatorTest { String path = clazz.getName().replace('.', '/') + ".class"; try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(path)) { - return new DexConverter(new Dexing(new DexOptions(), new CfOptions())) + return new DexConverter(new Dexing(new DxContext(), new DexOptions(), new CfOptions())) .toDexFile(ByteStreams.toByteArray(in), path); } } diff --git a/src/test/java/com/google/devtools/build/android/dexer/DexFileMergerTest.java b/src/test/java/com/google/devtools/build/android/dexer/DexFileMergerTest.java index 226561b559..60b53094ac 100644 --- a/src/test/java/com/google/devtools/build/android/dexer/DexFileMergerTest.java +++ b/src/test/java/com/google/devtools/build/android/dexer/DexFileMergerTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.fail; import com.android.dex.ClassDef; import com.android.dex.Dex; +import com.android.dx.command.dexer.DxContext; import com.google.common.base.Function; import com.google.common.base.Predicates; import com.google.common.collect.HashMultimap; @@ -259,7 +260,7 @@ public class DexFileMergerTest { options.outputZip = FileSystems.getDefault().getPath(System.getenv("TEST_TMPDIR"), "libtests.dex.zip"); options.maxThreads = 1; - DexBuilder.buildDexArchive(options, new Dexing.DexingOptions()); + DexBuilder.buildDexArchive(options, new Dexing(new DxContext(), new Dexing.DexingOptions())); return options.outputZip; } diff --git a/src/tools/android/java/com/google/devtools/build/android/dexer/DexBuilder.java b/src/tools/android/java/com/google/devtools/build/android/dexer/DexBuilder.java index 6cee5cfc93..eadc42532f 100644 --- a/src/tools/android/java/com/google/devtools/build/android/dexer/DexBuilder.java +++ b/src/tools/android/java/com/google/devtools/build/android/dexer/DexBuilder.java @@ -17,7 +17,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static java.util.concurrent.Executors.newFixedThreadPool; -import com.android.dx.command.DxConsole; +import com.android.dx.command.dexer.DxContext; import com.google.common.annotations.VisibleForTesting; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; @@ -120,13 +120,12 @@ class DexBuilder { if (options.persistentWorker) { runPersistentWorker(); } else { - buildDexArchive(options, optionsParser.getOptions(DexingOptions.class)); + buildDexArchive(options, new Dexing(optionsParser.getOptions(DexingOptions.class))); } } @VisibleForTesting - static void buildDexArchive(Options options, DexingOptions dexingOptions) - throws Exception { + static void buildDexArchive(Options options, Dexing dexing) throws Exception { checkArgument(options.maxThreads > 0, "--max_threads must be strictly positive, was: %s", options.maxThreads); try (ZipFile in = new ZipFile(options.inputJar.toFile())) { @@ -134,7 +133,7 @@ class DexBuilder { int threads = Math.min(options.maxThreads, in.size() / 1000 + 1); ExecutorService executor = newFixedThreadPool(threads); try (ZipOutputStream out = createZipOutputStream(options.outputZip)) { - produceDexArchive(in, out, executor, threads <= 1, dexingOptions, null); + produceDexArchive(in, out, executor, threads <= 1, dexing, null); } finally { executor.shutdown(); } @@ -169,11 +168,11 @@ class DexBuilder { // Redirect dx's output so we can return it in response ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos, /*autoFlush*/ true); - DxConsole.out = DxConsole.err = ps; + DxContext context = new DxContext(ps, ps); // Make sure that we exit nonzero in case uncaught errors occur during processRequest. int exitCode = 1; try { - processRequest(executor, dexCache, request.getArgumentsList()); + processRequest(executor, dexCache, context, request.getArgumentsList()); exitCode = 0; // success! } catch (Exception e) { // Deliberate catch-all so we can capture a stack trace. @@ -206,7 +205,10 @@ class DexBuilder { } private static void processRequest( - ExecutorService executor, Cache<DexingKey, byte[]> dexCache, List<String> args) + ExecutorService executor, + Cache<DexingKey, byte[]> dexCache, + DxContext context, + List<String> args) throws OptionsParsingException, IOException, InterruptedException, ExecutionException { OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class, DexingOptions.class); @@ -220,7 +222,7 @@ class DexBuilder { out, executor, /*convertOnReaderThread*/ false, - optionsParser.getOptions(DexingOptions.class), + new Dexing(context, optionsParser.getOptions(DexingOptions.class)), dexCache); } // Use input's timestamp for output file so the output file is stable. @@ -236,7 +238,7 @@ class DexBuilder { ZipOutputStream out, ExecutorService executor, boolean convertOnReaderThread, - DexingOptions dexingOptions, + Dexing dexing, @Nullable Cache<DexingKey, byte[]> dexCache) throws InterruptedException, ExecutionException, IOException { // If we only have one thread in executor, we give a "direct" executor to the stuffer, which @@ -245,7 +247,7 @@ class DexBuilder { // the stuffer is still working its way through the input. DexConversionEnqueuer enqueuer = new DexConversionEnqueuer(in, convertOnReaderThread ? MoreExecutors.newDirectExecutorService() : executor, - new DexConverter(new Dexing(dexingOptions)), + new DexConverter(dexing), dexCache); Future<?> enqueuerTask = executor.submit(enqueuer); while (true) { diff --git a/src/tools/android/java/com/google/devtools/build/android/dexer/DexFileAggregator.java b/src/tools/android/java/com/google/devtools/build/android/dexer/DexFileAggregator.java index 0b0a27c61e..bd7d572fe2 100644 --- a/src/tools/android/java/com/google/devtools/build/android/dexer/DexFileAggregator.java +++ b/src/tools/android/java/com/google/devtools/build/android/dexer/DexFileAggregator.java @@ -19,6 +19,9 @@ import com.android.dex.Dex; import com.android.dex.DexFormat; import com.android.dex.FieldId; import com.android.dex.MethodId; +import com.android.dex.ProtoId; +import com.android.dex.TypeList; +import com.android.dx.command.dexer.DxContext; import com.android.dx.merge.CollisionPolicy; import com.android.dx.merge.DexMerger; import com.google.auto.value.AutoValue; @@ -55,14 +58,17 @@ class DexFileAggregator implements Closeable { private final int maxNumberOfIdxPerDex; private final int wasteThresholdPerDex; private final MultidexStrategy multidex; + private final DxContext context; private DexFileArchive dest; private int nextDexFileIndex = 0; public DexFileAggregator( + DxContext context, DexFileArchive dest, MultidexStrategy multidex, int maxNumberOfIdxPerDex, int wasteThresholdPerDex) { + this.context = context; this.dest = dest; this.multidex = multidex; this.maxNumberOfIdxPerDex = maxNumberOfIdxPerDex; @@ -145,7 +151,7 @@ class DexFileAggregator implements Closeable { return dexes[0]; default: try { - DexMerger dexMerger = new DexMerger(dexes, CollisionPolicy.FAIL); + DexMerger dexMerger = new DexMerger(dexes, CollisionPolicy.FAIL, context); dexMerger.setCompactWasteThreshold(wasteThresholdPerDex); return dexMerger.merge(); } catch (BufferOverflowException e) { @@ -195,12 +201,13 @@ class DexFileAggregator implements Closeable { abstract static class MethodDescriptor { static MethodDescriptor fromDex(Dex dex, int methodIndex) { MethodId method = dex.methodIds().get(methodIndex); + ProtoId proto = dex.protoIds().get(method.getProtoIndex()); String name = dex.strings().get(method.getNameIndex()); String declaringClass = typeName(dex, method.getDeclaringClassIndex()); - String returnType = typeName(dex, dex.returnTypeIndexFromMethodIndex(methodIndex)); - short[] parameterTypeIndices = dex.parameterTypeIndicesFromMethodIndex(methodIndex); + String returnType = typeName(dex, proto.getReturnTypeIndex()); + TypeList parameterTypeIndices = dex.readTypeList(proto.getParametersOffset()); ImmutableList.Builder<String> parameterTypes = ImmutableList.builder(); - for (short parameterTypeIndex : parameterTypeIndices) { + for (short parameterTypeIndex : parameterTypeIndices.getTypes()) { parameterTypes.add(typeName(dex, parameterTypeIndex & 0xFFFF)); } return new AutoValue_DexFileAggregator_MethodDescriptor( diff --git a/src/tools/android/java/com/google/devtools/build/android/dexer/DexFileMerger.java b/src/tools/android/java/com/google/devtools/build/android/dexer/DexFileMerger.java index 7c44ade68f..d81befc374 100644 --- a/src/tools/android/java/com/google/devtools/build/android/dexer/DexFileMerger.java +++ b/src/tools/android/java/com/google/devtools/build/android/dexer/DexFileMerger.java @@ -19,7 +19,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.android.dex.Dex; import com.android.dex.DexFormat; -import com.android.dx.command.DxConsole; +import com.android.dx.command.dexer.DxContext; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Predicate; import com.google.common.base.Predicates; @@ -188,9 +188,10 @@ class DexFileMerger { DexFileAggregator out = createDexFileAggregator(options)) { checkForUnprocessedClasses(zip); if (!options.verbose) { - // com.android.dx.merge.DexMerger prints tons of debug information to System.out that we - // silence here unless it was explicitly requested. - System.setOut(DxConsole.noop); + // com.android.dx.merge.DexMerger prints status information to System.out that we silence + // here unless it was explicitly requested. (It also prints debug info to DxContext.out, + // which we populate accordingly below.) + System.setOut(Dexing.nullout); } if (classesInMainDex == null) { @@ -262,6 +263,7 @@ class DexFileMerger { private static DexFileAggregator createDexFileAggregator(Options options) throws IOException { return new DexFileAggregator( + new DxContext(options.verbose ? System.out : ByteStreams.nullOutputStream(), System.err), new DexFileArchive( new ZipOutputStream( new BufferedOutputStream(Files.newOutputStream(options.outputArchive)))), diff --git a/src/tools/android/java/com/google/devtools/build/android/dexer/Dexing.java b/src/tools/android/java/com/google/devtools/build/android/dexer/Dexing.java index 56e210f75e..ca5dba24ae 100644 --- a/src/tools/android/java/com/google/devtools/build/android/dexer/Dexing.java +++ b/src/tools/android/java/com/google/devtools/build/android/dexer/Dexing.java @@ -15,7 +15,7 @@ package com.google.devtools.build.android.dexer; import com.android.dx.cf.direct.DirectClassFile; import com.android.dx.cf.direct.StdAttributeFactory; -import com.android.dx.command.DxConsole; +import com.android.dx.command.dexer.DxContext; import com.android.dx.dex.DexOptions; import com.android.dx.dex.cf.CfOptions; import com.android.dx.dex.cf.CfTranslator; @@ -25,16 +25,20 @@ import com.android.dx.dex.file.DexFile; import com.android.dx.util.ByteArray; import com.google.auto.value.AutoValue; import com.google.common.annotations.VisibleForTesting; +import com.google.common.io.ByteStreams; import com.google.devtools.common.options.Option; import com.google.devtools.common.options.OptionDocumentationCategory; import com.google.devtools.common.options.OptionEffectTag; import com.google.devtools.common.options.OptionsBase; +import java.io.PrintStream; /** * Common helper class that encodes Java classes into {@link DexFile}s. */ class Dexing { + static final PrintStream nullout = new PrintStream(ByteStreams.nullOutputStream()); + /** * Common command line options for use with {@link Dexing}. */ @@ -73,11 +77,11 @@ class Dexing { ) public boolean printWarnings; - public CfOptions toCfOptions() { + public CfOptions toCfOptions(DxContext context) { CfOptions result = new CfOptions(); result.localInfo = this.localInfo; result.optimize = this.optimize; - result.warn = printWarnings ? DxConsole.err : DxConsole.noop; + result.warn = printWarnings ? context.err : Dexing.nullout; // Use dx's defaults result.optimizeListFile = null; result.dontOptimizeListFile = null; @@ -114,15 +118,21 @@ class Dexing { @SuppressWarnings("mutable") abstract byte[] classfileContent(); } + private final DxContext context; private final DexOptions dexOptions; private final CfOptions cfOptions; public Dexing(DexingOptions options) { - this(options.toDexOptions(), options.toCfOptions()); + this(new DxContext(), options); + } + + public Dexing(DxContext context, DexingOptions options) { + this(context, options.toDexOptions(), options.toCfOptions(context)); } @VisibleForTesting - Dexing(DexOptions dexOptions, CfOptions cfOptions) { + Dexing(DxContext context, DexOptions dexOptions, CfOptions cfOptions) { + this.context = context; this.dexOptions = dexOptions; this.cfOptions = cfOptions; } @@ -140,7 +150,9 @@ class Dexing { } public ClassDefItem addToDexFile(DexFile dest, DirectClassFile classFile) { - ClassDefItem result = CfTranslator.translate(classFile, + ClassDefItem result = CfTranslator.translate( + context, + classFile, (byte[]) null /*ignored*/, cfOptions, dest.getDexOptions(), |