我对Gradle有一些依赖性问题。依赖包是apache storm(org.apache.storm:storm-core:0.9.5)并使用Intellij。
我需要使用风暴包进行编译,但不需要在运行时,因此我的build.gradle配置如下。
apply plugin: 'application'
apply plugin: 'idea'
apply plugin: 'eclipse'
...
configurations {
provided
}
idea {
module{
scopes.PROVIDED.plus += [configurations.provided]
}
}
eclipse {
classpath {
plusConfigurations += [configurations.provided]
}
}
sourceSets {
main {
compileClasspath += configurations.provided
runtimeClasspath += configurations.provided
}
test {
compileClasspath += configurations.provided
runtimeClasspath += configurations.provided
}
}
dependencies {
...
provided 'org.apache.storm:storm-core:0.9.5'
...
}
类似地,配置允许Intellij知道链接到引用和构建的依赖性。我的问题是我想在LocalMode中运行Storm拓扑但是当我这样做时,依赖性似乎没有在运行时拉入,我得到下面的错误。如何在创建jar时保留包,但在通过Intellij或Eclipse运行时包括?
Connected to the target VM, address: '127.0.0.1:56593', transport: 'socket'
Exception in thread "main" java.lang.NoClassDefFoundError: backtype/storm/topology/IRichSpout
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2693)
at java.lang.Class.privateGetMethodRecursive(Class.java:3040)
at java.lang.Class.getMethod0(Class.java:3010)
at java.lang.Class.getMethod(Class.java:1776)
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
Disconnected from the target VM, address: '127.0.0.1:56593', transport: 'socket'
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: backtype.storm.topology.IRichSpout
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more
答案 0 :(得分:0)
通过配置运行/调试配置以明确包含应用程序jar和apache-storm jar的类路径,我找到了一种方法。
如果有更好的方法,我会很高兴听到它。
答案 1 :(得分:0)
configurations {
includedInStormJar
excludedFromStormJar.extendsFrom includedInStormJar
compile.extendsFrom excludedFromStormJar
}
然后,在我的依赖项部分中:
excludedFromStormJar "org.apache.storm:storm-core:$stormVersion"
includedInStormJar "org.yaml:snakeyaml:1.15"
// any other cool stuff here
最后一项看起来与广为人知的'fatJar'相似的任务:
task stormJar(type: Jar) {
dependsOn configurations.runtime
from {
(configurations.runtime - configurations.excludedFromStormJar + configurations.includedInStormJar).collect {
it.isDirectory() ? it : zipTree(it)
}
}
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
with jar
}
因此,当使用'gradle clean stormJar'构建jar时,它会排除与Storm本身相关的所有内容(以及它的依赖项),但包含所有其他与它依赖的东西 - 它可能很重要,因为有时候我有依赖冲突。此外,由于编译配置从excludedFromStormJar扩展,IntelliJ的构建获得Storm并且可以在LocalCluster的实例上运行。
您也可以查看以下问题:
Making the Storm JARs compile-time only in a Gradle project
类似的方法,但在不同的,我不得不承认,更优雅的方式。