How are JCenter and Maven Central coordinates different from one another? - java

I am trying to include LazyBones, which is stored here in Bintray/JCenter in my Gradle project as a compile-time dependency, like so:
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
compile 'com.typesafe.akka:akka-actor_2.10:2.3.12'
compile 'org.codemonkey.simplejavamail:simple-java-mail:2.3'
compile 'pledbrook/lazybones-templates:lazybones:0.8.1' // <-- here
}
I have tried many other combination/permutations of group/artifact names for the 0.8.1 version, but nothing is working/resolving. This is the first time I’ve ever (intentionally) tried depending on a compile binary that is only stored in JCenter, and not available via Maven Central. So I ask: what’s the difference between Maven Central and JCenter coordinates, and what do I need to do so that Gradle can “find” the LazyBones JAR living in JCenter?

The thing with this Lazybones artifact is that it's not a maven artifact. It's a zip, not in maven layout, and from what I know about Lazybones it's not supposed to be used directly as a dependency from Gradle/Maven.
That's why you can't use the normal coordinates.

Related

Is there a Gradle equivalent to the publishToMavenLocal task of the maven-publish Gradle plugin [duplicate]

I know that I can use the maven plugin coupled with mavenLocal() to install an artifact and use it locally.
However investigating this a bit further, I notice that this means the artifacts are installed to Mavens's standard ~/.m2, but at the same time Gradle's own cache lives under ~/.gradle/caches in a different format.
This seems wasteful to me, a) working with two local caches, and b) having to add mavenLocal() to all projects. I was wondering if there is a way to publish an artifact to Gradle's ~/.gradle/caches ?
Note that the local Maven repository is not (really) a cache, and that the Gradle cache is not a repository. Gradle uses its cache only to cache remote artifacts, it should not copy artifacts retrieved from local Maven repositories there. In turn, you cannot publish artifacts to the Gradle cache.
So the approach to publish to and use mavenLocal() should not be as wasteful as you think. Also, you do not have to add mavenLocal() to all projects of a multi-project separately. You can simply use something like allprojects { repositories { mavenLocal() } } in your root project. Or if you want mavenLocal() in all your independent Gradle projects you could even try adding it to ~/.gradle/init.gradle.
Here is an example with code.
As it's not possible to publish into Gradle. The workaround is to publish into the maven and use it in Gradle.
Step 1 publish the code to local maven repository /users/jay/.m2/repository/
Step2 - Use the local maven repo code in another project.
Step #1 (Publish to local maven repo)
apply plugin: 'maven-publish'
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
Step #2 (Use the local maven repo in your gradle project)
repositories {
// ..... Other repositories
mavenLocal()
}
dependencies {
compile 'com.jai:myapp:1.0.0'
}

gradle can't resolve nexus dependency

I have a dependency I'd like to include from a local nexus. I've seen several related problems that all say to do something like
apply plugin: "java"
apply plugin: "maven"
repositories {
maven {
url "http://my.url.com/"
}
}
dependencies {
compile "name:id:version"
}
I can access the nexus fine via web but when I try the above, I end up with a error message
Could not resolve: name:id:version
Any help would be greatly appreciated.
I found my problem. There were transitive dependencies I didn't catch as I was initially building from Eclipse without the --stacktrace option. I modified the build script such that
compile("name:id:version") {
exclude group: "another-name", module: "its-module"
// other dependencies to exclude ...
}
If by local repository you mean your local computer repository, then to ask Gradle to lookup dependencies from the local maven repository you should explicitly tell him to do so like this:
repositories {
mavenLocal()
}
Gradle is not like maven and is not using the local repository of the maven to cache downloaded artifacts. From the Gradle points of view, the local maven repository is also like other repositories.

Gradle could not find retrofit dependencies

I need some retrofit2 dependencies for my java project.
In build.gradle additional repositories are declared:
repositories
{
jcenter()
mavenCentral()
mavenLocal()
}
In dependencies section I declared:
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-jackson:2.1.0'
So Gradle could not find them.
I used project-report plugin to analyze dependency tree. I got next report:
Interesting thing that before I used 2.0.2 versions for retrofit libraries and Gradle found them.
Any help will be appreciated.
Gradle version 2.12
If using IntelliJ you can include plugin idea or include plugin eclipse, which gives you an option to run gradle idea or gradle eclipseClasspath tasks and refresh the project with updated/freshly added dependencies.
IDE's are not yet ideal supporting gradle.

Make Gradle use Maven local repository for downloading artifacts

