【问题标题】:Gradle dependency issues - Apache StormGradle 依赖问题 - Apache Storm
【发布时间】:2015-07-27 00:28:15
【问题描述】:

我在使用 Gradle 时遇到了一些依赖问题。依赖包是 apachestorm (org.apache.storm:storm-core:0.9.5),使用 Intellij。

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

【问题讨论】:

    标签: intellij-idea gradle apache-storm


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我是这样做的。首先是一堆名字繁琐的新配置:

      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 cleanstormJar' 构建一个 jar 时,它会排除与 Storm 本身相关的所有内容(以及它的依赖项),但会包含所有其他与其依赖项相关的内容 - 这可能很重要,因为有时我遇到了依赖项冲突.此外,由于编译配置从excludedFromStormJar 扩展而来,IntelliJ 的构建获得了 Storm 并且可以在 LocalCluster 的实例上运行。

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

      Making the Storm JARs compile-time only in a Gradle project

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-22
        • 1970-01-01
        • 1970-01-01
        • 2017-01-28
        • 1970-01-01
        • 1970-01-01
        • 2019-07-05
        • 1970-01-01
        相关资源
        最近更新 更多