Gradle + Artifactory plugin: Trying to publish the resolved dependency version - gradle

In a gradle project, I have my dependencies set as:
dependencies {
compile group: 'com.our_organization.lib', name: 'Libraries', version: '5.+'
compile group: 'commons-io', name: 'commons-io', version: '2.4'
}
which uses the latest released version of Libraries, and works perfectly.
I then release my built jar to Artifactory via:
artifactory {
contextUrl = artifactory_contextUrl
publish {
repository {
repoKey = publicationRepoKey
username = artifactory_user
password = artifactory_password
maven = true
}
}
}
which for the most part works fine.
However, when I go to artifactory and get the xml for any given version, it's dependencies are listed as
<dependencies>
<dependency org="com.our_organization.lib" name="Libraries" rev="5.+" />
<dependency org="commons.io" name="commons.io" rev="2.4" />
</dependencies>
which means I am unable to link my version to the specific Libraries version that was used for its build.
What I'd like to do is have the dependency version given to artifactory be the specific resolved version that is used in the build.
I've scoped a couple of things, all very hacky, and feel there has to be a better way.
Here's what I've thought of / tried:
Resolving the dependency myself and setting the specific version in the gradle dependency dsl, so to gradle it looks like a specific version. Using ivy to get the resolved version of a dependency of proving to be harder that it should.
Mucking the xml after its written but before it's sent to artifactory. This is just bad on so many levels and prone to breaking in the future.
Using a seperate gradle project to determine the resolved version and write that to a properties file which is then used similarly to #1. This feels like overkill.
Overall, this seems like a simple for which, for the life of me, I can't find an appropriate solution.

I am not sure what Gradle will do with it in pom.xml, but you might try using the Artifactory's functionality to retrieving the latest version, instead of Gradle's one.

The post
In Gradle, how can I generate a POM file with dynamic dependencies resolved to the actual version used?
exactly solves this problem. But you have to use the maven-publish Plugin instead of the Artifactory Plugin.

Related

Cannot import com.tibco.tibjms.TibjmsQueueConnectionFactory with Gradle

so I've been working on migrating a Maven project over onto a Gradle one. While doing so, I can across a class called TibjmsQueueConnectionFactory that I've been trying to figure out how trying to import. I've found most of my other imports on MVNRepository however, none of the ones I try for this one seem to work.
This is basically all I'm trying to do:
// https://mvnrepository.com/artifact/com.tibco/tibjms
implementation group: 'com.tibco', name: 'tibjms', version: '1.0'
I did see somewhere that Tibco may not exist at that location at all, and maybe I'll have to download a jar file, but I'm not sure if this is the case or not. Has anyone else had this issue before? How did you resolve it?
A possible maven project pom dependency solution is available in this answer.
You can get tibjms-4.1 from pom uploaded in openmindonline repo which has TibjmsQueueConnectionFactory. We are not able to access other version from icm.
Add openmindonline repo information in your repositories block in your build.gradle
repositories {
// You can declare any Maven/Ivy/file repository here.
maven {
url "http://repository.openmindonline.it/"
}
}
Then add implementation 'tibco-ems:tibjms:version:4.1' in dependencies block.
If you have jar file available locally, you can follow solutions available in this question.

Gradle Dependency Problem when Upgrading to Gradle 6

I have a gradle Project where I have a dependency on "hudson-core 3.3.3"
compile group: 'org.eclipse.hudson', name: 'hudson-core', version: '3.3.3'
This works without a problem when using Gradle 5.6.2
When I upgrade to Gradle 6.0.1 I receive the following error:
Could not resolve org.eclipse.hudson:hudson-remoting:3.0.3.
Required by:
project : > org.eclipse.hudson:hudson-core:3.3.3
project : > org.eclipse.hudson:hudson-core:3.3.3 > org.eclipse.hudson:hudson-cli:3.3.3
> Could not resolve org.eclipse.hudson:hudson-remoting:3.0.3.
> inconsistent module metadata found. Descriptor: org.eclipse.hudson:hudson-remoting:3.0.4-SNAPSHOT Errors: bad version: expected='3.0.3' found='3.0.4-SNAPSHOT'
The Repository is always the same:
repositories {
mavenCentral()
maven {
url 'http://repo.jenkins-ci.org/public/'
}
}
Any Ideas why this error happens?
As said by #ToYonos, the problem is in the dependency itself.
Not perfect solutions, but 2 workarounds can be done as explained in Gradle's documentation (v6.7.1):
Exclude that transitive dependency, for example in the current Gradle versions using implementation instead of compile:
implementation('org.eclipse.hudson:hudson-core:3.3.3') {
exclude group: 'org.eclipse.hudson'
exclude module: 'hudson-remoting'
}
Override that transitive dependency version:
implementation('org.eclipse.hudson:hudson-remoting') {
version {
strictly '3.0.2' // As 3.0.3 is having the issue
}
}
In the pom.xml file of hudson-remoting 3.0.3, the version is <version>3.0.4-SNAPSHOT</version>
The issue is quite clear.
I tried with an old Gradle 4.4.1 and I am having the exact same issue. Likewise with Gradle 5.1.1 and your version, 5.6.2
I'm quite sure that if you clean your artefact cache for Gradle 5.6.2, it won't work anymore.
The error is on the repository side.
Another option is to define a repository that will download only a jar:
repositories {
mavenCentral() {
name = "Download only jar repo"
metadataSources { artifact() }
content {
// Use this repository only for org.eclipse.hudson:hudson-remoting
includeVersion("org.eclipse.hudson", "hudson-remoting", "3.0.3")
}
}
mavenCentral()
}
Also since pom is not downloaded you would have to add hudson-remoting dependencies by hand to build.gradle. But luckily for this particular case hudson-core already contains the only dependency commons-codec:commons-codec:1.4 that hudson-remoting needs, so this is not needed.
Note: the order of repositories is important, although in that case it will work either way. If you don't want to care about the order when using repositories with filter check exclusive content filtering.

