Move dump utilities into AndroidApp.

This CL also adds handling of duplicates and prepares for allowing compilation to continue after dumping inputs.

Change-Id: If1458c00aa1ac4ce3505109a4d78168705c8f536
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
index 6e95cac..4549d8e 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -7,17 +7,14 @@
 import static com.android.tools.r8.graph.ClassKind.LIBRARY;
 import static com.android.tools.r8.graph.ClassKind.PROGRAM;
 import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;
-import static com.android.tools.r8.utils.InternalOptions.ASM_VERSION;
 
 import com.android.tools.r8.ClassFileResourceProvider;
-import com.android.tools.r8.DataEntryResource;
 import com.android.tools.r8.DataResourceProvider;
 import com.android.tools.r8.ProgramResource;
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.ProgramResourceProvider;
 import com.android.tools.r8.ResourceException;
 import com.android.tools.r8.StringResource;
-import com.android.tools.r8.Version;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.graph.ClassKind;
 import com.android.tools.r8.graph.DexApplication;
@@ -43,38 +40,26 @@
 import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.Timing;
-import com.android.tools.r8.utils.ZipUtils;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.io.ByteStreams;
-import com.google.common.io.Closer;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.OpenOption;
 import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Queue;
-import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.stream.Collectors;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-import org.objectweb.asm.ClassVisitor;
 
 public class ApplicationReader {
 
   private final InternalOptions options;
   private final DexItemFactory itemFactory;
   private final Timing timing;
-  private final AndroidApp inputApp;
+  private AndroidApp inputApp;
 
   public interface ProgramClassConflictResolver {
     DexProgramClass resolveClassConflict(DexProgramClass a, DexProgramClass b);
@@ -123,7 +108,7 @@
       throws IOException, ExecutionException {
     assert verifyMainDexOptionsCompatible(inputApp, options);
     if (options.dumpInputToFile != null) {
-      dumpInputToFile();
+      inputApp = dumpInputToFile(inputApp, options);
       throw options.reporter.fatalError("Dumped compilation inputs to: " + options.dumpInputToFile);
     }
     timing.begin("DexApplication.read");
@@ -160,141 +145,9 @@
     return builder.build();
   }
 
-  private void dumpInputToFile() throws IOException  {
-    try {
-      List<ProgramResourceProvider> programResourceProviders =
-          inputApp.getProgramResourceProviders();
-      Set<DataEntryResource> dataEntryResources = inputApp.getDataEntryResourcesForTesting();
-      List<ProgramResource> programResourcesWithDescriptors = new ArrayList<>();
-      for (ProgramResourceProvider programResourceProvider : programResourceProviders) {
-        addProgramResourcesWithDescriptor(
-            programResourcesWithDescriptors, programResourceProvider.getProgramResources());
-      }
-
-      List<ProgramResource> libraryProgramResourcesWithDescriptors =
-          getProgramResourcesWithDescriptors(inputApp.getLibraryResourceProviders());
-
-      List<ProgramResource> classpathProgramResourcesWithDescriptors =
-          getProgramResourcesWithDescriptors(inputApp.getClasspathResourceProviders());
-
-      OpenOption[] openOptions =
-          new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
-      try (Closer closer = Closer.create()) {
-        try (ZipOutputStream out =
-            new ZipOutputStream(
-                Files.newOutputStream(Paths.get(options.dumpInputToFile), openOptions))) {
-          writeToZip(
-              dataEntryResources, programResourcesWithDescriptors, closer, out, "program.jar");
-          writeToZip(
-              ImmutableSet.of(),
-              libraryProgramResourcesWithDescriptors,
-              closer,
-              out,
-              "library.jar");
-          writeToZip(
-              ImmutableSet.of(),
-              classpathProgramResourcesWithDescriptors,
-              closer,
-              out,
-              "classpath.jar");
-          if (options.hasProguardConfiguration()) {
-            String proguardConfig = options.getProguardConfiguration().getParsedConfiguration();
-            ZipUtils.writeToZipStream(
-                out, "proguard.config", proguardConfig.getBytes(), ZipEntry.DEFLATED);
-          }
-
-          ZipUtils.writeToZipStream(
-              out, "r8-version", Version.getVersionString().getBytes(), ZipEntry.DEFLATED);
-        }
-      }
-    } catch (ResourceException e) {
-      options.reporter.fatalError("Failed to write input:" + e.getMessage());
-    }
-  }
-
-  private static void writeToZip(
-      Set<DataEntryResource> dataEntryResources,
-      List<ProgramResource> programResourcesWithDescriptors,
-      Closer closer,
-      ZipOutputStream out,
-      String entry)
-      throws IOException, ResourceException {
-    try (ByteArrayOutputStream programByteStream = new ByteArrayOutputStream()) {
-      try (ZipOutputStream archiveOutputStream = new ZipOutputStream(programByteStream)) {
-        ZipUtils.writeResourcesToZip(
-            programResourcesWithDescriptors, dataEntryResources, closer, archiveOutputStream);
-      }
-      ZipUtils.writeToZipStream(out, entry, programByteStream.toByteArray(), ZipEntry.DEFLATED);
-    }
-  }
-
-  private static List<ProgramResource> getProgramResourcesWithDescriptors(
-      List<ClassFileResourceProvider> classFileResourceProviders)
-      throws IOException, ResourceException {
-    ArrayList<ProgramResource> programResourcesWithDescriptors = new ArrayList<>();
-    for (ClassFileResourceProvider libraryResourceProvider : classFileResourceProviders) {
-      List<ProgramResource> programResources = new ArrayList<>();
-      for (String classDescriptor : libraryResourceProvider.getClassDescriptors()) {
-        programResources.add(libraryResourceProvider.getProgramResource(classDescriptor));
-      }
-      addProgramResourcesWithDescriptor(programResourcesWithDescriptors, programResources);
-    }
-    return programResourcesWithDescriptors;
-  }
-
-  private static void addProgramResourcesWithDescriptor(
-      List<ProgramResource> programResourcesWithDescriptors,
-      Collection<ProgramResource> programResources)
-      throws IOException, ResourceException {
-    for (ProgramResource programResource : programResources) {
-      if (programResource.getKind() != Kind.CF) {
-        continue;
-      }
-      try (InputStream inputStream = programResource.getByteStream()) {
-        byte[] bytes = ByteStreams.toByteArray(inputStream);
-        String descriptor = extractClassInternalType(bytes);
-        programResourcesWithDescriptors.add(
-            ProgramResource.fromBytes(
-                programResource.getOrigin(),
-                programResource.getKind(),
-                bytes,
-                ImmutableSet.of(descriptor)));
-      }
-    }
-  }
-
-  private static String extractClassInternalType(byte[] bytes) throws IOException {
-    class ClassNameExtractor extends ClassVisitor {
-      private String className;
-
-      private ClassNameExtractor() {
-        super(ASM_VERSION);
-      }
-
-      @Override
-      public void visit(
-          int version,
-          int access,
-          String name,
-          String signature,
-          String superName,
-          String[] interfaces) {
-        className = name;
-      }
-
-      String getDescriptor() {
-        return "L" + className + ";";
-      }
-    }
-
-    org.objectweb.asm.ClassReader reader = new org.objectweb.asm.ClassReader(bytes);
-    ClassNameExtractor extractor = new ClassNameExtractor();
-    reader.accept(
-        extractor,
-        org.objectweb.asm.ClassReader.SKIP_CODE
-            | org.objectweb.asm.ClassReader.SKIP_DEBUG
-            | org.objectweb.asm.ClassReader.SKIP_FRAMES);
-    return extractor.getDescriptor();
+  private static AndroidApp dumpInputToFile(AndroidApp app, InternalOptions options) {
+    return app.dump(
+        Paths.get(options.dumpInputToFile), options.getProguardConfiguration(), options.reporter);
   }
 
   private static boolean verifyMainDexOptionsCompatible(
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApp.java b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
index 1c3af7a..14f705e 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApp.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
@@ -7,6 +7,8 @@
 import static com.android.tools.r8.utils.FileUtils.isArchive;
 import static com.android.tools.r8.utils.FileUtils.isClassFile;
 import static com.android.tools.r8.utils.FileUtils.isDexFile;
+import static com.android.tools.r8.utils.InternalOptions.ASM_VERSION;
+import static com.android.tools.r8.utils.ZipUtils.writeToZipStream;
 
 import com.android.tools.r8.ClassFileConsumer;
 import com.android.tools.r8.ClassFileResourceProvider;
@@ -25,28 +27,39 @@
 import com.android.tools.r8.Resource;
 import com.android.tools.r8.ResourceException;
 import com.android.tools.r8.StringResource;
+import com.android.tools.r8.Version;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.errors.InternalCompilerError;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.origin.PathOrigin;
 import com.android.tools.r8.shaking.FilteredClassPath;
+import com.android.tools.r8.shaking.ProguardConfiguration;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.io.ByteStreams;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.nio.file.Files;
 import java.nio.file.NoSuchFileException;
+import java.nio.file.OpenOption;
 import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import org.objectweb.asm.ClassVisitor;
 
 /**
  * Collection of program files needed for processing.
@@ -382,6 +395,154 @@
     return programResourcesMainDescriptor.get(resource);
   }
 
+  public AndroidApp dump(Path output, ProguardConfiguration configuration, Reporter reporter) {
+    int nextDexIndex = 0;
+    Builder builder = AndroidApp.builder(reporter);
+    OpenOption[] openOptions =
+        new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
+    try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(output, openOptions))) {
+      writeToZipStream(out, "r8-version", Version.getVersionString().getBytes(), ZipEntry.DEFLATED);
+      if (configuration != null) {
+        String proguardConfig = configuration.getParsedConfiguration();
+        writeToZipStream(out, "proguard.config", proguardConfig.getBytes(), ZipEntry.DEFLATED);
+      }
+      nextDexIndex = dumpProgramResources("program.jar", nextDexIndex, out, builder);
+      nextDexIndex =
+          dumpClassFileResources(
+              "classpath.jar", nextDexIndex, out, builder, classpathResourceProviders);
+      nextDexIndex =
+          dumpClassFileResources(
+              "library.jar", nextDexIndex, out, builder, libraryResourceProviders);
+    } catch (IOException | ResourceException e) {
+      reporter.fatalError(new StringDiagnostic("Failed to dump inputs"), e);
+    }
+    return builder.build();
+  }
+
+  private int dumpProgramResources(
+      String archiveName, int nextDexIndex, ZipOutputStream out, Builder builder)
+      throws IOException, ResourceException {
+    try (ByteArrayOutputStream archiveByteStream = new ByteArrayOutputStream()) {
+      try (ZipOutputStream archiveOutputStream = new ZipOutputStream(archiveByteStream)) {
+        Set<String> seen = new HashSet<>();
+        Set<DataEntryResource> dataEntries = getDataEntryResourcesForTesting();
+        for (DataEntryResource dataResource : dataEntries) {
+          builder.addDataResources(dataResource);
+          String entryName = dataResource.getName();
+          try (InputStream dataStream = dataResource.getByteStream()) {
+            byte[] bytes = ByteStreams.toByteArray(dataStream);
+            writeToZipStream(out, entryName, bytes, ZipEntry.DEFLATED);
+          }
+        }
+        for (ProgramResourceProvider provider : programResourceProviders) {
+          for (ProgramResource programResource : provider.getProgramResources()) {
+            nextDexIndex =
+                dumpProgramResource(
+                    builder, seen, nextDexIndex, archiveOutputStream, programResource);
+          }
+        }
+      }
+      writeToZipStream(out, archiveName, archiveByteStream.toByteArray(), ZipEntry.DEFLATED);
+    }
+    return nextDexIndex;
+  }
+
+  private static int dumpClassFileResources(
+      String archiveName,
+      int nextDexIndex,
+      ZipOutputStream out,
+      Builder builder,
+      ImmutableList<ClassFileResourceProvider> classpathResourceProviders)
+      throws IOException, ResourceException {
+    try (ByteArrayOutputStream archiveByteStream = new ByteArrayOutputStream()) {
+      try (ZipOutputStream archiveOutputStream = new ZipOutputStream(archiveByteStream)) {
+        Set<String> seen = new HashSet<>();
+        for (ClassFileResourceProvider provider : classpathResourceProviders) {
+          for (String descriptor : provider.getClassDescriptors()) {
+            ProgramResource programResource = provider.getProgramResource(descriptor);
+            int oldDexIndex = nextDexIndex;
+            nextDexIndex =
+                dumpProgramResource(
+                    builder, seen, nextDexIndex, archiveOutputStream, programResource);
+            assert nextDexIndex == oldDexIndex;
+          }
+        }
+      }
+      writeToZipStream(out, archiveName, archiveByteStream.toByteArray(), ZipEntry.DEFLATED);
+    }
+    return nextDexIndex;
+  }
+
+  private static int dumpProgramResource(
+      Builder builder,
+      Set<String> seen,
+      int nextDexIndex,
+      ZipOutputStream archiveOutputStream,
+      ProgramResource programResource)
+      throws ResourceException, IOException {
+    byte[] bytes = ByteStreams.toByteArray(programResource.getByteStream());
+    Set<String> classDescriptors = programResource.getClassDescriptors();
+    if (classDescriptors.size() != 1 && programResource.getKind() == Kind.CF) {
+      classDescriptors = Collections.singleton(extractClassDescriptor(bytes));
+    }
+    if (programResource instanceof OneShotByteResource) {
+      builder.addProgramResources(
+          OneShotByteResource.create(
+              programResource.getKind(), programResource.getOrigin(), bytes, classDescriptors));
+
+    } else {
+      builder.addProgramResources(programResource);
+    }
+    String entryName;
+    if (programResource.getKind() == Kind.CF) {
+      String classDescriptor =
+          classDescriptors.size() == 1
+              ? classDescriptors.iterator().next()
+              : extractClassDescriptor(bytes);
+      String classFileName = DescriptorUtils.getClassFileName(classDescriptor);
+      entryName = seen.add(classDescriptor) ? classFileName : (classFileName + ".dup");
+    } else {
+      assert programResource.getKind() == Kind.DEX;
+      entryName = "classes" + nextDexIndex++ + ".dex";
+    }
+    writeToZipStream(archiveOutputStream, entryName, bytes, ZipEntry.DEFLATED);
+    return nextDexIndex;
+  }
+
+  private static String extractClassDescriptor(byte[] bytes) {
+    class ClassNameExtractor extends ClassVisitor {
+      private String className;
+
+      private ClassNameExtractor() {
+        super(ASM_VERSION);
+      }
+
+      @Override
+      public void visit(
+          int version,
+          int access,
+          String name,
+          String signature,
+          String superName,
+          String[] interfaces) {
+        className = name;
+      }
+
+      String getDescriptor() {
+        return "L" + className + ";";
+      }
+    }
+
+    org.objectweb.asm.ClassReader reader = new org.objectweb.asm.ClassReader(bytes);
+    ClassNameExtractor extractor = new ClassNameExtractor();
+    reader.accept(
+        extractor,
+        org.objectweb.asm.ClassReader.SKIP_CODE
+            | org.objectweb.asm.ClassReader.SKIP_DEBUG
+            | org.objectweb.asm.ClassReader.SKIP_FRAMES);
+    return extractor.getDescriptor();
+  }
+
   /**
    * Builder interface for constructing an AndroidApp.
    */
diff --git a/src/main/java/com/android/tools/r8/utils/OneShotByteResource.java b/src/main/java/com/android/tools/r8/utils/OneShotByteResource.java
index da958c3..1dfbc64 100644
--- a/src/main/java/com/android/tools/r8/utils/OneShotByteResource.java
+++ b/src/main/java/com/android/tools/r8/utils/OneShotByteResource.java
@@ -17,7 +17,7 @@
   private byte[] bytes;
   private final Set<String> classDescriptors;
 
-  static ProgramResource create(
+  public static OneShotByteResource create(
       Kind kind, Origin origin, byte[] bytes, Set<String> classDescriptors) {
     return new OneShotByteResource(origin, kind, bytes, classDescriptors);
   }
diff --git a/src/test/java/com/android/tools/r8/DumpInputsTest.java b/src/test/java/com/android/tools/r8/DumpInputsTest.java
new file mode 100644
index 0000000..3c2d9b3
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/DumpInputsTest.java
@@ -0,0 +1,72 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.ZipUtils;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class DumpInputsTest extends TestBase {
+
+  static final String EXPECTED = StringUtils.lines("Hello, world");
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withCfRuntime(CfVm.JDK9).build();
+  }
+
+  public DumpInputsTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    Path dump = temp.newFolder().toPath().resolve("dump.zip");
+    try {
+      testForExternalR8(parameters.getBackend())
+          .useExternalJDK(parameters.getRuntime().asCf().getVm())
+          .addJvmFlag("-Dcom.android.tools.r8.dumpinputtofile=" + dump)
+          .addProgramClasses(TestClass.class)
+          .compile();
+    } catch (AssertionError e) {
+      assertTrue(Files.exists(dump));
+      Path unzipped = temp.newFolder().toPath();
+      ZipUtils.unzip(dump.toString(), unzipped.toFile());
+      assertTrue(Files.exists(unzipped.resolve("program.jar")));
+      assertTrue(Files.exists(unzipped.resolve("classpath.jar")));
+      assertTrue(Files.exists(unzipped.resolve("proguard.config")));
+      assertTrue(Files.exists(unzipped.resolve("r8-version")));
+      Set<String> entries = new HashSet<>();
+      ZipUtils.iter(
+          unzipped.resolve("program.jar").toString(),
+          (entry, input) -> entries.add(entry.getName()));
+      assertTrue(
+          entries.contains(
+              DescriptorUtils.getClassFileName(
+                  DescriptorUtils.javaTypeToDescriptor(TestClass.class.getTypeName()))));
+      return;
+    }
+    fail("Expected external compilation to exit");
+  }
+
+  static class TestClass {
+    public static void main(String[] args) {
+      System.out.println("Hello, world");
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ExternalR8TestBuilder.java b/src/test/java/com/android/tools/r8/ExternalR8TestBuilder.java
index 0328184..ae4a36c 100644
--- a/src/test/java/com/android/tools/r8/ExternalR8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/ExternalR8TestBuilder.java
@@ -57,6 +57,8 @@
 
   private boolean addR8ExternalDeps = false;
 
+  private List<String> jvmFlags = new ArrayList<>();
+
   private ExternalR8TestBuilder(TestState state, Builder builder, Backend backend) {
     super(state, builder, backend);
   }
@@ -72,7 +74,7 @@
 
   public ExternalR8TestBuilder useExternalJDK(CfVm externalJDK) {
     this.externalJDK = externalJDK;
-    return this;
+    return self();
   }
 
   private String getJDKToRun() {
@@ -82,6 +84,11 @@
     return getJavaExecutable(externalJDK);
   }
 
+  public ExternalR8TestBuilder addJvmFlag(String flag) {
+    jvmFlags.add(flag);
+    return self();
+  }
+
   @Override
   ExternalR8TestCompileResult internalCompile(
       Builder builder, Consumer<InternalOptions> optionsConsumer, Supplier<AndroidApp> app)
@@ -99,9 +106,12 @@
               : r8jar.toAbsolutePath().toString();
 
       List<String> command = new ArrayList<>();
+      Collections.addAll(command, getJDKToRun());
+
+      command.addAll(jvmFlags);
+
       Collections.addAll(
           command,
-          getJDKToRun(),
           "-ea",
           "-cp",
           classPath,
diff --git a/src/test/java/com/android/tools/r8/R8EntryPointTests.java b/src/test/java/com/android/tools/r8/R8EntryPointTests.java
index 553ff0e..0bbc7bc 100644
--- a/src/test/java/com/android/tools/r8/R8EntryPointTests.java
+++ b/src/test/java/com/android/tools/r8/R8EntryPointTests.java
@@ -9,20 +9,13 @@
 
 import com.android.tools.r8.ToolHelper.ProcessResult;
 import com.android.tools.r8.utils.FileUtils;
-import com.android.tools.r8.utils.ZipUtils;
-import com.android.tools.r8.utils.ZipUtils.OnEntryHandler;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
-import java.io.InputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.zip.ZipEntry;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -180,53 +173,6 @@
   }
 
   @Test
-  public void testDumpInputs() throws IOException {
-    Path out = temp.newFile("dex.zip").toPath();
-    Path dump = temp.newFile("dump.zip").toPath();
-    ProcessResult r8 =
-        ToolHelper.forkR8WithJavaOptions(
-            Paths.get("."),
-            ImmutableList.of("-Dcom.android.tools.r8.dumpinputtofile=" + dump.toString()),
-            "--lib",
-            ToolHelper.getDefaultAndroidJar().toString(),
-            "--dex",
-            "--output",
-            out.toString(),
-            "--pg-conf",
-            PROGUARD_FLAGS.toString(),
-            "--pg-conf",
-            testFlags.toString(),
-            INPUT_JAR.toString());
-
-    List<ZipEntry> entries = new ArrayList<>();
-    ZipUtils.iter(
-        dump.toString(),
-        new OnEntryHandler() {
-          @Override
-          public void onEntry(ZipEntry entry, InputStream input) throws IOException {
-            entries.add(entry);
-          }
-        });
-    Assert.assertTrue(hasEntry(entries, "program.jar"));
-    Assert.assertTrue(hasEntry(entries, "library.jar"));
-    Assert.assertTrue(hasEntry(entries, "classpath.jar"));
-    Assert.assertTrue(hasEntry(entries, "proguard.config"));
-    Assert.assertTrue(hasEntry(entries, "r8-version"));
-    // When dumping the inputs we throw an error in the program to exit early.
-    Assert.assertNotEquals(0, r8.exitCode);
-  }
-
-  private boolean hasEntry(Collection<ZipEntry> entries, String name) {
-    for (ZipEntry entry : entries) {
-      if (entry.getName().equals(name)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  @Test
   public void testSpecifyDexAndClassfileNotAllowed() throws IOException, InterruptedException {
     Path out = temp.newFile("dex.zip").toPath();
     ProcessResult r8 =