publish final jar file in artifactory using gradle - gradle

I am trying to publish jar file (output of a gradle project) to jfrog/artifactory. The project is successful when I execute gradlew build or gradlew build artifactoryPublish. I also see on console that Build successfully deployed. Browse it in Artifactory under https://... but when I go to Artifactory the nothing is there. I tried following the jfrog/artifactory documentation, some questions on stackoverflow like this one and this one. Following is the snippet from my build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
//Check for the latest version here: http://plugins.gradle.org/plugin/com.jfrog.artifactory
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4+"
}
}
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
apply plugin: 'io.spring.dependency-management'
allprojects {
apply plugin: "com.jfrog.artifactory"
}
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:29.0-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.13'
}
task sourceJar(type: Jar){
from file("build/libs/mygradle-1.0.0-sources.jar")
classifier = 'sources'
}
task certify(type: Zip, group: 'build', dependsOn: 'build') {
from ("build.gradle")
from ("libs")
from ("src/test")
from ("build/libs")
from ("${buildDir}/reports/tests")
archiveFileName = "certify-resources.zip"
destinationDirectory = file("${buildDir}/certify")
}
version = '1.0.0'
group = 'com.mypro.test' // this is the package prefix the jar will go into artifactory
artifacts {
archives sourceJar
}
publishing {
publications {
pluginJar(MavenPublication) {
groupId "${group}"
artifactId 'mygradle' // this is the package suffix the jar will go into in artifactory
version "${version}"
artifact sourceJar
from components.java
}
}
}
artifactory {
contextUrl = "${artifactory_contextUrl}" //The base Artifactory URL if not overridden by the publisher/resolver
publish {
repository {
repoKey = 'gradle-release-local'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
resolve {
repository {
repoKey = 'gradle-dev'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}
I am not sure what I am missing. Could anyone suggest what I missed. Thanks
EDIT: I created new instance of rhel/artifactory and a new gradle project just to be sure that the issue is not coming from somewhere else but still
only this information Build-info successfully deployed. Browse it in Artifactory under http://100.100.11.11:8081/artifactory/webapp/builds/mygradle/1675035714284 is showing when I execute gradlew build artifactoryPublish with
BUILD SUCCESSFUL

The JAR component can be extracted from components.java.
Try to add it to the publication as following:
pluginJar(MavenPublication) {
groupId "${group}"
artifactId 'my-published-project'
version "${version}"
artifact sourceJar
from components.java // <- add this line
}
the java component in its default setup consists of a JAR — produced by the jar task
For more information see Component terminology and Maven publications.
EDIT:
Also, since "pluginJar" is not a default publication name, we should add the publication to the list (the plugin adds mavenJava and ivyJava by default).
artifactory {
contextUrl = "${artifactory_contextUrl}" //The base Artifactory URL if not overridden by the publisher/resolver
publish {
repository {
repoKey = 'gradle-release-local'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
defaults {
publications('pluginJar') // <- add this
}
}
...
}

Related

BootJar + MavenJar. Artifact wasn't produced by this build

I have a sample project with the following hierearhy:
Sample (root)
-- model (simple jar)
-- api (springboot jar)
I want to publish both generated jars: plain jar & bootJar to my localRepository.
gradlew clean build -xTest publishToMavenLocal
However, the following error occures:
* What went wrong:
Execution failed for task ':api:publishMavenJavaPublicationToMavenLocal'.
> Failed to publish publication 'mavenJava' to repository 'mavenLocal'
> Artifact api.jar wasn't produced by this build.
The root build.gradle is a follows:
plugins {
id 'java'
id "org.springframework.boot" version "2.2.5.RELEASE" apply false
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
}
group 'sample'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
ext {
artifactVersion = version
springBootVersion = "2.2.5.RELEASE"
}
allprojects {
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'maven'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
repositories {
mavenCentral()
jcenter()
}
}
subprojects {
apply plugin: "io.spring.dependency-management"
apply plugin: "maven-publish"
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencyManagement {
imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootVersion}"
}
}
dependencies {
implementation "org.springframework.boot:spring-boot-dependencies:${springBootVersion}"
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId project.group
artifactId project.name
version project.version
from components.java
}
}
}
}
api build.gradle
apply plugin: 'org.springframework.boot'
dependencies {
compile project(":model")
implementation "org.springframework.boot:spring-boot-starter-web"
}
bootJar {
}
Adding bootJava task to api build.gradle allowes to publish the bootJar directly from api module, but the root publish task remains broken.
publishing {
publications {
bootJava(MavenPublication) {
artifact bootJar
}
}
}
I've tried almost every solution from docs & google, but none seem to work.
Can anyone explain, what is misconfigured?
Gradle version: 6.3
As stated by gradle documentation here:
Starting from Gradle 6.2, Gradle performs a sanity check before uploading, to make sure you don’t upload stale files (files produced by another build). This introduces a problem with Spring Boot applications which are uploaded using the components.java component
More explanation is available in the link above.
They propose the following workaround that I personally tried and worked for me :
configure the outgoing configurations
configurations {
[apiElements, runtimeElements].each {
it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
it.outgoing.artifact(bootJar)
}
}
here after the configuration from my build.gradle:
....
apply plugin: 'maven-publish'
...
configurations {
[apiElements, runtimeElements].each {
it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
it.outgoing.artifact(bootJar)
}
....
}
publishing {
publications {
myPublication(MavenPublication) {
groupId groupId
artifactId artifactId
version version
from components.java
versionMapping {
usage('java-api') {
fromResolutionOf('runtimeClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
}
}
repositories {
maven {
url azureRepoUrl
name azureRepoName
credentials {
username azureRepoUserName
password azureRepoAccessToken
}
}
}
}
Excerpt from
Starting from Gradle 6.2, the main jar task is disabled by the Spring Boot application, and the component expects it to be present. Because the bootJar task uses the same file as the main jar task by default, previous releases of Gradle would either:
publish a stale bootJar artifact
or fail if the bootJar task hasn’t been called previously
To simple workaround would be configuring the outgoing configurations. For multi-module Gradle project, place the below configuration in the service module(spring boot module).
dependencies {
.....
}
configurations {
[apiElements, runtimeElements].each {
it.outgoing.artifacts.removeIf {
it.buildDependencies.getDependencies(null).contains(jar)
}
it.outgoing.artifact(bootJar)
}
}
Note: There is no need for changing anything with artifactory task if it was configured correctly. This working solution has been tested with Gradle 6.4.1.
Don't try the alternate suggestion that they provided, because classifier attribute is deprecated in recent versions, also altering the bootJar task with custom configuration would result in improper uber jar construction, and if you extract the generated jar distributive, you could find the missing BOOT-INF directory and necessary META-INF/MANIFEST.MF values.
jar {
enabled = true
}
bootJar {
classifier = 'application'
}
Update:
From Spring Boot 2.5.0, jar task generates an additional jar archive which ends with -plain.jar. It may break someone's build if they have used some patterns like *.jar to copy the build archive, hence, to restrict the additional jar creation, the following jar task configuration code snippet should be used.
jar {
enabled = false
}
I could get this worked by just adding artifact bootJar in the publishing task as shown below and with out adding any configurations as suggested in the gradle documentation. I believe this could be working same as their first workaround in the documentation. Tested with gradle 6.5.1
publishing {
publications {
mavenJava(MavenPublication) {
artifact bootJar
artifact sourceJar {
classifier "sources"
}
}
}
}
project.tasks.publish.dependsOn bootJar
According to the 'Gradle' documentation under,
https://docs.gradle.org/current/userguide/upgrading_version_6.html#publishing_spring_boot_applications
Just add the following to the build.gradle file
jar {
enabled = true
}
bootJar {
classifier = 'application'
}
If you are using gradle kotlin dsl add the equivalent in your build.gradle. It worked for me
configurations {
val elements = listOf(apiElements, runtimeElements)
elements.forEach { element ->
element.get().outgoing.artifacts.removeIf { it -> it.buildDependencies.getDependencies(null).contains(tasks.jar.get())}
element.get().outgoing.artifact(tasks.bootJar.get())
}
}
For Spring Boot 2.5.0+, this configurations works for publishing the embedded jar, its sources and javadoc:
plugins {
id 'maven-publish'
id 'java-library'
}
jar {
enabled = false
}
java {
withSourcesJar()
withJavadocJar()
}
publishing {
publications {
publication(MavenPublication) {
artifact bootJar
from components.java
}
}
}

Not able to download jar from Artifactory repository in gradle project

I want to connect to the Artifactory repository
https://www.artifactrepository.citigroup.net/artifactory/webapp/#/artifacts/browse/tree/General/
and download a jar using build.gradle.
I have 2 repository in my code, which I want to connect: one is local and is where I've download all Gradle related jars and the other is artifactory repository where I want to download TIBCO related jars.
but not able to connect to second repo
This is my build.gradle code
buildscript {
repositories {
maven {
url "${artifactory_contextUrl}/plugins-release"
}
maven {
url 'https://www.artifactrepository.citigroup.net/artifactory/maven-cto-dev-3rdpartymanual-local'
}
}
dependencies {
classpath(group: 'org.jfrog.buildinfo', name: 'build-info-extractor-gradle', version: '2.0.9')
}
}
allprojects {
apply plugin: 'artifactory'
apply plugin: 'maven'
group = 'com.citi.recon'
task wrapper(type: Wrapper) {
distributionUrl = "${artifactory_contextUrl}/simple/ext-release-local/org/gradle/services/distributions/gradle/1.9/gradle-1.9-bin.zip"
description = 'Generates gradlew[.bat] scripts'
gradleVersion = '1.9'
}
}
artifactory {
contextUrl = "${artifactory_contextUrl}" //The base Artifactory URL if not overridden by the publisher/resolver
publish {
repository {
repoKey = 'libs-release-local'
maven = true
}
}
resolve {
repository {
repoKey = 'repo'
maven = true
}
}
}

Gradle Maven publish to nexus delombok source code

I'm using following setup:
gradle 5.2.1
nexus publish
lombok 1.18.6
lombok gradle plugin io.freefair.lombok 3.1.4
I would like to upload sourceJar to nexus after delombok is done.
For maven publishing I use the following:
task javadocJar(type: Jar) {
from javadoc.destinationDir
classifier = 'javadoc'
}
task sourcesJar(type: Jar) {
from sourceSets.main.allJava
classifier = 'sources'
}
...
publications {
maven(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
}
}
Sources uploaded to nexus are just one to one with my original source. How to change configuration so that uploaded sources are delombok sources?
Here’s a self-contained example that produces the desired delomboked source JAR and publishes it to a Maven repository (using ./gradlew publishMavenPublicationToMyRepoRepository):
plugins {
id 'java'
id 'maven-publish'
id 'io.freefair.lombok' version '3.1.4'
}
group = 'com.example'
version = '0.1'
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.6'
annotationProcessor 'org.projectlombok:lombok:1.18.6'
}
task javadocJar(type: Jar) {
from javadoc.destinationDir
classifier = 'javadoc'
}
task sourcesJar(type: Jar) {
///////////////////////////////////////////////
// This is the relevant change:
from sourceSets.main.delombokTask
///////////////////////////////////////////////
classifier = 'sources'
}
publishing {
repositories {
maven {
name = 'myRepo'
url = 'file:///tmp/myRepoDir'
}
}
publications {
maven(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
}
}
}
Please note that the example doesn’t use “nexus publish” but instead it simply publishes to a simple file system repository. As far as I understood your question, the actual uploading is not the problem but rather the creation of the delomboked source JAR.

download jars and wars from artifactory and copy to a specific folder using gradle

I am new to gradle and artifactory and trying to download jars and wars from artifactory and copy to a specific folder using gradle. How can I do this?
My artifactory repository is a generic one where in I am uploading all the jars and wars. From here I want to download them and copy them to a folder.
This is what I got from the artifactory. I replaced the repoKey with my-repo where the jar and war files are located.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4+"
}
}
allprojects {
apply plugin: "com.jfrog.artifactory"
}
artifactory {
contextUrl = "${artifactory_contextUrl}"
publish {
repository {
repoKey = 'my-repo-upload'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
resolve {
repository {
repoKey = 'my-repot'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}

Gradle artifactory plugin cannot resolve dependency on configuration phase

I am trying to resolve dependency in configuration phase with artifactory gradle plugin.
apply plugin: 'java'
apply plugin: 'com.jfrog.artifactory'
artifactory {
contextUrl = "${artifactory_contextUrl}"
...
resolve {
repository {
repoKey = 'repo'
username = "${artifactory_user}"
password = "${artifactory_password}"
maven = true
}
}
}
dependencies {
compile 'commons-lang:commons-lang:+'
}
task testCustomResolve {
logger.quiet configurations.getByName('compile').singleFile.absolutePath
}
And it gives me
Could not resolve all dependencies for configuration ':compile'.
Cannot resolve external dependency commons-lang:commons-lang:+ because no repositories are defined.
It works as a charm in execution phase
task testCustomResolve << {
logger.quiet configurations.getByName('compile').singleFile.absolutePath
}
or when I use mavenCentral()
repositories {
mavenCentral()
}
In case you don't need to publish to Artifactory, I noticed that it works better if you don't use the artifactory {} syntax. Instead, try using:
plugins {
id "com.jfrog.artifactory" version "4.4.10"
}
repositories {
mavenLocal()
maven {
url "${artifactory_contextUrl}/${artifactory_repo}"
credentials {
username = "${artifactory_user}"
password = "${artifactory_password}"
}
}
mavenCentral()
}

Resources