I have an android project with 16 modules. Many of these are java modules, and some include annotation processing. I have targeted Java 1.8 as well, to include support for lambdas and other Java 8 features.
Most of my dependencies are declared in my dependencies closure, however I am adding some dependencies using a custom plugin. This adds runtimeOnly and implementation dependencies during the build:
class DynamicDeps implements Plugin<Project> {
@Override
void apply(Project target) {
target.dependencies.add("implementation", target.rootProject.project("myUiModule"))
target.dependencies.add("runtimeOnly", target.rootProject.project("myBusinessLogicModule"))
}
}
apply plugin: DynamicDeps
Every module except app builds fine independently, however when I run
gradlew clean :app:assemble
I get the following exception:
Exception in thread "main" java.lang.TypeNotPresentException: Type org.jdom.Element not present
at sun.invoke.util.BytecodeDescriptor.parseSig(BytecodeDescriptor.java:85)
at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:54)
at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:41)
at java.lang.invoke.MethodType.fromMethodDescriptorString(MethodType.java:1067)
at com.google.devtools.build.android.desugar.LambdaDesugaring$InvokedynamicRewriter.toMethodHandle(LambdaDesugaring.java:599)
at com.google.devtools.build.android.desugar.LambdaDesugaring$InvokedynamicRewriter.toJvmMetatype(LambdaDesugaring.java:586)
at com.google.devtools.build.android.desugar.LambdaDesugaring$InvokedynamicRewriter.visitInvokeDynamicInsn(LambdaDesugaring.java:401)
at org.objectweb.asm.ClassReader.a(Unknown Source)
at org.objectweb.asm.ClassReader.b(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at org.objectweb.asm.ClassReader.accept(Unknown Source)
at com.google.devtools.build.android.desugar.Desugar.desugarClassesInInput(Desugar.java:401)
at com.google.devtools.build.android.desugar.Desugar.desugarOneInput(Desugar.java:326)
at com.google.devtools.build.android.desugar.Desugar.desugar(Desugar.java:280)
at com.google.devtools.build.android.desugar.Desugar.main(Desugar.java:584)
Caused by: java.lang.ClassNotFoundException: Class org.jdom.Element not found
at com.google.devtools.build.android.desugar.HeaderClassLoader.findClass(HeaderClassLoader.java:53)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at sun.invoke.util.BytecodeDescriptor.parseSig(BytecodeDescriptor.java:83)
... 14 more
I am not using the libraries mentioned, but my understanding is that these could be transitive dependencies of annotation processors (such as Dagger, which I am using) or Mockito.
What steps can I take to resolve this issue? Has anyone else had this problem and was able to resolve? Due to the nature of this project, I cannot post many additional details, however I am using:
I was able to fix this with two changes:
As suspected, this was a problem with transitive dependencies. The dynamically-added dependency add method can accept a third parameter to configure its settings. Using this to force non-transitive dependencies was the solution:
class DynamicDeps implements Plugin<Project> {
@Override
void apply(Project target) {
target.dependencies.add("implementation", target.rootProject.project("myUiModule"), { dep ->
dep.transitive = false
})
target.dependencies.add("runtimeOnly", target.rootProject.project("myBusinessLogicModule"), { dep ->
dep.transitive = false
})
}
}
apply plugin: DynamicDeps
I also used Retrolambda to convert the bytecode from my Java 8 modules into Java 7 to support better compatibility with Android. I am not sure if this step was needed, but it was part of the solution that worked for me.