Gradle artifactory plugin saying "Cannot cast object 'org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention'..."

Here's the configuration to get the artifactory plugin:
buildscript {
repositories {
mavenCentral()
maven { url 'http://jcenter.bintray.com' }
}
dependencies {
classpath group:'org.jfrog.buildinfo', name: 'build-info-extractor-gradle', version: '3.0.1'
}
}
apply plugin:'com.jfrog.artifactory'
apply plugin:'ivy-publish'
...some publish spec stuff...
I run gradle (2.3) and I get:
> Failed to apply plugin [id 'com.jfrog.artifactory']
> Cannot cast object 'org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention#6b6c7be4' with class 'org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention' to class 'org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention'
Certainly looks like a classpath issue, but I literally have this project and a sibling project using this same set of gradle/artifactory configurations and one works and the other does not. Both are part of the same top level project. Same JDK (1.8.0_20). Same Gradle. Same everything.
I'm baffled...
The problem was that when I added the various bits to the sibling project that meant I had two projects defining the buildscript {} section.
buildscript {
...
dependencies {
classpath group:'org.jfrog.buildinfo', name: 'build-info-extractor-gradle', version: '3.0.1'
}
}
Apparently that caused two different versions of the dependency to exist in the classpath, hence the error.
The solution was to move the buildscript bit into the master project so those dependencies are only defined once:
buildscript {
repositories {
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath group:'org.jfrog.buildinfo', name: 'build-info-extractor-gradle', version: '3.0.1'
}
}
Here's another potential cause. All of this looks to be a problem with rival classloaders defining the class. The full qualified classes include the loader. so, load A foo.bar is not loader B foo.bar and crossing that divide is a complex dance requiring interfaces and careful definition.
So, when using the Jenkins artifactory plugin to build your gradle project with the gradle artifactory plugin, you must add the usesPlugin or jenkins plugin will generate an init script which adds the gradle plugin on to a class loader.
def server = Artifactory.server "artifactory"
def rtGradle = Artifactory.newGradleBuild()
rtGradle.usesPlugin = true // Artifactory plugin already defined in build script
...
My problem was, desktop build OK, jenkins build shows this post's problem
I was getting a similar exception when building with Jenkins. For me the conflict was with Jenkin's version and the version in the Build script:
To address this the Artifactory section of the build has a flag you can check specifying that you want to use the version from the gradle file:
This fixed my issue. Hope it helps.
I had a similar problem. Gradle seems to try to reach across and do some checking or evaluation across siblings. I have a top level settings.gradle with 10 or so subprojects.
The fix for me was to put the buildscript block and dependencies at the top level build.gradle and put it in each of the individual subprojects build.gradle files where needed.
My guess as to the reason this works is that the plugin gets loaded in the parent which will be a parent classloader, then each child project inherits that classloader such that the declaration in the lower child script uses that classloaders class and CCE does not occur. The problem is they are the same class, but not assignable since the different classloaders per subproject if nothing is declared at the top. This was Gradle 2.4, and using IntelliJ 14.
In case it helps someone, I got the same error, but for a different reason.
I had the following in my build.gradle:
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:+"
}
At some point the artifactory plugin updated itself from version 3.x to version 4.x while building, because no specific version was specified for the dependency. After it updated I got the error (Could not find any convention object of type ArtifactoryPluginConvention).
I guess the problem was that the rest of the configuration in my build script doesn't work with the new plugin version. Setting the dependency to use version 3.x fixed the problem for me:
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.+"
}
While the currently accepted answer correctly identifies the cause of this issue, the proposed solution doesn't work when you still need to be able to build individual subprojects (because then of course they no longer have access to the buildscript defined repositories and dependencies). The solution that worked for me was to have identical buildscript blocks in each of my subprojects, that seemed to be the key. Any variations would cause the original error.
I got the same exception thrown by bamboo:
'org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention#18eb2827' with class 'org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention' to class 'org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention'
Since the bamboo Bamboo Artifactory Plugin by default looks for the gradle.propeties file in each sub-project module, it has to be provided there.
There is no need for publishing logic in the build.gradle file since the Bamboo Artifactory plugin will read the gradle.properties file for each module respectively, containing:
group=com.example
artifactId=your-project
version=1.0.0
The reason that I got the ArtifactoryPluginConvention exception thrown was that my configured build plan on Bamboo was misconfigured.
With misconfigured, the build ordered of the tasks was not correct. Have a look at your bamboo building tasks/preferably clone a Bamboo plan that is already working.

