DexByteCodeConverter { @VisibleForTesting synchronized boolean shouldDexInProcess( @NonNull DexOptions dexOptions, @NonNull Revision buildToolsVersion) { if (mIsDexInProcess != null) { return mIsDexInProcess; } if (!dexOptions.getDexInProcess()) { mIsDexInProcess = false; return false; } if (buildToolsVersion.compareTo(DexProcessBuilder.FIXED_DX_MERGER) < 0) { mLogger.warning("Running dex in-process requires build tools %1$s.\n" + "For faster builds update this project to use the latest build tools.", DexProcessBuilder.FIXED_DX_MERGER.toShortString()); mIsDexInProcess = false; return false; } long requestedHeapSize; if (dexOptions.getJavaMaxHeapSize() != null) { Optional<Long> heapSize = parseSizeToBytes(dexOptions.getJavaMaxHeapSize()); if (heapSize.isPresent()) { requestedHeapSize = heapSize.get(); } else { mLogger.warning( "Unable to parse dex options size parameter '%1$s', assuming %2$s bytes.", dexOptions.getJavaMaxHeapSize(), DEFAULT_DEX_HEAP_SIZE); requestedHeapSize = DEFAULT_DEX_HEAP_SIZE; } } else { requestedHeapSize = DEFAULT_DEX_HEAP_SIZE; } long requiredHeapSizeHeuristic = requestedHeapSize + NON_DEX_HEAP_SIZE; long maxMemory = getUserDefinedHeapSize(); if (requiredHeapSizeHeuristic > maxMemory) { String dexOptionsComment = ""; if (dexOptions.getJavaMaxHeapSize() != null) { dexOptionsComment = String.format( " (based on the dexOptions.javaMaxHeapSize = %s)", dexOptions.getJavaMaxHeapSize()); } mLogger.warning("\nRunning dex as a separate process.\n\n" + "To run dex in process, the Gradle daemon needs a larger heap.\n" + "It currently has %1$d MB.\n" + "For faster builds, increase the maximum heap size for the " + "Gradle daemon to at least %2$s MB%3$s.\n" + "To do this set org.gradle.jvmargs=-Xmx%2$sM in the " + "project gradle.properties.\n" + "For more information see " + "https: maxMemory / (1024 * 1024), ((requiredHeapSizeHeuristic - 1) / (1024 * 1024)) + 1, dexOptionsComment); mIsDexInProcess = false; return false; } mIsDexInProcess = true; return true; } DexByteCodeConverter(ILogger logger, TargetInfo targetInfo,
            JavaProcessExecutor javaProcessExecutor,
            boolean verboseExec); void convertByteCode(
            @NonNull Collection<File> inputs,
            @NonNull File outDexFolder,
            boolean multidex,
            @Nullable File mainDexList,
            @NonNull DexOptions dexOptions,
            boolean optimize,
            @NonNull ProcessOutputHandler processOutputHandler); void runDexer(
            @NonNull final DexProcessBuilder builder,
            @NonNull final DexOptions dexOptions,
            @NonNull final ProcessOutputHandler processOutputHandler);  }
@Test public void checkDexInProcessIsDefaultEnabled() { when(dexOptions.getDexInProcess()).thenReturn(true); when(dexOptions.getJavaMaxHeapSize()).thenReturn("1024"); assertTrue(dexByteCodeConverter.shouldDexInProcess(dexOptions, new Revision(23, 0, 2))); }
@Test public void checkDisabledDexInProcessIsDisabled() { when(dexOptions.getDexInProcess()).thenReturn(false); assertFalse(dexByteCodeConverter.shouldDexInProcess(dexOptions, new Revision(23, 0, 2))); }
@Test public void checkDexInProcessWithOldBuildToolsIsDisabled() { when(dexOptions.getDexInProcess()).thenReturn(true); assertFalse(dexByteCodeConverter.shouldDexInProcess(dexOptions, new Revision(23, 0, 1))); }
@Test public void checkDexInProcessWithNotEnoughMemoryIsDisabled() { when(dexOptions.getDexInProcess()).thenReturn(true); String heapSizeSetting = "10000G"; when(dexOptions.getJavaMaxHeapSize()).thenReturn(heapSizeSetting); assertFalse(dexByteCodeConverter.shouldDexInProcess(dexOptions, new Revision(23, 0, 2))); verify(logger).warning( contains("org.gradle.jvmargs=-Xmx"), any(), eq(10000 * 1024 + DexByteCodeConverter.NON_DEX_HEAP_SIZE / 1024 / 1024), contains(heapSizeSetting)); verifyNoMoreInteractions(logger); }