这是关于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而不是代理,但我是Gradle的新手,更不用说Ant了,我无法找到/想出一个例子。
最后,我还尝试按照corda docs的建议将ext.corda_gradle_plugins_version = '1.0.0'
升级为2.0.9
,但gradle在升级后无法调用cordaCompile
,而我还没有能够在插件上找到任何文档。
编辑:我注意到从2.1.0
升级到2.4.0
的artemis-core-client会解决corda-node-api的内部冲突as you can see here。至于commons-io,遗憾的是commons-fileupload是最新版本1.3.3
,自17年7月以来一直没有更新
答案 0 :(得分:0)
您需要设置依赖关系,如下所述:How can CorDapps deal with transitive dependencies。
背景:什么是阴影?
说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的构建的最后一个阶段。