Gradle依赖问题 - Apache Storm

时间:2015-07-27 00:28:16

标签: intellij-idea gradle apache-storm

我对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

2 个答案:

答案 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

类似的方法,但在不同的,我不得不承认,更优雅的方式。