I know I can configure Gradle to use local Maven repository
repositories {
mavenLocal()
mavenCentral()
}
Can I configure Gradle to download into Local (maven) repository? (So that Maven would also be able to use those jars)
ref Gradle configuration to use maven local repository
A solution was given in the gradle forums:
https://discuss.gradle.org/t/need-a-gradle-task-to-copy-all-dependencies-to-a-local-maven-repo/13397/2
using this gradle plugin: https://github.com/ysb33r/ivypot-gradle-plugin
you can call a new tasg
gradle syncRemoteRepositories
which will download all dependencies to a local Ivy repository (which is the same library Maven uses). The folder you point to with
syncRemoteRepositories {
repoRoot '/path/to/repo'
}
will contain the dependencies. I would suggest first trying out with a different local path than your M2_HOME, because I saw some warning about the Ivy repository structure having changed between Maven versions.
It should be as simple as
apply plugin: 'maven'
apply plugin: 'java'
dependencies {
mavenLocal()
}
And
gradle install
More info here

Gradle won't resolve dependency (Maven will)

My project has dependencies configured through gradle. I would like to add the following dependency:
compile group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', version: '2.3.1'
Which can be found in the following repository (which I have added to my build.gradle):
maven {
url "http://maven.restlet.org"
}
However when I do that I get the following error:
Could not find org.restlet.jse:org.restlet.lib.swagger-models:1.5.0-SNAPSHOT.
http://maven.restlet.org/org/restlet/jse/org.restlet.lib.swagger-models/1.5.0-SNAPSHOT/maven-metadata.xml
http://maven.restlet.org/org/restlet/jse/org.restlet.lib.swagger-models/1.5.0-SNAPSHOT/org.restlet.lib.swagger-models-1.5.0-null-null.pom
http://maven.restlet.org/org/restlet/jse/org.restlet.lib.swagger-models/1.5.0-SNAPSHOT/org.restlet.lib.swagger-models-1.5.0-null-null.jar
Required by: org.restlet.jse:org.restlet.ext.apispark:2.3.1
I can see that the jar is in fact in the repository however Gradle is not looking for it in the right location for reasons unknown to me. Why is it not using the version in the filename but rather 1.5.0-null-null.
I have made a made a Maven project with the same dependency defined in the pom.xml which works.
Link to working pom.xml that has same dependency
How can this issue be resolved? I'm at this point also interesting in more manual solutions :) Thank you.
Diagnosis
It seems to be related to snapshot "uniqueness". For information on Maven repositories, snapshots artifacts can be deployed "unique" or "non-unique".
Unique snapshots: Each time you deploy a snapshot, it is tagged with a timestamp and a buildNumber, these timestamp and buildNumber are written in the maven-metadata.xml file and they are appended to its name that ends up like: artifactName-version-timestamp-buildNumber.jar.
Non-unique snapshots: Each time you deploy a snapshot it overwrites the previous version, his name ends up like: artifactName-version.jar.
It is recommended to use unique snapshot as one can refer precisely to one version of the artifact if needed.
The problem is that "http://maven.restlet.org" seems to use non-unique snapshots and sadly, gradle seems to have problems to deal with non-unique snapshots: https://issues.gradle.org/browse/GRADLE-3164.
If you look at http://maven.restlet.com/org/restlet/jse/org.restlet.lib.org.restlet.lib.swagger-models/1.5.0-SNAPSHOT/maven-metadata.xml you can clearly see null in timestamp and buildNumber tags:
<metadata>
[...]
<versioning>
<snapshot>
<timestamp>null</timestamp>
<buildNumber>null</buildNumber>
</snapshot>
<lastUpdated>null</lastUpdated>
</versioning>
</metadata>
I think that's where the "null-null" comes from.
Solution 1 - flatDir
To deal with it you can manually download the artifact, put it in a directory, for example "lib" and create a flatDir repository:
repositories {
[...]
flatDir {
dirs 'lib'
}
[...]
}
It's not an ideal solution, but it works.
Solution 2 - jcenter repository
Suggested by Opal
Add the jcenter repository that contains your missing dependency and that Gradle handles well.
Since Gradle 1.7 you can simply define it with:
repositories {
[...]
jcenter()
[...]
}
It seems that you need other repositories to download all the dependencies. Probably maven handle this transparently. The following script downloads all dependencies successfully when cp task is run:
apply plugin: 'java'
configurations {
lol
}
repositories {
jcenter()
mavenCentral()
maven {
url "http://maven.restlet.org"
}
maven {
url "https://repository.mulesoft.org/nexus/content/repositories/public/"
}
}
dependencies {
lol group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', version: '2.3.1'
}
task cp(type: Copy) {
from configurations.lol
into 'deps'
}

Categories