Using ClassGraph in Android Study 3.2.1

18 views
Skip to first unread message

Craig Neuwirt

unread,
Oct 21, 2018, 10:48:17 PM10/21/18
to ClassGraph-Users
I am trying to pull in a dependency that uses ClassGraph 4.4.1 into and android application, but am getting a build failure.  The only reference I found when I googling is possibly something to do with SDK version 26 or 27.  Does anyone know how to resolve this?

thanks,
  Craig

error processing /Users/cneuwirt/.gradle/caches/modules-2/files-2.1/io.github.classgraph/classgraph/4.4.1/8df6dbed6ad699742e864a15eaba2cfdf853c950/classgraph-4.4.1.jar
java.lang.RuntimeException
at org.objectweb.asm.ClassVisitor.visitModule(ClassVisitor.java:148)
at org.objectweb.asm.ClassReader.readModule(ClassReader.java:731)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:632)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
at com.android.builder.desugaring.DesugaringClassAnalyzer.analyze(DesugaringClassAnalyzer.java:144)
at com.android.builder.desugaring.DesugaringClassAnalyzer.analyzeJar(DesugaringClassAnalyzer.java:92)
at com.android.builder.desugaring.DesugaringClassAnalyzer.analyze(DesugaringClassAnalyzer.java:63)
at com.android.build.gradle.internal.transforms.DesugarIncrementalTransformHelper.lambda$getInitalGraphData$4(DesugarIncrementalTransformHelper.java:150)
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)
java.lang.RuntimeException: java.lang.RuntimeException
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:423)
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.DesugarIncrementalTransformHelper.getInitalGraphData(DesugarIncrementalTransformHelper.java:162)
at com.android.build.gradle.internal.transforms.DesugarIncrementalTransformHelper.makeDesugaringGraph(DesugarIncrementalTransformHelper.java:130)
at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers.java:160)
at com.android.build.gradle.internal.transforms.DesugarIncrementalTransformHelper.getDependenciesPaths(DesugarIncrementalTransformHelper.java:231)
at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.getD8DesugaringCacheInfo(DexArchiveBuilderTransform.java:461)
at com.android.build.gradle.internal.transforms.DexArchiveBuilderTransform.transform(DexArchiveBuilderTransform.java:375)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:239)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:235)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102)
at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:230)
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.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:50)
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:124)
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:113)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:95)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:73)
at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59)
at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101)
at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91)
at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59)
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:256)
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:249)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:238)
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:663)
at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:597)
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:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException
at org.objectweb.asm.ClassVisitor.visitModule(ClassVisitor.java:148)
at org.objectweb.asm.ClassReader.readModule(ClassReader.java:731)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:632)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
at com.android.builder.desugaring.DesugaringClassAnalyzer.analyze(DesugaringClassAnalyzer.java:144)
at com.android.builder.desugaring.DesugaringClassAnalyzer.analyzeJar(DesugaringClassAnalyzer.java:92)
at com.android.builder.desugaring.DesugaringClassAnalyzer.analyze(DesugaringClassAnalyzer.java:63)
at com.android.build.gradle.internal.transforms.DesugarIncrementalTransformHelper.lambda$getInitalGraphData$4(DesugarIncrementalTransformHelper.java:150)
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)

Luke Hutchison

unread,
Oct 21, 2018, 11:02:01 PM10/21/18
to cneu...@gmail.com, classgra...@googlegroups.com
Are you using the latest ObjectWeb ASM? That is what is throwing the exception. Old versions have been known to throw exceptions when they hit module-info.class. (Although in this case, based on the method "visitModule", your version is at least aware of modules.)

If ObjectWeb ASM is being pulled in by a dependency (ClassGraph itself doesn't pull it in), you can override the version of ObjectWeb ASM that the thing that depends on it uses, by specifying a dependency override for one of your own dependencies in your Gradle or Maven file. See https://stackoverflow.com/questions/49398894/unable-to-compile-simple-java-10-project-with-maven/49398936#49398936

Note that ClassGraph works only at build-time in Android, it will fail at runtime because it expects the classfile format, not the Dalvik apk format.

Also, you are one of the first people to use ClassGraph in Android, although it has been a goal to enable this for a long time. I put up these instructions recently: https://github.com/classgraph/classgraph/wiki/Build-Time-Scanning#build-time-scanning-in-gradle-for-android -- are those the instructions you are following? If so, I would appreciate feedback and/or help in improving the code or the instructions. Thanks.




--
You received this message because you are subscribed to the Google Groups "ClassGraph-Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to classgraph-use...@googlegroups.com.
To post to this group, send email to classgra...@googlegroups.com.
Visit this group at https://groups.google.com/group/classgraph-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/classgraph-users/40d03ed3-49bd-401f-9c7f-d1094e7ca223%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Luke Hutchison

unread,
Oct 22, 2018, 3:05:50 AM10/22/18
to cneu...@gmail.com, classgra...@googlegroups.com
I just thought of another possibility. Android's own build tools, up until recently, would choke on jarfiles that include a module-info.class file. The Android build tools have been fixed to blacklist META-INF when scanning for classfiles, so that module-info.class can be put into META-INF/versions/9: https://issuetracker.google.com/u/0/issues/77587908

This is also being changed to be the default for Moditect, which ClassGraph uses to build its module-info.class file: https://github.com/moditect/moditect/issues/67

However, I have been waiting for Moditect to push out a new release for quite a while to fix this. I just pinged the author of Moditect about this again. When that release happens, I'll push out a new release of ClassGraph.

The Android build tools will still need to be fixed though to handle this problem. I just added a comment to the first thread linked above in this message, explaining how the current fixes are probably insufficient.

What I recommend you do for now is download the latest version of ClassGraph (4.4.7), then manually remove the module-info.class file from the jarfile, then manually include this patched jarfile in your project. Unfortunately until Android fixes their tools, this may be the only reasonable option, short of ClassGraph dropping JPMS support altogether (which is not a great idea, since some users already depend upon using ClassGraph as a module).


Craig Neuwirt

unread,
Oct 22, 2018, 9:35:59 AM10/22/18
to ClassGraph-Users
Hey Luke,

   Can you tell me a little more about the build time usage of ClassGraph.  Would the the expected usage be to scan all dependencies at build time and generate some code that would be equivalent the runtime usage?  If that's the case, perhaps I can readjust my approach to try that and help validate ClassGraph on Android.

Luke Hutchison

unread,
Oct 22, 2018, 10:44:58 AM10/22/18
to Craig Neuwirt, classgra...@googlegroups.com
(forgot to CC list) 


On Mon, Oct 22, 2018, 8:37 AM Luke Hutchison <luke....@gmail.com> wrote:
Almost, minus the need for code generation. The idea is to run the scan you need after the code is compiled into classfiles and before the classfiles are converted into Dalvik byte code. Then you write out the results of the scan to a resource file in some format (eg. write out the names of classes that have some annotation you're interested in). The file is then converted into a .flat file so that it can be incorporated into the .apk, and it is put with the other .flat files that have already been converted by the AAPT2 tool during earlier stages of the build process. This then gets picked up as part of the apk file by the final build stages. Take a look at the code examples on that page I linked.



Reply all
Reply to author
Forward
0 new messages