使用 Gradle 将依赖项打包在 WAR 中,同时在 EAR 中保留瞬态依赖项
Using Gradle to package dependencies in a WAR, while leaving transient dependencies in the EAR
我很新Gradle。我前几天才开始看,我真的很喜欢它,所以我正在尝试将我的项目转换为 Gradle.
我刚刚运行进入我的第一个难题。我想不出如何防止 'war' 插件复制大量已在我的 EAR 中找到的 t运行sient 依赖项。例如,假设我想在 WAR 中使用 org.springframework:spring-web
。这个 jar 有很多 t运行sient 依赖项,它们都打包在 WEB-INF/lib
中。这是一个问题,b/c 所有这些依赖项已经在我的 EAR 的 APP-INF/lib
中,b/c 还有其他模块使用它们。
我想告诉 Gradle 我希望像往常一样用所有依赖项编译 WAR 代码,但是当涉及到打包 WAR,我想对进入 WEB-INF/lib
的内容有一些控制。据我所知,此功能不存在。还是我遗漏了什么?
我现在已经用 hack 解决了这个问题,但我觉得一定有更简单的方法来做到这一点。希望有经验的人指出我这里哪里出错了。
这是我目前拥有的:
apply plugin: 'war'
configurations {
// Use this config to indicate that a module should be packaged inside the WAR w/o its transitive dependencies
//
packageWithoutDependencies
// Use this one when you want to package this module and all of its dependencies in the WAR
//
packageWithDependencies
compile.extendsFrom packageWithoutDependencies
compile.extendsFrom packageWithDependencies
}
dependencies {
packageWithDependencies "org.richfaces:richfaces-bom:$richFacesVersion"
packageWithDependencies "org.richfaces.ui:richfaces-components-ui:$richFacesVersion"
packageWithDependencies "org.richfaces.core:richfaces-core-impl:$richFacesVersion"
packageWithoutDependencies "org.springframework:spring-web:$springVersion"
packageWithoutDependencies "org.springframework.security:spring-security-config:$springSecurityVersion"
packageWithoutDependencies "org.springframework.security:spring-security-taglibs:$springSecurityVersion"
packageWithoutDependencies "org.springframework.security:spring-security-web:$springSecurityVersion"
}
// The approach here is to directly modify the classpath used by the 'war' task. This is necessary
// b/c we want to compile with all the dependencies resolved as per usual, yet when we deploy,
// we only want the jars that belong in the WAR, with most transitive dependencies for those already
// deployed as 3rd party jars in the EAR.
//
task modifyWarClasspath << {
// Get the names of all non-transitive modules we are packaging
//
println " ========= WAR Modules w/o dependencies ========= "
def firstLevelDeps = configurations.packageWithoutDependencies.resolvedConfiguration.firstLevelModuleDependencies
def nonTransientDepNames = firstLevelDeps.collect { it.moduleName }
println nonTransientDepNames
// Get the names of all direct file includes we are packaging
//
println "\n ========= WAR Files w/o dependencies ========= "
def directFileIncludes = configurations.packageWithoutDependencies
.getDependencies().findAll{it.hasProperty('source')}
.source.files*.name.flatten()
println directFileIncludes
// Get the names of all transitive modules we a re packaging
//
println "\n ========= WAR Modules with dependencies ========= "
def recursiveDeps = configurations.packageWithDependencies.resolvedConfiguration
.firstLevelModuleDependencies*.allModuleArtifacts.flatten()
def transientDepNames = recursiveDeps.collect { it.name }
println transientDepNames
// Look through the WAR classpath (runtime - providedCompile), and keep only those
// files that match a module name on either of the 3 lists we made above.
//
println "\n ========= Packaging jars in the WAR ========= "
war.classpath = war.classpath.findAll {file ->
((nonTransientDepNames + transientDepNames + directFileIncludes + 'main').find {directDepName ->
file.name.startsWith(directDepName)
} != null)
}
war.classpath*.name.sort().each { println it }
println "\n\n"
}
// Enable 'packageWithDependencies' and 'packageWithoutDependencies' configs
war {
dependsOn modifyWarClasspath
}
我现在有一个很好的简单解决方案。关键是利用 'provided' 范围,然后在我的 WAR 依赖项中使用它来引用我的 EAR 依赖项。这样,整个 WAR 类路径就会从 EAR 依赖项中减去可访问的类路径,因此只有 Web 依赖项被打包到 WAR 中。漂亮又简单。
方法如下:
configurations {
provided {
dependencies.all { dep ->
configurations.default.exclude(group: dep.group, module: dep.name)
}
}
compile.extendsFrom provided
}
然后在您的 WAR 项目中,您可以:
dependencies {
provided project(':DFIPConfig')
provided project(':DFIPSAPBatch')
provided project(':DFIPDomain')
// etc...
compile project(':DryDockProjects:DryDockWebProjects:CommonWebWCAGJar')
compile project(':DryDockProjects:DryDockWebProjects:CommonParticipantWeb')
// etc...
// Other WAR dependencies as per usual
}
我很新Gradle。我前几天才开始看,我真的很喜欢它,所以我正在尝试将我的项目转换为 Gradle.
我刚刚运行进入我的第一个难题。我想不出如何防止 'war' 插件复制大量已在我的 EAR 中找到的 t运行sient 依赖项。例如,假设我想在 WAR 中使用 org.springframework:spring-web
。这个 jar 有很多 t运行sient 依赖项,它们都打包在 WEB-INF/lib
中。这是一个问题,b/c 所有这些依赖项已经在我的 EAR 的 APP-INF/lib
中,b/c 还有其他模块使用它们。
我想告诉 Gradle 我希望像往常一样用所有依赖项编译 WAR 代码,但是当涉及到打包 WAR,我想对进入 WEB-INF/lib
的内容有一些控制。据我所知,此功能不存在。还是我遗漏了什么?
我现在已经用 hack 解决了这个问题,但我觉得一定有更简单的方法来做到这一点。希望有经验的人指出我这里哪里出错了。
这是我目前拥有的:
apply plugin: 'war'
configurations {
// Use this config to indicate that a module should be packaged inside the WAR w/o its transitive dependencies
//
packageWithoutDependencies
// Use this one when you want to package this module and all of its dependencies in the WAR
//
packageWithDependencies
compile.extendsFrom packageWithoutDependencies
compile.extendsFrom packageWithDependencies
}
dependencies {
packageWithDependencies "org.richfaces:richfaces-bom:$richFacesVersion"
packageWithDependencies "org.richfaces.ui:richfaces-components-ui:$richFacesVersion"
packageWithDependencies "org.richfaces.core:richfaces-core-impl:$richFacesVersion"
packageWithoutDependencies "org.springframework:spring-web:$springVersion"
packageWithoutDependencies "org.springframework.security:spring-security-config:$springSecurityVersion"
packageWithoutDependencies "org.springframework.security:spring-security-taglibs:$springSecurityVersion"
packageWithoutDependencies "org.springframework.security:spring-security-web:$springSecurityVersion"
}
// The approach here is to directly modify the classpath used by the 'war' task. This is necessary
// b/c we want to compile with all the dependencies resolved as per usual, yet when we deploy,
// we only want the jars that belong in the WAR, with most transitive dependencies for those already
// deployed as 3rd party jars in the EAR.
//
task modifyWarClasspath << {
// Get the names of all non-transitive modules we are packaging
//
println " ========= WAR Modules w/o dependencies ========= "
def firstLevelDeps = configurations.packageWithoutDependencies.resolvedConfiguration.firstLevelModuleDependencies
def nonTransientDepNames = firstLevelDeps.collect { it.moduleName }
println nonTransientDepNames
// Get the names of all direct file includes we are packaging
//
println "\n ========= WAR Files w/o dependencies ========= "
def directFileIncludes = configurations.packageWithoutDependencies
.getDependencies().findAll{it.hasProperty('source')}
.source.files*.name.flatten()
println directFileIncludes
// Get the names of all transitive modules we a re packaging
//
println "\n ========= WAR Modules with dependencies ========= "
def recursiveDeps = configurations.packageWithDependencies.resolvedConfiguration
.firstLevelModuleDependencies*.allModuleArtifacts.flatten()
def transientDepNames = recursiveDeps.collect { it.name }
println transientDepNames
// Look through the WAR classpath (runtime - providedCompile), and keep only those
// files that match a module name on either of the 3 lists we made above.
//
println "\n ========= Packaging jars in the WAR ========= "
war.classpath = war.classpath.findAll {file ->
((nonTransientDepNames + transientDepNames + directFileIncludes + 'main').find {directDepName ->
file.name.startsWith(directDepName)
} != null)
}
war.classpath*.name.sort().each { println it }
println "\n\n"
}
// Enable 'packageWithDependencies' and 'packageWithoutDependencies' configs
war {
dependsOn modifyWarClasspath
}
我现在有一个很好的简单解决方案。关键是利用 'provided' 范围,然后在我的 WAR 依赖项中使用它来引用我的 EAR 依赖项。这样,整个 WAR 类路径就会从 EAR 依赖项中减去可访问的类路径,因此只有 Web 依赖项被打包到 WAR 中。漂亮又简单。
方法如下:
configurations {
provided {
dependencies.all { dep ->
configurations.default.exclude(group: dep.group, module: dep.name)
}
}
compile.extendsFrom provided
}
然后在您的 WAR 项目中,您可以:
dependencies {
provided project(':DFIPConfig')
provided project(':DFIPSAPBatch')
provided project(':DFIPDomain')
// etc...
compile project(':DryDockProjects:DryDockWebProjects:CommonWebWCAGJar')
compile project(':DryDockProjects:DryDockWebProjects:CommonParticipantWeb')
// etc...
// Other WAR dependencies as per usual
}