2013-04-08 2 views
0

Я экспериментирую с Gradle, чтобы построить несколько банок, вместо того, чтобы поддерживать список классов, в которых есть EJB, чтобы я мог развернуть их отдельно. Я думал, что может быть аккуратно сканировать классы при создании банку.Опубликовать артефакт переписать другой артефакт в Gradle

Вместо того, чтобы загружать классы и использовать отражение, чтобы получить аннотации, я подумал, что проще просканировать классы с помощью asm, следовательно, классный ClassReader в одной из задач.

Я не думаю, что это проблема, поэтому ее можно игнорировать, в основном у меня есть 2 задачи, которые я использую для определения содержимого банок, оба сообщают, что через них каждый контент отправляется через распечатку eachFile, однако когда я смотрю в месте публикации репозитория, оба файла и связанный с ним sha1 идентичны.

Либо Gradle сломан или, скорее, я сделал что-то сумасшедшее, но не могу понять, что это такое, может ли кто-нибудь помочь?

Кстати, если я отключу публикацию любого из файлов jar, тот, который создается, правильный, поэтому я думаю, что это что-то не так с публикацией, а не с jarring, но может быть неправильным.

// 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]" 
     } 
    } 
    } 
} 

Я действительно сломал предмет в более простой форме, поскольку я думал, что это может быть ошибка Грейдл.

Упрощенная форма была:

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]" 
    } 
     } 
    } 
    } 
} 

Это приводит к 2 файлам в C: /temp/gradletest/ICantBeEmpty/report-bug/biggie/unspecified/biggie-unspecified.jar и с:/температурами/gradletest/ICantBeEmpty/report-bug/smallie/unpecified/smallie-unspecified.jar Оба эти файла идентичны, однако я думаю, что знаю, почему я вижу мой более поздний ответ.

ответ

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 различные банки.

0

Это не полный ответ, но достаточно хорошая работа, если я добавлю новое определение публикации, я могу опубликовать артефакты, которые я хочу, чтобы место, которое я хочу, единственный недостаток в том, что он создаст еще один град задача, которая не является идеальной.

publications { 
     mypub(IvyPublication) { 
     artifact(ejbJar) { 
      name 'ejb' 
     } 
     } 
     newpub(IvyPublication) { 
     artifact(clientEjbJar) { 
      name 'client-ejb' 
     } 
     } 
    } 
0

выше ответ работает в краткосрочной перспективе, однако это выявить еще один короткий приход в мире Gradle enter link description here

Не уверен Gradle все это может быть в данный момент, и до сих пор никто не имеет ответил на мои вопросы, так что, возможно, это не так активно развивается !!

0

Я не эксперт в этой части Gradle, но функциональность, которую вы используете, отмечена как «incubating»; вы используете новую функцию публикации, которая может быть или не быть полной. Возможно, вам следует использовать old way. Вы также, кажется, смешиваете оба способа, используя закрытие artifacts.

+0

спасибо за интерес, но ссылка «старый путь» показывает мне именно то, что я уже делаю в стороне от того факта, что я использую реплика плюща, а не плоский файл. Потому что что-то находится в состоянии инкубации, это не значит, что его нельзя использовать, и вопрос поднят об этом, это сущность открытого источника, развивающегося так быстро. Я действительно определил проблему сейчас, поскольку имя, используемое для поиска артефактов в конфигурации, не уникально и опубликует полное описание, чтобы сохранить других пользователей Gradle в ту же самую проблему. –

Смежные вопросы