Revert "Read the app once while converting specification"

Revert submission 66404

Reason for revert:broken bots
Reverted Changes:
I69a982c9a:Read the app once while converting specification
Ib894f9bd9:Use LazyLoadedDexApp on Specification conversion

Change-Id: Ie9600e84af9681aeb5c8c58c6e6481aff2c6d70e
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAmender.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAmender.java
index 62f6e56..bd146e9 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAmender.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAmender.java
@@ -4,14 +4,11 @@
 
 package com.android.tools.r8.ir.desugar.desugaredlibrary;
 
-import com.android.tools.r8.androidapi.ComputedApiLevel;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.MethodAccessFlags;
-import com.android.tools.r8.utils.Reporter;
 import java.util.Map;
 
 /**
@@ -21,34 +18,21 @@
  */
 public class DesugaredLibraryAmender {
 
-  private final DexDefinitionSupplier definitions;
-  private final Reporter reporter;
-  private final ComputedApiLevel minAPILevel;
+  private final AppView<?> appView;
 
   public static void run(AppView<?> appView) {
-    run(
-        appView,
-        appView.options().reporter,
-        appView.computedMinApiLevel(),
-        appView.options().machineDesugaredLibrarySpecification.getAmendLibraryMethods());
+    run(appView, appView.options().machineDesugaredLibrarySpecification.getAmendLibraryMethods());
   }
 
-  public static void run(
-      DexDefinitionSupplier definitions,
-      Reporter reporter,
-      ComputedApiLevel minAPILevel,
-      Map<DexMethod, MethodAccessFlags> amendLibrary) {
+  public static void run(AppView<?> appView, Map<DexMethod, MethodAccessFlags> amendLibrary) {
     if (amendLibrary.isEmpty()) {
       return;
     }
-    new DesugaredLibraryAmender(definitions, reporter, minAPILevel).run(amendLibrary);
+    new DesugaredLibraryAmender(appView).run(amendLibrary);
   }
 
-  private DesugaredLibraryAmender(
-      DexDefinitionSupplier definitions, Reporter reporter, ComputedApiLevel minAPILevel) {
-    this.definitions = definitions;
-    this.reporter = reporter;
-    this.minAPILevel = minAPILevel;
+  private DesugaredLibraryAmender(AppView<?> appView) {
+    this.appView = appView;
   }
 
   private void run(Map<DexMethod, MethodAccessFlags> amendLibrary) {
@@ -56,14 +40,17 @@
   }
 
   private void amendLibraryMethod(DexMethod method, MethodAccessFlags methodAccessFlags) {
-    DexClass dexClass = definitions.contextIndependentDefinitionFor(method.getHolderType());
+    DexClass dexClass = appView.contextIndependentDefinitionFor(method.getHolderType());
     if (dexClass == null || !dexClass.isLibraryClass()) {
       // Consider just throwing an error.
-      reporter.warning(
-          "Desugared library: Cannot amend library method "
-              + method
-              + " because the holder is not a library class"
-              + (dexClass == null ? "(null)." : "."));
+      appView
+          .options()
+          .reporter
+          .warning(
+              "Desugared library: Cannot amend library method "
+                  + method
+                  + " because the holder is not a library class"
+                  + (dexClass == null ? "(null)." : "."));
       return;
     }
     if (dexClass.lookupMethod(method) != null) {
@@ -74,7 +61,7 @@
             .setMethod(method)
             .setAccessFlags(methodAccessFlags)
             .setCode(null)
-            .setApiLevelForDefinition(minAPILevel)
+            .setApiLevelForDefinition(appView.computedMinApiLevel())
             .build();
     dexClass.getMethodCollection().addMethod(encodedMethod);
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibrarySpecification.java
index a76d426..e284e54 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibrarySpecification.java
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8.ir.desugar.desugaredlibrary;
 
+import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecification;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.legacyspecification.LegacyDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
@@ -23,6 +25,14 @@
     return false;
   }
 
+  default LegacyDesugaredLibrarySpecification asLegacyDesugaredLibrarySpecification() {
+    return null;
+  }
+
+  default HumanDesugaredLibrarySpecification asHumanDesugaredLibrarySpecification() {
+    return null;
+  }
+
   boolean isEmpty();
 
   boolean isLibraryCompilation();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecification.java
index f9aadb2..5f08201 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecification.java
@@ -3,6 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification;
 
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion.HumanToMachineSpecificationConverter;
@@ -13,6 +18,8 @@
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 public class HumanDesugaredLibrarySpecification implements DesugaredLibrarySpecification {
 
@@ -44,6 +51,11 @@
     return true;
   }
 
+  @Override
+  public HumanDesugaredLibrarySpecification asHumanDesugaredLibrarySpecification() {
+    return this;
+  }
+
   public boolean supportAllCallbacksFromLibrary() {
     return topLevelFlags.supportAllCallbacksFromLibrary();
   }
@@ -75,6 +87,61 @@
     return topLevelFlags.getIdentifier();
   }
 
+  public Map<String, String> getRewritePrefix() {
+    return rewritingFlags.getRewritePrefix();
+  }
+
+  public boolean hasEmulatedLibraryInterfaces() {
+    return !getEmulateLibraryInterface().isEmpty();
+  }
+
+  public Map<DexType, DexType> getEmulateLibraryInterface() {
+    return rewritingFlags.getEmulatedInterfaces();
+  }
+
+  // If the method is retargeted, answers the retargeted method, else null.
+  public DexMethod retargetMethod(DexEncodedMethod method, AppView<?> appView) {
+    Map<DexMethod, DexType> retargetCoreLibMember = rewritingFlags.getRetargetMethod();
+    DexType dexType = retargetCoreLibMember.get(method.getReference());
+    if (dexType != null) {
+      return appView
+          .dexItemFactory()
+          .createMethod(
+              dexType,
+              appView.dexItemFactory().prependHolderToProto(method.getReference()),
+              method.getName());
+    }
+    return null;
+  }
+
+  public DexMethod retargetMethod(DexClassAndMethod method, AppView<?> appView) {
+    return retargetMethod(method.getDefinition(), appView);
+  }
+
+  public Map<DexMethod, DexType> getRetargetCoreLibMember() {
+    return rewritingFlags.getRetargetMethod();
+  }
+
+  public Map<DexType, DexType> getBackportCoreLibraryMember() {
+    return rewritingFlags.getLegacyBackport();
+  }
+
+  public Map<DexType, DexType> getCustomConversions() {
+    return rewritingFlags.getCustomConversions();
+  }
+
+  public Set<DexType> getWrapperConversions() {
+    return rewritingFlags.getWrapperConversions();
+  }
+
+  public Set<DexMethod> getDontRewriteInvocation() {
+    return rewritingFlags.getDontRewriteInvocation();
+  }
+
+  public Set<DexType> getDontRetargetLibMember() {
+    return rewritingFlags.getDontRetarget();
+  }
+
   @Override
   public List<String> getExtraKeepRules() {
     return topLevelFlags.getExtraKeepRules();
@@ -92,7 +159,12 @@
   @Override
   public MachineDesugaredLibrarySpecification toMachineSpecification(
       InternalOptions options, AndroidApp app, Timing timing) throws IOException {
-    return new HumanToMachineSpecificationConverter(timing).convert(this, app, options);
+    return new HumanToMachineSpecificationConverter(timing)
+        .convert(
+            this,
+            isLibraryCompilation() ? app.getProgramResourceProviders() : null,
+            app.getLibraryResourceProviders(),
+            options);
   }
 
   @Override
@@ -100,6 +172,6 @@
       InternalOptions options, Path library, Path desugaredJDKLib, Timing timing)
       throws IOException {
     return new HumanToMachineSpecificationConverter(timing)
-        .convertForTesting(this, desugaredJDKLib, library, options);
+        .convert(this, isLibraryCompilation() ? desugaredJDKLib : null, library, options);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/legacyspecification/LegacyDesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/legacyspecification/LegacyDesugaredLibrarySpecification.java
index 6db6566..e48a6d0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/legacyspecification/LegacyDesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/legacyspecification/LegacyDesugaredLibrarySpecification.java
@@ -15,6 +15,7 @@
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Pair;
 import com.android.tools.r8.utils.Timing;
 import java.io.IOException;
 import java.nio.file.Path;
@@ -47,6 +48,11 @@
     return true;
   }
 
+  @Override
+  public LegacyDesugaredLibrarySpecification asLegacyDesugaredLibrarySpecification() {
+    return this;
+  }
+
   public LegacyTopLevelFlags getTopLevelFlags() {
     return topLevelFlags;
   }
@@ -78,6 +84,18 @@
     return topLevelFlags.getIdentifier();
   }
 
+  public Map<String, String> getRewritePrefix() {
+    return rewritingFlags.getRewritePrefix();
+  }
+
+  public boolean hasEmulatedLibraryInterfaces() {
+    return !getEmulateLibraryInterface().isEmpty();
+  }
+
+  public Map<DexType, DexType> getEmulateLibraryInterface() {
+    return rewritingFlags.getEmulateLibraryInterface();
+  }
+
   // If the method is retargeted, answers the retargeted method, else null.
   public DexMethod retargetMethod(DexEncodedMethod method, AppView<?> appView) {
     Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
@@ -98,6 +116,14 @@
     return retargetMethod(method.getDefinition(), appView);
   }
 
+  public Map<DexString, Map<DexType, DexType>> getRetargetCoreLibMember() {
+    return rewritingFlags.getRetargetCoreLibMember();
+  }
+
+  public Map<DexType, DexType> getBackportCoreLibraryMember() {
+    return rewritingFlags.getBackportCoreLibraryMember();
+  }
+
   public Map<DexType, DexType> getCustomConversions() {
     return rewritingFlags.getCustomConversions();
   }
@@ -106,6 +132,13 @@
     return rewritingFlags.getWrapperConversions();
   }
 
+  public List<Pair<DexType, DexString>> getDontRewriteInvocation() {
+    return rewritingFlags.getDontRewriteInvocation();
+  }
+
+  public Set<DexType> getDontRetargetLibMember() {
+    return rewritingFlags.getDontRetargetLibMember();
+  }
 
   @Override
   public List<String> getExtraKeepRules() {
@@ -121,7 +154,7 @@
   public MachineDesugaredLibrarySpecification toMachineSpecification(
       InternalOptions options, AndroidApp app, Timing timing) throws IOException {
     return new LegacyToHumanSpecificationConverter(timing)
-        .convert(this, app, options)
+        .convert(this, app.getLibraryResourceProviders(), options)
         .toMachineSpecification(options, app, timing);
   }
 
@@ -130,7 +163,7 @@
       InternalOptions options, Path library, Path desugaredJDKLib, Timing timing)
       throws IOException {
     return new LegacyToHumanSpecificationConverter(timing)
-        .convertForTesting(this, desugaredJDKLib, library, options)
+        .convert(this, library, options)
         .toMachineSpecification(options, library, desugaredJDKLib, timing);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/AppForSpecConversion.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/AppForSpecConversion.java
deleted file mode 100644
index 45f9dae..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/AppForSpecConversion.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2022, 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.ir.desugar.desugaredlibrary.specificationconversion;
-
-import com.android.tools.r8.ClassFileResourceProvider;
-import com.android.tools.r8.ProgramResourceProvider;
-import com.android.tools.r8.dex.ApplicationReader;
-import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.ThreadUtils;
-import com.android.tools.r8.utils.Timing;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.concurrent.ExecutorService;
-
-public class AppForSpecConversion {
-  static DexApplication readApp(
-      AndroidApp inputApp, InternalOptions options, boolean libraryCompilation, Timing timing)
-      throws IOException {
-    timing.begin("Read App");
-    AndroidApp.Builder builder = AndroidApp.builder();
-    for (ClassFileResourceProvider classFileResourceProvider :
-        inputApp.getLibraryResourceProviders()) {
-      builder.addLibraryResourceProvider(classFileResourceProvider);
-    }
-    if (libraryCompilation) {
-      for (ProgramResourceProvider programResourceProvider :
-          inputApp.getProgramResourceProviders()) {
-        builder.addProgramResourceProvider(programResourceProvider);
-      }
-    }
-    DexApplication app = internalReadApp(builder.build(), options, timing);
-    timing.end();
-    return app;
-  }
-
-  static DexApplication readAppForTesting(
-      Path desugaredJDKLib,
-      Path androidLib,
-      InternalOptions options,
-      boolean libraryCompilation,
-      Timing timing)
-      throws IOException {
-    timing.begin("Read App for testing");
-    assert !libraryCompilation || desugaredJDKLib != null;
-    AndroidApp.Builder builder = AndroidApp.builder();
-    if (libraryCompilation) {
-      builder.addProgramFile(desugaredJDKLib);
-    }
-    AndroidApp inputApp = builder.addLibraryFile(androidLib).build();
-    DexApplication app = internalReadApp(inputApp, options, timing);
-    timing.end();
-    return app;
-  }
-
-  private static DexApplication internalReadApp(
-      AndroidApp inputApp, InternalOptions options, Timing timing) throws IOException {
-    timing.begin("Internal Read App");
-    ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
-    ExecutorService executorService = ThreadUtils.getExecutorService(options);
-    assert !options.ignoreJavaLibraryOverride;
-    options.ignoreJavaLibraryOverride = true;
-    DexApplication app = applicationReader.read(executorService);
-    options.ignoreJavaLibraryOverride = false;
-    timing.end();
-    return app;
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
index 32c2400..f7189fb 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
@@ -4,9 +4,12 @@
 
 package com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion;
 
-import com.android.tools.r8.androidapi.ComputedApiLevel;
+import com.android.tools.r8.ClassFileResourceProvider;
+import com.android.tools.r8.ProgramResourceProvider;
+import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProto;
@@ -23,7 +26,7 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineTopLevelFlags;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.Reporter;
+import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.Sets;
 import java.io.IOException;
@@ -31,11 +34,11 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.ExecutorService;
 
 public class HumanToMachineSpecificationConverter {
 
-  private AppInfoWithClassHierarchy appInfo;
-  private Reporter reporter;
+  private AppView<?> appView;
   private final Set<DexType> missingCustomConversions = Sets.newIdentityHashSet();
   private final Timing timing;
 
@@ -44,30 +47,55 @@
   }
 
   public MachineDesugaredLibrarySpecification convert(
-      HumanDesugaredLibrarySpecification humanSpec, AndroidApp inputApp, InternalOptions options)
+      HumanDesugaredLibrarySpecification humanSpec,
+      List<ProgramResourceProvider> desugaredJDKLib,
+      List<ClassFileResourceProvider> library,
+      InternalOptions options)
       throws IOException {
-    DexApplication app =
-        AppForSpecConversion.readApp(inputApp, options, humanSpec.isLibraryCompilation(), timing);
-    return convert(humanSpec, app);
+    timing.begin("Human to machine convert");
+    assert !humanSpec.isLibraryCompilation() || desugaredJDKLib != null;
+    AndroidApp.Builder builder = AndroidApp.builder();
+    for (ClassFileResourceProvider classFileResourceProvider : library) {
+      builder.addLibraryResourceProvider(classFileResourceProvider);
+    }
+    if (humanSpec.isLibraryCompilation()) {
+      for (ProgramResourceProvider programResourceProvider : desugaredJDKLib) {
+        builder.addProgramResourceProvider(programResourceProvider);
+      }
+    }
+    MachineDesugaredLibrarySpecification machineSpec =
+        internalConvert(humanSpec, builder.build(), options);
+    timing.end();
+    return machineSpec;
   }
 
-  public MachineDesugaredLibrarySpecification convertForTesting(
+  public MachineDesugaredLibrarySpecification convert(
       HumanDesugaredLibrarySpecification humanSpec,
       Path desugaredJDKLib,
       Path androidLib,
       InternalOptions options)
       throws IOException {
-    DexApplication app =
-        AppForSpecConversion.readAppForTesting(
-            desugaredJDKLib, androidLib, options, humanSpec.isLibraryCompilation(), timing);
-    return convert(humanSpec, app);
+    timing.begin("Human to machine convert");
+    assert !humanSpec.isLibraryCompilation() || desugaredJDKLib != null;
+    AndroidApp.Builder builder = AndroidApp.builder();
+    if (humanSpec.isLibraryCompilation()) {
+      builder.addProgramFile(desugaredJDKLib);
+    }
+    AndroidApp inputApp = builder.addLibraryFile(androidLib).build();
+    MachineDesugaredLibrarySpecification machineSpec =
+        internalConvert(humanSpec, inputApp, options);
+    timing.end();
+    return machineSpec;
   }
 
-  private MachineDesugaredLibrarySpecification convert(
-      HumanDesugaredLibrarySpecification humanSpec, DexApplication app) {
-    timing.begin("Human to machine convert");
-    reporter = app.options.reporter;
-    appInfo = AppInfoWithClassHierarchy.createForDesugaring(AppInfo.createInitialAppInfo(app));
+  private MachineDesugaredLibrarySpecification internalConvert(
+      HumanDesugaredLibrarySpecification humanSpec, AndroidApp inputApp, InternalOptions options)
+      throws IOException {
+    timing.begin("internal convert");
+    DexApplication app = readApp(inputApp, options);
+    timing.begin("appView creation");
+    appView = AppView.createForD8(AppInfo.createInitialAppInfo(app));
+    timing.end();
     LibraryValidator.validate(
         app,
         humanSpec.isLibraryCompilation(),
@@ -94,9 +122,9 @@
   private MachineRewritingFlags convertRewritingFlags(
       String synthesizedPrefix, HumanRewritingFlags rewritingFlags) {
     timing.begin("convert rewriting flags");
+    AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
     MachineRewritingFlags.Builder builder = MachineRewritingFlags.builder();
-    DesugaredLibraryAmender.run(
-        appInfo, reporter, ComputedApiLevel.unknown(), rewritingFlags.getAmendLibraryMethod());
+    DesugaredLibraryAmender.run(appView, rewritingFlags.getAmendLibraryMethod());
     rewritingFlags.getAmendLibraryMethod().forEach(builder::amendLibraryMethod);
     new HumanToMachineRetargetConverter(appInfo)
         .convertRetargetFlags(rewritingFlags, builder, this::warnMissingReferences);
@@ -143,6 +171,18 @@
     builder.putCustomConversion(type, new CustomConversionDescriptor(toMethod, fromMethod));
   }
 
+  private DexApplication readApp(AndroidApp inputApp, InternalOptions options) throws IOException {
+    timing.begin("Read app");
+    ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
+    ExecutorService executorService = ThreadUtils.getExecutorService(options);
+    assert !options.ignoreJavaLibraryOverride;
+    options.ignoreJavaLibraryOverride = true;
+    DexApplication app = applicationReader.read(executorService);
+    options.ignoreJavaLibraryOverride = false;
+    timing.end();
+    return app;
+  }
+
   void warnMissingReferences(String message, Set<? extends DexReference> missingReferences) {
     List<DexReference> memberList = new ArrayList<>(missingReferences);
     memberList.sort(DexReference::compareTo);
@@ -159,6 +199,6 @@
     if (memberList.isEmpty()) {
       return;
     }
-    reporter.warning("Specification conversion: " + message + memberList);
+    appView.options().reporter.warning("Specification conversion: " + message + memberList);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java
index 47ef9e3..13306e4 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java
@@ -4,8 +4,10 @@
 
 package com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion;
 
+import com.android.tools.r8.ClassFileResourceProvider;
 import com.android.tools.r8.StringConsumer;
 import com.android.tools.r8.StringResource;
+import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexClass;
@@ -33,6 +35,7 @@
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Pair;
+import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -43,6 +46,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
 
 public class LegacyToHumanSpecificationConverter {
 
@@ -55,10 +59,7 @@
   }
 
   public void convertAllAPILevels(
-      StringResource inputSpecification,
-      Path desugaredJDKLib,
-      Path androidLib,
-      StringConsumer output)
+      StringResource inputSpecification, Path androidLib, StringConsumer output)
       throws IOException {
     InternalOptions options = new InternalOptions();
     MultiAPILevelLegacyDesugaredLibrarySpecification legacySpec =
@@ -66,21 +67,19 @@
                 options.dexItemFactory(), options.reporter)
             .parseMultiLevelConfiguration(inputSpecification);
     MultiAPILevelHumanDesugaredLibrarySpecification humanSpec =
-        convertAllAPILevels(legacySpec, desugaredJDKLib, androidLib, options);
+        convertAllAPILevels(legacySpec, androidLib, options);
     MultiAPILevelHumanDesugaredLibrarySpecificationJsonExporter.export(humanSpec, output);
   }
 
   public MultiAPILevelHumanDesugaredLibrarySpecification convertAllAPILevels(
       MultiAPILevelLegacyDesugaredLibrarySpecification legacySpec,
-      Path desugaredJDKLib,
       Path androidLib,
       InternalOptions options)
       throws IOException {
     timing.begin("Legacy to human all API convert");
     Origin origin = legacySpec.getOrigin();
-    DexApplication app =
-        AppForSpecConversion.readAppForTesting(desugaredJDKLib, androidLib, options, true, timing);
-
+    AndroidApp androidApp = AndroidApp.builder().addLibraryFile(androidLib).build();
+    DexApplication app = readApp(androidApp, options);
     HumanTopLevelFlags humanTopLevelFlags = convertTopLevelFlags(legacySpec.getTopLevelFlags());
     Int2ObjectArrayMap<HumanRewritingFlags> commonFlags =
         convertRewritingFlagMap(legacySpec.getCommonFlags(), app, origin);
@@ -101,29 +100,36 @@
   }
 
   public HumanDesugaredLibrarySpecification convert(
-      LegacyDesugaredLibrarySpecification legacySpec, AndroidApp inputApp, InternalOptions options)
-      throws IOException {
-    DexApplication app =
-        AppForSpecConversion.readApp(inputApp, options, legacySpec.isLegacy(), timing);
-    return convert(legacySpec, app, options);
-  }
-
-  public HumanDesugaredLibrarySpecification convertForTesting(
       LegacyDesugaredLibrarySpecification legacySpec,
-      Path desugaredJDKLib,
-      Path androidLib,
+      List<ClassFileResourceProvider> library,
       InternalOptions options)
       throws IOException {
-    DexApplication app =
-        AppForSpecConversion.readAppForTesting(
-            desugaredJDKLib, androidLib, options, legacySpec.isLibraryCompilation(), timing);
-    return convert(legacySpec, app, options);
+    timing.begin("Legacy to human convert");
+    AndroidApp.Builder builder = AndroidApp.builder();
+    for (ClassFileResourceProvider classFileResourceProvider : library) {
+      builder.addLibraryResourceProvider(classFileResourceProvider);
+    }
+    HumanDesugaredLibrarySpecification humanSpec =
+        internalConvert(legacySpec, builder.build(), options);
+    timing.end();
+    return humanSpec;
   }
 
   public HumanDesugaredLibrarySpecification convert(
-      LegacyDesugaredLibrarySpecification legacySpec, DexApplication app, InternalOptions options)
+      LegacyDesugaredLibrarySpecification legacySpec, Path androidLib, InternalOptions options)
       throws IOException {
-    timing.begin("Legacy to Human convert");
+    timing.begin("Legacy to human convert");
+    AndroidApp androidApp = AndroidApp.builder().addLibraryFile(androidLib).build();
+    HumanDesugaredLibrarySpecification humanSpec = internalConvert(legacySpec, androidApp, options);
+    timing.end();
+    return humanSpec;
+  }
+
+  public HumanDesugaredLibrarySpecification internalConvert(
+      LegacyDesugaredLibrarySpecification legacySpec, AndroidApp inputApp, InternalOptions options)
+      throws IOException {
+    timing.begin("internal convert");
+    DexApplication app = readApp(inputApp, options);
     LibraryValidator.validate(
         app,
         legacySpec.isLibraryCompilation(),
@@ -196,6 +202,15 @@
     builder.retargetMethod(source, target);
   }
 
+  private DexApplication readApp(AndroidApp inputApp, InternalOptions options) throws IOException {
+    timing.begin("Read app");
+    ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
+    ExecutorService executorService = ThreadUtils.getExecutorService(options);
+    DexApplication app = applicationReader.read(executorService);
+    timing.end();
+    return app;
+  }
+
   private Int2ObjectArrayMap<HumanRewritingFlags> convertRewritingFlagMap(
       Int2ObjectMap<LegacyRewritingFlags> libFlags, DexApplication app, Origin origin) {
     Int2ObjectArrayMap<HumanRewritingFlags> map = new Int2ObjectArrayMap<>();
@@ -207,6 +222,7 @@
       LegacyRewritingFlags flags, DexApplication app, Origin origin) {
     timing.begin("Convert rewriting flags");
     HumanRewritingFlags.Builder builder = HumanRewritingFlags.builder(app.options.reporter, origin);
+
     flags
         .getRewritePrefix()
         .forEach((prefix, rewritten) -> rewritePrefix(builder, prefix, rewritten));
@@ -215,9 +231,11 @@
     flags.getCustomConversions().forEach(builder::putCustomConversion);
     flags.getDontRetargetLibMember().forEach(builder::addDontRetargetLibMember);
     flags.getWrapperConversions().forEach(builder::addWrapperConversion);
+    timing.begin("Convert retarget");
     flags
         .getRetargetCoreLibMember()
         .forEach((name, typeMap) -> convertRetargetCoreLibMember(builder, app, name, typeMap));
+    timing.end();
     flags
         .getDontRewriteInvocation()
         .forEach(pair -> convertDontRewriteInvocation(builder, app, pair));
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
index f107b2a..df07564 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
@@ -59,11 +59,7 @@
                 StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
 
     MultiAPILevelHumanDesugaredLibrarySpecification humanSpec1 =
-        converter.convertAllAPILevels(
-            spec,
-            ToolHelper.getDesugarJDKLibs(),
-            ToolHelper.getAndroidJar(getRequiredCompilationAPILevel()),
-            options);
+        converter.convertAllAPILevels(spec, ToolHelper.getAndroidJar(31), options);
 
     Box<String> json = new Box<>();
     MultiAPILevelHumanDesugaredLibrarySpecificationJsonExporter.export(