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
}
}
...
}
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
}
}
}
Yes, I know, there are many question about similar problems, but I haven't found an answer for me.
I want to host a telegram bot written in Kotlin on Heroku.
My gradle file:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.41'
id 'distribution'
}
jar {
baseName = 'mybot'
version = '0.1'
}
group 'ru.ilagent.mybot'
version '0.1'
repositories {
mavenCentral()
maven { url "https://jitpack.io" }
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation 'io.github.seik.kotlin-telegram-bot:telegram:0.3.4'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
task stage {
dependsOn installDist
}
I follow the instruction https://devcenter.heroku.com/articles/getting-started-with-kotlin#deploy-the-app , also I've added stage and jar. I can push my bot to heroku and call ps:scale successfully. But nothing works. When I'm finding out logs, I see the error: "Unable to access jarfile build/libs/mybot-0.1.jar" . When I call the jar task locally, jar-file is created with a path mentioned in the log.
Also I've created Procfile
web: java -jar build/libs/mybot-0.1.jar
Something went wrong (. Please, help!
That's working code:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.41'
}
version '0.1'
apply plugin: 'application'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url "https://jitpack.io" }
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation 'io.github.seik.kotlin-telegram-bot:telegram:0.3.4'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
mainClassName = 'ru.ilagent.mybot.MainKt'
task stage {
dependsOn installDist
}
and Procfile
web: build/install/mybot/bin/mybot
Hope that be helpful for anybody)
Could you please help me to find a proper way to rename built artifact with Gradle 5 Kotlin DSL
I created a Gradle 5.5.1 Spring Boot 2 project based on Kotlin DSL.
After executing gradle build the built artifact is inside $buildDir/libs folder.
How can I rename it? Let's say I want to give a simple name - app.jar
plugins {
id("java")
id("idea")
id("org.springframework.boot") version "2.1.5.RELEASE"
id("io.spring.dependency-management") version "1.0.8.RELEASE"
}
group = "com.hbv"
version = "1.0.0-SNAPSHOT"
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.5.RELEASE")
}
}
the<DependencyManagementExtension>().apply {
imports {
mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
}
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation(platform("org.springframework.cloud:spring-cloud-dependencies:Greenwich.RELEASE"))
implementation("org.springframework.cloud:spring-cloud-starter-config")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-security")
testImplementation("com.h2database", "h2")
testImplementation("org.springframework.boot", "spring-boot-starter-test")
testImplementation("org.springframework.security", "spring-security-test")
}```
Configure the bootJar task which is generating the jar and is a gradle jar task and set its archiveFileName property:
tasks {
bootJar {
archiveFileName.set("app.jar")
}
}
define archiveBaseName in jar task
tasks.withType<Jar> {
archiveBaseName.set("app")
manifest {
attributes["Main-Class"] = application.mainClass
attributes["Implementation-Version"] = archiveVersion
attributes["Implementation-Title"] = "Test for App"
}
}
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
}
}
}