Java 我可以用Gradle强制类路径中的依赖项顺序吗?
一个项目在谷歌应用程序引擎上运行。该项目具有依赖项,该依赖项使用的类由于安全约束而无法在App Engine上调用(未启用)。我的解决方案(非常粗糙)是将该类的修改版本复制到我的项目中(匹配原始类的名称和包),而不需要受限类。我认为这在dev和live上都有效,因为我的源代码出现在外部依赖项之前的类路径中 为了使它更简洁,我决定将该类的修改版本放入它自己的项目中,该项目可以打包在一个jar中,并发布给任何其他人,以供他们在遇到此问题时使用 这是我的身材。格雷德尔:Java 我可以用Gradle强制类路径中的依赖项顺序吗?,java,google-app-engine,gradle,classpath,dependency-management,Java,Google App Engine,Gradle,Classpath,Dependency Management,一个项目在谷歌应用程序引擎上运行。该项目具有依赖项,该依赖项使用的类由于安全约束而无法在App Engine上调用(未启用)。我的解决方案(非常粗糙)是将该类的修改版本复制到我的项目中(匹配原始类的名称和包),而不需要受限类。我认为这在dev和live上都有效,因为我的源代码出现在外部依赖项之前的类路径中 为了使它更简洁,我决定将该类的修改版本放入它自己的项目中,该项目可以打包在一个jar中,并发布给任何其他人,以供他们在遇到此问题时使用 这是我的身材。格雷德尔: // my jar that
// my jar that has 'fixed' version of Class.
compile files('path/to/my-hack-0.0.1.jar')
// dependency that includes class that won't run on appengine
compile 'org.elasticsearch:elasticsearch:1.4.4'
在我的本地开发服务器上,这工作正常,代码首先在运行时找到我的类的黑客版本。在live上,由于未知原因,首先加载elasticsearch依赖项中的版本
我知道在类路径中拥有同一类的两个版本并不理想,但我希望我可以可靠地强制我的版本位于类路径的开头。有什么想法吗?或者,有没有更好的方法来解决这个问题?我应该研究的是appengine类加载器,而不是gradle appengine允许您在
appengine web.xml
中使用少量xml。就我而言:
<class-loader-config>
<priority-specifier filename="my-hack-0.0.1.jar"/>
</class-loader-config>
这是因为它正在加载一个旧的org.json
依赖项,这是上帝知道的。我通过将以下内容添加到appengine-web.xml中进行了修复:
<class-loader-config>
<priority-specifier filename="json-20180130.jar"/>
</class-loader-config>
根据,依赖顺序定义了类路径中的顺序。因此,我们可以简单地将库按“依赖项”的正确顺序排列
但要当心!以下是两条优先级更高的规则:
- 对于动态版本,“较高”的静态版本优于“较低”的版本
- 由模块描述符文件(Ivy或POM文件)声明的模块优先于仅具有工件文件的模块
build.gradle
的相关部分的外观
configurations {
priority
sourceSets.main.compileClasspath = configurations.priority + sourceSets.main.compileClasspath
}
dependencies {
priority 'org.blah:JarB:2.3'
compile 'org.blah:JarA:2.4'
...
}
决定类装入顺序的不是gradle,而是类装入器本身。通常有一些规则确定类装入器层次结构中的类装入顺序,但是如果类在一个类装入器(afaik)的上下文中装入,则装入顺序没有定义,也不能保证保持不变(除非是一个非常特殊的类装入器保证了这种行为)。Huzzah,谢谢@DaniloTommasina!当然,我应该调查的是appengine类加载器,而不是gradle。我找到了一个解决方案,详细信息如下,如果您感兴趣的话……这有变化吗?我在文档中看不到任何类似的内容
compile 'org.json:json:20180130'
configurations {
priority
sourceSets.main.compileClasspath = configurations.priority + sourceSets.main.compileClasspath
}
dependencies {
priority 'org.blah:JarB:2.3'
compile 'org.blah:JarA:2.4'
...
}