Gradle idea插件排除了未排除的其他子项目的传递依赖性

时间:2014-02-10 20:01:53

标签: java intellij-idea gradle dependency-management

我有一个具有以下依赖结构的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.1module1的传递)。这是因为它在运行时与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使用3.3.1,它具有不同的组ID),这是从另一个模块中提取的传递依赖。

顺便说一下,我知道IDEA 13有更好的Gradle集成但是(a)我们有12个许可证而不是很快就升级整个开发团队而且(b)IDEA 13仍然有一些问题与多语言Gradle项目(Java / Scala),因此不适合该法案。

1 个答案:

答案 0 :(得分:0)

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

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

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