question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can't count methods in AAR (Java 8)

See original GitHub issue

Build process was changed from gradle android plugin 2.4.0. If you use some features from Java 8 and minSdk < 26, then it run “desugar” before transforming classes to dex (https://developer.android.com/studio/write/java8-support.html).

Gradle: 4.1 Gradle Android plugin: 3.0.0-beta7

library build.gradle:

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 26
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

Stacktrace:

Dexcount name:    dexcount-gradle-plugin
Dexcount version: 0.8.1
Dexcount input:   /home/dmitry/IdeaProjects/TestLibrary/library/build/outputs/aar/library-release.aar
Error counting dex methods. Please contact the developer at https://github.com/KeepSafe/dexcount-gradle-plugin/issues
com.getkeepsafe.dexcount.DexCountException: dx exited with exit code 1
stderr=Uncaught translation error: com.android.dx.cf.code.SimException: invalid opcode ba (invokedynamic requires --min-sdk-version >= 26)
1 error; aborting

        at com.getkeepsafe.dexcount.DexFile$Companion.extractDexFromAar(DexFile.kt:167)
        at com.getkeepsafe.dexcount.DexFile$Companion.extractDexData(DexFile.kt:101)
        at com.getkeepsafe.dexcount.DexMethodCountTaskBase.generatePackageTree(Tasks.kt:165)
        at com.getkeepsafe.dexcount.DexMethodCountTaskBase.countMethods(Tasks.kt:127)
        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:498)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.doExecute(DefaultTaskClassInfoStore.java:141)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:134)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:121)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:731)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:705)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:122)
        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:197)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:111)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:63)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)
        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:197)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
        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:124)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:80)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:105)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:99)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:625)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:580)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:99)
        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)

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:19

github_iconTop GitHub Comments

2reactions
benjamin-badercommented, Mar 28, 2018

Not really; it’s more that dx doesn’t understand some Java 8 bytecodes, and Desugar is needed to translate such classes into a Java 6-compatible form. The issue you refer to is different in that dexcount-gradle-plugin just doesn’t count jars at all, as we haven’t implemented it. There’s some similarity though - any jar using Java 8 would probably hit this problem, too.

This issue is still open because Android Build Tools have become incredibly complex since the 3.0 release, and I haven’t had the time or inclination to untangle exactly how to incorporate desugar. I’d still be happy to take a PR here 👼

Also, build-tools 3.1 just dropped, and d8 is now the default .class->.dex compiler. In 3.2, d8 does desugaring, too. At this rate, it’s entirely likely that we’ll just wait for 3.2 to release (6 months, maybe?), and just deprecate dx support entirely.

1reaction
benjamin-badercommented, Dec 22, 2017

Thanks, folks, for the info! You’re correct, we could use desugar_deploy.jar. I didn’t consider doing so for a few reasons:

  • not everybody will be using Android Studio, so we can’t rely on the jar being present; we’d have to bundle it ourselves.
  • desugar changes with minor Android Studio releases, so we’d layer on yet another moving target for compatibility, which I’d prefer to avoid.
  • It’s not guaranteed that our inputs to desugar_deploy.jar would match up with those used by the Android Gradle Plugin, so it would be difficult to trust the resulting method counts.

I’d accept a PR using desugar_deploy.jar as an interim solution, but I believe it will be better for us to find a way to use Android Gradle Plugin here.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is there a way to get count of number methods used in a jar file
I have used decompilers like dex2jar JAD and others to name a few ,but they all seem to show methods only in particular...
Read more >
d8 - Android Developers
d8 is a command-line tool that Android Studio and the Android Gradle plugin use to compile your project's Java bytecode into DEX bytecode ......
Read more >
Spring Data JPA - Reference Documentation
In addition to query methods, query derivation for both count and delete queries is available. The following list shows the interface ...
Read more >
How to Find Array Length in Java - Javatpoint
There is no predefined method to obtain the length of an array. We can find the array ... It does not count the...
Read more >
Can't get broadcasts working with a native android module ...
I created a native module in Android studio and placed the AAR file ... On the Unity side of things i made a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found