【发布时间】: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