With the update to Android Studio 3.1
our apps' builds started breaking randomly on all machines. On my machine the build breaks with a StackOverflowError
during the dexing process. When d8
and desugaring
are disabled in gradle.properties
the builds pass.
The problem seems to be related to the qoppapdf library that we used for several years in our prod app without problems. The problem is reproducible with a new Android project where the library jar is included in the libs
dir and multidex
is used in gradle. The StackOverflow error is as follows:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformClassesWithDexBuilderForDebug'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: com.android.build.api.transform.TransformException: com.android.builder.dexing.DexArchiveBuilderException: com. android.builder.dexing.DexArchiveBuilderException: Failed to process C:\Projects\MyApplication\app\libs\qoppapdf.jar
at com.android.builder.profile.Recorder$Block.handleException(Recorder.java:55)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:104)
at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:212)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:46)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
... 32 more
Caused by: com.android.build.api.transform.TransformException: com.android.builder.dexing.DexArchiveBuilderException: com.android.builder.dexing. DexArchiveBuilderException: Failed to process C:\Projects\MyApplication\app\libs\qoppapdf.jar
at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.transform(DexArchiveBuilderTransform.java:327)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:221)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:217)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102)
... 48 more
Caused by: com.android.builder.dexing.DexArchiveBuilderException: com.android.builder.dexing.DexArchiveBuilderException: Failed to process C:\Projects\MyApplication\app\libs\qoppapdf.jar
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:593)
at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:720)
at com.android.ide.common.internal.WaitableExecutor.waitForTasksWithQuickFail(WaitableExecutor.java:146)
at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.transform(DexArchiveBuilderTransform.java:306)
... 51 more
Caused by: com.android.builder.dexing.DexArchiveBuilderException: Failed to process C:\Projects\MyApplication\app\libs\qoppapdf.jar
at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.launchProcessing(DexArchiveBuilderTransform.java:803)
at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.lambda$convertToDexArchive$8(DexArchiveBuilderTransform.java:728)
at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1424)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: com.android.builder.dexing.DexArchiveBuilderException: Error while dexing.
at com.android.builder.dexing.D8DexArchiveBuilder.getExceptionToRethrow(D8DexArchiveBuilder.java:169)
at com.android.builder.dexing.D8DexArchiveBuilder.convert(D8DexArchiveBuilder.java:146)
at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.launchProcessing(DexArchiveBuilderTransform.java:798)
... 6 more
Caused by: java.lang.RuntimeException: java.lang.StackOverflowError
at com.android.tools.r8.R8.unwrapExecutionException(R8.java:501)
at com.android.tools.r8.D8.run(D8.java:170)
at com.android.tools.r8.D8.lambda$run$1(D8.java:91)
at com.android.tools.r8.utils.ExceptionUtils.withCompilationHandler(ExceptionUtils.java:58)
at com.android.tools.r8.utils.ExceptionUtils.withD8CompilationHandler(ExceptionUtils.java:45)
at com.android.tools.r8.D8.run(D8.java:88)
at com.android.builder.dexing.D8DexArchiveBuilder.convert(D8DexArchiveBuilder.java:144)
... 7 more
Caused by: java.lang.StackOverflowError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:598)
at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:1005)
at com.android.tools.r8.utils.ThreadUtils.awaitFutures(ThreadUtils.java:21)
at com.android.tools.r8.ir.conversion.IRConverter.convertClassesToDex(IRConverter.java:315)
at com.android.tools.r8.ir.conversion.IRConverter.convertToDex(IRConverter.java:225)
at com.android.tools.r8.D8.optimize(D8.java:187)
at com.android.tools.r8.D8.run(D8.java:158)
... 12 more
Caused by: java.lang.StackOverflowError
at java.util.HashMap.hash(HashMap.java:338)
at java.util.HashMap.containsKey(HashMap.java:595)
at java.util.HashSet.contains(HashSet.java:203)
at com.android.tools.r8.ir.code.IRCode.depthFirstSorting(IRCode.java:264)
at com.android.tools.r8.ir.code.IRCode.depthFirstSorting(IRCode.java:267)
at com.android.tools.r8.ir.code.IRCode.depthFirstSorting(IRCode.java:267)
The qoppapdf library can be downloaded from here https://www.qoppa.com/android/pdfsdk/evaluate/. Then the qoppapdf.jar
which is located in qpdftoolkit.zip
. qoppapdf.jar
is then added to the libs
directory of the project. This is the very basic build.gradle of the test app that I used to reproduce the build. The only difference with the default build.gradle is that multidex is enabled:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 27
defaultConfig {
applicationId "net.vectorworks.myapplication"
minSdkVersion 21
targetSdkVersion 27
multiDexEnabled true
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:27.1.0'
implementation 'com.android.support:multidex:1.0.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
Deleting the in-app and "global" .gradle
directories, build directories, invalidating Android Studio caches and rebuilding the app don't fix the problem. The only solution I found is disabling D8
altogether in gradle.properties
:
android.enableD8=false
This is resulting to a warning The option 'android.enableD8' is deprecated and should not be used anymore. Use 'android.enableD8=true' to remove this warning. It will be removed in AGP version 3.3.
So clearly not a long term solution. Any help will be appreciated!
The issue was resolved via the Google issue tracker issue 77307838 and issue 77626496. Googler [email protected]
writes:
I've reproduced this issue (with minimal java stack -Xss228k) and confirmed that is the same issue as b/77626496.
For very large graphs, the recursive register lookup and dominator tree construction may blow the stack.
Please use 1.2.9-dev to verify your build now works:
New version is 1.2.9 at hash f027c89aa49b92245662457f9e6096611f2dfbc0:
repositories { ... mavenCentral() maven { url "http://storage.googleapis.com/r8-releases/raw/master/f027c89aa49b92245662457f9e6096611f2dfbc0" } } dependencies { classpath 'com.android.tools:r8:1.2.9-dev' classpath '...gradle...' ... }
Note that the r8 classpath entry must be before the gradle one.
Alternatively you can get the d8 jar if you are using the compiler standalone:
http://storage.googleapis.com/r8-releases/raw/master/f027c89aa49b92245662457f9e6096611f2dfbc0/d8.jar