我正在尝试使用Gradle来构建一些jar,而不是维护一个包含EJB的类列表,这样我就可以单独部署它了。我认为在制作jar时扫描类可能很简洁。
不是加载类并使用反射来获取注释,我认为用asm扫描类可能更简单,因此在其中一个任务中使用chuncky ClassReader。
我不认为这是问题所以可以忽略,基本上我有两个任务,我用来定义罐子的内容,都报告不同的内容通过eachFile打印出来,但是当我查看发布存储库位置,两个文件和关联的sha1都是相同的。
要么Gradle被破坏了,或者更有可能的是,我做了一些疯狂的事情,却看不到它是什么,有人可以帮忙吗?
顺便说一句,如果我禁用任何一个jar文件的发布,那么确实创建的那个是正确的,所以我认为发布的内容有些不对,而不是发生震动,但可能是错误的。
// ASM is used to interpret the class files, this avoids having to load all classes in the vm and use reflection
import org.objectweb.asm.*
task ejbJar(type: Jar) {
//outputs.upToDateWhen { false }
from "${project.buildDir}/classes/main"
eachFile { println "EJB server: ${name}" }
include getEjbClassFiles(project.buildDir)
}
task clientEjbJar(type: Jar) {
//outputs.upToDateWhen { false }
from "${project.buildDir}/classes/main/com/company/core/versioner"
eachFile { println "Client EJB ${name}" }
include '**/*'
}
artifacts {
archives clientEjbJar
archives ejbJar
}
String[] getEjbClassFiles(base) {
def includedFiles = []
def baseDir = project.file("${base}/classes/main")
def parentPath = baseDir.toPath()
if (baseDir.isDirectory()) {
baseDir.eachFileRecurse(groovy.io.FileType.FILES) { file ->
if(file.name.endsWith('.class')) {
//get hold of annotations in there --- org.objectweb.asm.Opcodes.ASM4
def reader = new ClassReader(file.bytes).accept(
new ClassVisitor(Opcodes.ASM4) {
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if(desc.equals("Ljavax/ejb/Stateless;") ||
desc.equals("Ljavax/ejb/Stateful;")) {
includedFiles += parentPath.relativize(file.toPath())
}
return null //no interest in actually visiting the annotation values
}
},
ClassReader.SKIP_DEBUG | ClassReader.EXPAND_FRAMES | ClassReader.SKIP_FRAMES | ClassReader.SKIP_CODE
)
}
}
}
return includedFiles
}
publishing {
publications {
mypub(IvyPublication) {
artifact(ejbJar) {
name 'ejb'
}
artifact(clientEjbJar) {
name 'client-ejb'
}
}
}
repositories {
ivy {
name 'personal'
url "${ant['developer.repository']}/"
layout 'pattern', {
artifact "[organisation]/[module]/[artifact]/[revision]/[type]/[artifact]-[revision].[ext]"
ivy "[organisation]/[module]/[type]/[revision]/[type]/[type]-[revision].[ext]"
}
}
}
}
我确实把事情分解成一个更简单的形式,因为我认为它可能是一个Gradle bug。
简化形式是:
apply plugin: 'java'
apply plugin: 'ivy-publish'
task bigJar(type: Jar) {
from "${rootDir}/src/main/resources"
include '**/*'
}
task smallJar(type: Jar) {
from "${rootDir}/src/main/resources/A/B"
include '**/*'
}
group 'ICantBeEmpty'
artifacts {
archives bigJar
archives smallJar
}
publishing {
publications {
mypub(IvyPublication) {
artifact(bigJar) { name 'biggie' }
artifact(smallJar) { name 'smallie' }
}
repositories {
ivy {
name 'personal'
url "c:/temp/gradletest"
layout 'pattern', {
artifact "[organisation]/[module]/[artifact]/[revision]/[type]/[artifact]-[revision].[ext]"
ivy "[organisation]/[module]/[type]/[revision]/[type]/[type]-[revision].[ext]"
}
}
}
}
}
这导致c中的2个文件:/temp/gradletest/ICantBeEmpty/report-bug/biggie/unspecified/biggie-unspecified.jar和c:/ temp / gradletest / ICantBeEmpty / report-bug / smallie / unspecified / smallie -unspecified.jar 这两个文件都是相同的,但我想我知道为什么会看到我以后的答案。
答案 0 :(得分:1)
在查看某些配置时,我注意到一些奇怪的行为导致我解决了这个问题,这是一个Gradle错误。
在我的构建中,我做了一个临时任务
configurations.archives.artifacts.each { println it }
这给了我5个不同的行输出,但是将其更改为
configurations.archives.artifacts.each { println it.file }
生成相同的文件名5次。
事实证明这与我的问题有关,虽然工件作为单独的实体存在,但用于唯一标识它们的名称是相同的,因此在发布期间始终选择相同的文件。工件的名称由$ {baseName} - $ {appendix} - $ {version} - $ {classifier}。$ {extension}默认在java插件中提供。这意味着如果既未指定附录或分类,则工件将具有相同的名称。
我使用上面的示例代码通过添加附录名称
对此进行了测试task bigJar(type: Jar) {
appendix = 'big'
from "${rootDir}/src/main/resources"
include '**/*'
}
task smallJar(type: Jar) {
appendix = 'small'
from "${rootDir}/src/main/resources/A/B"
include '**/*'
}
使用此而不是问题中的代码会产生2个不同的罐子。
答案 1 :(得分:0)
这不是一个完整的答案,但是一个足够好的解决方案,如果我添加一个新的发布定义,我可以将我想要的工件发布到我想要的位置,唯一的缺点是它将创建另一个gradle任务这不太理想。
publications {
mypub(IvyPublication) {
artifact(ejbJar) {
name 'ejb'
}
}
newpub(IvyPublication) {
artifact(clientEjbJar) {
name 'client-ejb'
}
}
}
答案 2 :(得分:0)
上述答案在短期内有效,但确实揭示了Gradle世界的另一个短暂的问题enter link description here
目前还不确定Gradle是否可能,到目前为止还没有人回答我的问题,所以可能不是那么积极开发!!
答案 3 :(得分:0)
我不是Gradle这一部分的专家,但您使用的功能标记为“incubating”;您正在使用可能或可能不完整的新发布功能。也许你应该使用old way做事。您似乎也通过使用artifacts
闭包来混合两种方式。