【问题标题】:Gradle idea plugin excluded transitive dependency from other sub-project not excludedGradle idea 插件排除了其他子项目的传递依赖,没有排除
【发布时间】:2014-03-08 08:23:21
【问题描述】:

我有一个具有以下依赖结构的 gradle 项目:

root
+--- module1
|    \--- 'some:dependency:1.0' (Maven dependency)
|         \--- 'some:transitive:2.1' (transitive dep)
\--- module2
     +--- module1
     +--- exclude 'some:transitive:2.1'
     \--- 'some:other:1.0'
          \--- 'other:transitive:1.1'

基本上module2 排除了依赖some:transitive:2.1(对于module1 是可传递的)。这是因为它在运行时与 other:transitive:1.1 冲突(我可以提供我正在谈论的确切库,但这与我的问题无关)并且组 ID 和工件 ID 不同,因此必须手动排除:

configurations.all {
  exclude group: 'some', module: 'transitive', version: '2.1'
}

正确排除了依赖项(我可以通过执行dependencyInsight 任务来判断)。如果我在module2 中创建一个测试,使用来自some:other:1.0 的代码将触发运行时冲突,它会使用Gradle 成功运行,因为该jar 被排除在外:

gradle :module2:test -Dtest.single=SomeTest

现在我正在使用 IntelliJ 12(Gradle 集成太差),我使用 Gradle idea 插件生成 .ipr 和 .iml 文件。一切都很好。

但是,如果我从 IDE 运行 SomeTest,我会得到由上述冲突触发的运行时冲突。查看 IDE 测试类路径,我发现它实际上包含(除其他外)排除的 jar:

-classpath ...:/path/to/jar/some/transitive/2.1/some-transitive-2.1.jar:...

所以我的问题是:如何防止 IntelliJ 在不应该添加这种传递依赖时添加它?

为了完整起见,这里是我正在谈论的冲突(尽管它与本次讨论无关):

java.lang.IncompatibleClassChangeError: Implementing class
  at java.lang.ClassLoader.defineClass1(Native Method)
  at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
  at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
  at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
  at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
  at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
  at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
  at org.glassfish.jersey.server.ResourceConfig.scanClasses(ResourceConfig.java:875)
  at org.glassfish.jersey.server.ResourceConfig._getClasses(ResourceConfig.java:840)
  at org.glassfish.jersey.server.ResourceConfig.getClasses(ResourceConfig.java:755)
  at org.glassfish.jersey.server.ResourceConfig$RuntimeConfig.<init>(ResourceConfig.java:1171)
  at org.glassfish.jersey.server.ResourceConfig$RuntimeConfig.<init>(ResourceConfig.java:1144)
  at org.glassfish.jersey.server.ResourceConfig.createRuntimeConfig(ResourceConfig.java:1140)
  at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:299)
  at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:272)
  at org.glassfish.jersey.test.JerseyTest.<init>(JerseyTest.java:142)
  at com.mypackage.rest.SomeTest.<init>(RestServiceTest.java:19)

这是由 Jersey 和 ASM 4.1 之间的不兼容引起的(Jersey 使用具有不同组 ID 的 3.3.1),这是从另一个模块中提取的传递依赖。

顺便说一句,我知道 IDEA 13 具有更好的 Gradle 集成,但是 (a) 我们有 12 的许可证,并且不会很快升级整个开发团队,并且 (b) IDEA 13 在多语言方面仍然存在一些问题Gradle 项目 (Java/Scala),因此不符合要求。

【问题讨论】:

    标签: java intellij-idea gradle dependency-management


    【解决方案1】:

    排除 Maven 依赖的所有传递依赖,但显式添加所有必需的库。除了 'some:transitive:2.1',我假设你可以在没有它的情况下运行你的代码。

    group:'some', name:'dependency', version:'1.0' {
        transitive = false
    }
    // add required transitive libraries here
    

    另外,请尝试使用最新版本的 Gradle 运行您的原始代码。

    【讨论】:

    • 不幸的是,我不再使用 Gradle,如果有人可以确认这是可行的,我会接受。谢谢!
    • 这不起作用,我刚刚检查了 Gradle 2.3 和 Intellij IDEA 14.1.2,设置与 OP 类似
    猜你喜欢
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 2012-12-05
    • 2015-05-15
    • 2014-09-22
    • 2017-06-15
    • 2017-09-08
    • 1970-01-01
    相关资源
    最近更新 更多