Android多模块项目失败,出现TypeNotPresentException

时间:2018-03-20 14:10:05

标签: java android gradle gradle-plugin multi-module

我有一个包含16个模块的android项目。其中许多是java模块,有些包括注释处理。我也针对Java 1.8,包括对lambdas和其他Java 8功能的支持。

我的大多数依赖项都是在我的依赖项闭包中声明的,但是我使用自定义插件添加了一些依赖项。这会在构建过程中添加runtimeOnly和实现依赖项:

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

除了 app 之外的每个模块都可以独立构建,但是当我运行

gradlew clean :app:assemble

我得到以下异常:

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

我没有使用上面提到的库,但我的理解是这些可能是注释处理器(例如我正在使用的Dagger)或Mockito的传递依赖。

我可以采取哪些步骤来解决此问题?有没有其他人有这个问题,能够解决?由于这个项目的性质,我不能发布许多其他细节,但我正在使用:

  • Gradle 4.1 with
  • Android Gradle插件3.0.1。
  • Min sdk 22
  • 目标sdk 22
  • 编译sdk 26
  • 构建工具26.0.2

1 个答案:

答案 0 :(得分:0)

我能够通过两项更改解决这个问题:

  1. 如所怀疑的,这是传递依赖的问题。动态添加的依赖项添加方法可以接受第三个参数来配置其设置。使用它来强制非传递依赖是解决方案:

    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
    
  2. 我还使用Retrolambda将我的Java 8模块中的字节码转换为Java 7,以支持与Android的更好兼容性。我不确定是否需要这一步,但它是解决方案的一部分对我有用。