Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我可以用Gradle强制类路径中的依赖项顺序吗?_Java_Google App Engine_Gradle_Classpath_Dependency Management - Fatal编程技术网

Java 我可以用Gradle强制类路径中的依赖项顺序吗?

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

一个项目在谷歌应用程序引擎上运行。该项目具有依赖项,该依赖项使用的类由于安全约束而无法在App Engine上调用(未启用)。我的解决方案(非常粗糙)是将该类的修改版本复制到我的项目中(匹配原始类的名称和包),而不需要受限类。我认为这在dev和live上都有效,因为我的源代码出现在外部依赖项之前的类路径中

为了使它更简洁,我决定将该类的修改版本放入它自己的项目中,该项目可以打包在一个jar中,并发布给任何其他人,以供他们在遇到此问题时使用

这是我的身材。格雷德尔:

// 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文件)声明的模块优先于仅具有工件文件的模块

不确定这是否是访问此问题的人想要的,但这正是我的问题和解决方案所在。 jara:包含类XYZ jarb:还包含类XYZ 我的项目需要类路径上的jarb,然后才能编译jara

问题是Gradle在解析依赖项后根据字母顺序对它们进行排序,这意味着JARB将在生成的类路径中位于JARA之后,从而导致编译时出错

解决方案: 声明自定义配置并修补compileClasspath。这就是
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'
    ...
}