How do I get grails 2.4.3 to resolve dependencies in <project-dir>/lib?

I have a Grails 2.2.4 project which I'm upgrading to Grails 2.4.3. I've mostly navigated the dependency changes, I think, except that none of our local jars resolve anymore.
Specifically, our project depends on several jars in our lib directory--for example, newrelic-api-2.18.0.jar. Whenever I try to compile the project, I get this error:
| Error Resolve error obtaining dependencies: The following artifacts could not be resolved: newrelic:newrelic-api:jar:2.18.0 in grailsCentral (http://repo.grails.org/grails/plugins) (Use --stacktrace to see the full trace)
...which is completely fair as far as it goes: that jar really isn't in grailsCentral, it's in my-project/lib. So how do I get Grails to look for it there?
All of our local dependencies fail to resolve this way. All of our remote dependencies resolve correctly (at least, they did once I made a few small changes to e.g. the Hibernate version). I can get dependency resolution to succeed by commenting out all the local dependencies, but of course then compilation falls over a bit later with a bunch of NoClassDefFoundErrors.
When I switch back to 2.2.4, everything is fine again: the dependency is correct resolved and the app loads without a problem.
Here's the head of my buildConfig:
grails.servlet.version = "2.5"
grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
grails.project.target.level = 1.6
grails.project.source.level = 1.6
grails.project.dependency.resolver = "maven"
grails.project.dependency.resolution = {
cacheDir "target/ivy-cache"
inherits("global") { }
log "warn"
checksums true
legacyResolve true // whether to do a secondary resolve on plugin installation, not advised and here only for backwards compatibility
repositories {
inherits true
grailsPlugins()
grailsHome()
grailsCentral()
mavenLocal()
mavenCentral()
}
dependencies {
runtime 'newrelic:newrelic-api:2.18.0'
// ...various other deps, plugins, and whatnot...
}
}
What am I doing wrong? I don't see any discussion of this problem in the release notes, so it surely can't be an expected consequence of all the dependency changes.
This turns out to be a known issue, sort of; see the "No initial offline mode with Aether" section in the upgrade guide. The guide only mentions the jars that ship with grails, but all jars are affected and no jar is ever resolved locally unless it has first been resolved remotely. I guess if you have local dependencies, you're supposed to serve them from a Maven install of your own.
If for some reason you do not wish to manage your own Maven repo, the upgrade guide recommends that you use Ivy instead. DO NOT DO THIS. Ivy does not resolve transitive dependencies reliably in 2.4.3. If you can't maintain your own Maven repo, do not upgrade.

How to publish in order to resolve latest.integration with gradle?

What I have is a maven repository (nexus) to which maven has been publishing. In each artifact version folder in my artifact repository folder there are the standard maven artifacts: a maven-metadata.xml, a jar, and a pom.xml, etc.
Now I want to resolve these using gradle. In my gradle.build file if I list them as:
dependencies {
compile group: 'com.company', name: 'artifact', version: '1.0-SNAPSHOT'
}
Then they will resolve correctly. However, I want to use the version "latest.integration" so that I can automatically integrate the latest versions of my dependencies. When I do this though, gradle fails to resolve it.
I imagine that gradle is looking for some ivy specific files that maven is not publishing up to the repository in order to resolve latest.integration, but I am not sure. Should I go back and re-publish all of my upstream dependencies with gradle before trying to resolve down stream? It would seem that since gradle supports maven repositories under the repositories element that it should already know how to interpret "latest.integration" for that repository type.
This is my repositories section:
repositories {
mavenCentral()
maven { url "http://<server>/nexus/content/repositories/snapshots" }
}
Thank you for any help you can provide
latest.integration is an Ivy concept, and only works for Ivy repositories. In other words, both publication and consumption would have to happen in an Ivy-compatible manner. (Gradle is capable of this; not sure about Nexus.)
The obvious alternative is to use Maven snapshot dependencies. What do you hope to gain from using latest.integration?

Resources