首页 文章

Corda Dependency Conflicts在使用类星体代理时阻止调用Classloader

提问于
浏览
0

这是关于corda的github问题的my post的副本 .

我正在尝试将一个外部依赖包含在sample projects中 .

此依赖关系调用 ClassLoader.defineClass ,它以 java.lang.ClassFormatError: Illegal UTF8 string in constant pool in class file org/apache/xerces/impl/xpath/regex/ParserForXMLSchema 退出 . 该异常与this quasar issue提到的异常相同,这表明它是由冲突的依赖关系和使用类星体代理引起的 .

在对项目运行依赖关系报告之后,我不仅可以看到外部库和Corda之间的一些冲突,还可以看到Corda本身之间的冲突 . 到目前为止,Gradle一直通过其瞬态依赖管理来处理它们 . 以下是该报告的摘录:

+--- org.apache.jena:jena-core:3.6.0                            <-external library
     ...
|    \--- org.apache.jena:jena-base:3.6.0
       ...
|         +--- commons-io:commons-io:2.6      <- external lib dependency
\--- net.corda:corda-node-api:2.0.0
     ...
     +--- commons-beanutils:commons-beanutils:1.9.3       <- corda dependency
     |    +--- commons-logging:commons-logging:1.2
     |    \--- commons-collections:commons-collections:3.2.2
     +--- org.apache.activemq:artemis-core-client:2.1.0
     |    +--- org.jgroups:jgroups:3.6.13.Final
     |    +--- org.apache.activemq:artemis-commons:2.1.0
           ...
     |    |    +--- commons-beanutils:commons-beanutils:1.9.2 -> 1.9.3 (*) <- corda conflict
     ...
     +--- commons-fileupload:commons-fileupload:1.3.3
     |    \--- commons-io:commons-io:2.2 -> 2.6     <-    external lib conflict
    ...

这是我的root build.gradle:

buildscript {
    ext.corda_release_version = '2.0.0'
    ext.corda_gradle_plugins_version = '1.0.0'
    ext.kotlin_version = '1.1.4'
    ext.junit_version = '4.12'
    ext.quasar_version = '0.7.9'

    repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "net.corda.plugins:cordformation:$corda_gradle_plugins_version"
        classpath "net.corda.plugins:quasar-utils:$corda_gradle_plugins_version"
        classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
    }
}

repositories {
    mavenLocal()
    jcenter()
    mavenCentral()
    maven { url 'https://jitpack.io' }
    maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases' }
}

apply plugin: 'kotlin'
apply plugin: 'net.corda.plugins.cordformation'
apply plugin: 'net.corda.plugins.quasar-utils'

sourceSets {
    main {
        resources {
            srcDir "config/dev"
        }
    }
    test {
        resources {
            srcDir "config/test"
        }
    }
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
    testCompile "junit:junit:$junit_version"

    cordaCompile "net.corda:corda-core:$corda_release_version"
    cordaCompile "net.corda:corda-node-api:$corda_release_version"
    cordaRuntime "net.corda:corda:$corda_release_version"
    testCompile "net.corda:corda-node-driver:$corda_release_version"

    compile "org.apache.jena:jena-core:3.6.0"
}

作为参考,来自 jena-core 的函数调用是JUnit测试中的单行 ModelFactory.createDefaultModel() . 此时,我正在使用最少的Corda库来运行其他测试,因为在编译未使用的库时会出现更多冲突 .

另一种方法是使用quasar aot而不是代理,但我能够找到/提出一个例子 .

最后,我还尝试按照corda docs的建议将 ext.corda_gradle_plugins_version = '1.0.0' 升级到 2.0.9 ,但gradle在升级后无法调用 cordaCompile ,而且我无法在插件上找到任何文档 .

编辑:我注意到将artemis-core-client从 2.1.0 升级到 2.4.0 将解决corda-node-api的内部冲突as you can see here . 至于commons-io,遗憾的是commons-fileupload是最新版本 1.3.3 ,其中没有't been updated since July ' 17

1 回答

  • 0

    您需要设置依赖关系,如下所述:How can CorDapps deal with transitive dependencies .

    Background: 什么是阴影?

    说corda依赖于Guava版本1.它将使用 import com.google.guava.SpecialList 类型的import语句,这意味着当运行Corda时,类 com.google.guava.SpecialList 必须存在于类加载器中 .

    现在,假设开发人员正在编写使用Guava版本2的CorDapp . 运行CorDapp时,Guava版本1和Guava版本2 JAR都将在类路径上 .

    在运行时,Java将在其类路径上加载所有JAR . 这意味着它未定义将加载 com.google.guava.SpecialList 的哪个副本 . 它取决于订单,环境,Java版本等 . 并且可能会加载40%的版本1,而版本2的60%将被加载 .

    如果版本1和版本2兼容,则这不是问题 . CorDapp将使用版本1,或者Corda运行时将使用版本2.真正的乐趣在两个版本不兼容时开始,因为现在应用程序可能在某些情况下工作,而在其他情况下失败 - 这是一场噩梦 .

    着色为我们解决了这个问题 . 它允许我们重新打包依赖项,以便它们的包定义不再发生冲突 .

    作为构建过程的一部分,执行 shade 插件,它将 corda.dep 附加到Corda引用的所有类,并重写导入类的字节码,以便它们引用修改后的包 import corda.dep.com.google.guava.SpecialList .

    这导致Guava的第1版与其自己的命名空间( corda.dep )中的Corda JAR捆绑在一起 . 任何依赖于Guava的CorDapp现在都可以安全地导入这个库,并将其包含在类路径中,而不会与Corda使用的版本冲突 .

    有一个名为 shadow 的着色Gradle插件 . 我们将调用此插件作为生成Corda运行时jar的构建的最后一个阶段 .

相关问题