Gradle依赖问题- Apache Storm



我对Gradle有一些依赖问题。依赖包是apache storm (org.apache.storm:storm-core:0.9.5)和使用Intellij.

我需要storm包编译,但不是在运行时,所以我有我的构建。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

我找到了一种方法来做到这一点,通过配置运行/调试配置显式地包括我的应用程序的jar和apache-storm的jar的类路径。

如果有更好的方法,我很乐意听听。

我这样做。首先,有一堆新配置,它们的名字很麻烦:

configurations {
    includedInStormJar
    excludedFromStormJar.extendsFrom includedInStormJar
    compile.extendsFrom excludedFromStormJar
}

然后,在我的dependencies部分:

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实例上运行。

你可能还想检查这个问题:

让Storm jar只在Gradle项目中编译

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

最新更新