Soon I will publish a new version of my library, which is composed of several modules. For this release, I’m now using Gradle 7, so I’m thinking about changing something that I feel needs to be fixed:
This is the library declaration (for example, the thread
module):
group: 'com.intellisrc', name: 'thread', version: '2.8.0'
when published, it generates a jar with the name: thread-2.8.0.jar
, which I would prefer to be: intellisrc-thread-2.8.0.jar
as it is more descriptive (other than that, it is working without issues).
To fix it, one option is to change the artifact-id
, so the declaration will become:
group: 'com.intellisrc', name: 'intellisrc-thread', version: '2.8.0'
But I would prefer not to change it as consumers would have to update it and it might be confusing.
I guess that if I can change the jar name and the publication files (pom.xml, module.json), it should work.
So far I was able to change the jar file name that it is generated inside build/libs/
using:
jar {
archiveBaseName.set("intellisrc-" + project.name)
}
and inside publishing
:
publishing {
publications {
mavenJava(MavenPublication) {
artifactId project.name
from components.java
pom {
...
archivesBaseName = "intellisrc-" + project.name
...
}
}
}
}
By default, the pom-default.xml
has no file names in it. I followed this recommendation, and added:
pom {
properties = [
"jar.finalName" : archivesBaseName + "-" + project.version
]
}
which adds in pom-default.xml
file:
<properties>
<jar.finalName>com.intellisrc.core-2.8.0-SNAPSHOT</jar.finalName>
</properties>
However in module.json
the name hasn’t changed:
...
"files": [
{
"name": "thread-2.8.0.jar",
"url": "thread-2.8.0.jar",
"size": 92799,
...
Is there a way to change those values in module.json
from gradle? I can think of decoding the json file and replace its values, but I hope there is a better way to do it.
When I execute gradle publishToMavenLocal
, the jars installed on .m2/repository/com/intellisrc/
haven’t changed: it is still thread-2.8.0.jar
(despite being correctly in build/libs
), I’m not sure why.
How can I rename the jar without changing the artifact-id so it works with publish
and publishToMavenLocal
?
This is the complete build.gradle
:
plugins {
id 'groovy'
id 'java-library'
id 'maven-publish'
id 'signing'
}
def currentVersion = "2.8.0-SNAPSHOT"
allprojects {
group = groupName
version = currentVersion
repositories {
mavenLocal()
mavenCentral()
}
}
/**
* Returns project description
* @param name
* @return
*/
static String getProjectDescription(String name) {
String desc = ""
switch (name) {
case "core":
desc = "Basic functionality that is usually needed " +
"in any project. For example, configuration, " +
"logging, executing commands, controlling " +
"services and displaying colors in console."
break
case "etc":
desc = "Extra functionality which is usually very " +
"useful in any project. For example, monitoring " +
"Hardware, compressing or decompressing data, " +
"store data in memory cache, manage system " +
"configuration in a multithreading safe environment " +
"(using Redis as default), simple operations with " +
"bytes, etc."
break
case "db":
desc = "Manage databases, such as MySQL, SQLite, " +
"BerkeleyDB, Postgresql. Create, store and " +
"perform CRUD operations to data without having " +
"to use SQL (a light-weight implementation as " +
"alternative to Hibernate)."
break
case "net":
desc = "Classes related to networking. For example, " +
"sending emails through SMTP, connecting or " +
"creating TCP/UDP servers, getting network " +
"interfaces and perform netmask calculations, etc."
break
case "serial":
desc = "Manage serial communication easily. It uses " +
"JSSC library on the background."
break
case "web":
desc = "Create restful HTTP (GET, POST, PUT, DELETE, etc) " +
"or WebSocket application services. Manage JSON " +
"data from and to the server easily. It is build " +
"on top of Spark-Java Web Framework, so it is " +
"very flexible and powerful, but designed to be " +
"elegant and easier to use."
break
case "crypt":
desc = "Offers methods to encode, decode, hash and encrypt " +
"information. It is built using the BountyCastle " +
"library and simplifying its usage without reducing " +
"its safety."
break
case "thread":
desc = "Manage Tasks (Threads) with priority and watches " +
"its performance. You can create parallel processes " +
"easily, processes which are executed in an interval, " +
"as a service or after a specified amount of time. " +
"This module is very useful to help you to identify " +
"bottlenecks and to manage your main threads in a " +
"single place."
break
case "term":
desc = "Anything related to terminal is in this module " +
"(except AnsiColor, which is in core). It uses JLine " +
"to help you create interactive terminal (console) " +
"applications easily. It also contains some tools " +
"to display progress with colors."
break
case "img":
desc = "Classes for using Images (BufferedImage, File, FrameShot) " +
"and non-opencv related code, trying to keep dependencies " +
"to a minimum. It also includes common geometric operations."
break
case "cv":
desc = "Classes for Computer Vision (extension to OpenCV). " +
"Convert image formats, crop, rotate images or draw " +
"objects on top of them. It simplifies grabbing images " +
"from any video source."
break
}
return desc
}
subprojects {
apply plugin: 'groovy'
apply plugin: 'java-library'
apply plugin: 'maven-publish'
apply plugin: 'signing'
dependencies {
//def groovyVer = "2.5.14"
def groovyVer = "3.0.7"
def groovyExt = "3.0.8.7"
def spock = "2.0-groovy-3.0"
def junit = "4.13.2"
boolean isDev = currentVersion.contains("SNAPSHOT")
def deps = ["org.codehaus.groovy:groovy-all:${groovyVer}"]
if(isDev) {
deps.each { api it }
} else {
deps.each { compileOnly it } //Link it so we can choose version
}
// Always include groovy-extend and expose it to consumers:
api "com.intellisrc:groovy-extend:${groovyExt}"
testImplementation "org.spockframework:spock-core:${spock}"
testImplementation "junit:junit:${junit}"
}
jar {
archiveBaseName.set("intellisrc-" + archiveBaseName.get())
}
java {
withSourcesJar()
withJavadocJar()
}
// Used to publish to MavenLocal
publishing {
repositories {
maven {
def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2"
def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots"
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
credentials {
username = ossrhUsername
password = ossrhPassword
}
}
}
publications {
mavenJava(MavenPublication) {
artifactId project.name
from components.java
pom {
name = projectName + " : " + project.name.capitalize() + " Module"
description = getProjectDescription(project.name) ?: projectDescription
url = projectURL
inceptionYear = projectSince
archivesBaseName = "intellisrc-" + project.name
properties = [
"jar.finalName" : archivesBaseName + "-" + project.version
]
licenses {
license {
name = 'GNU General Public License v3.0'
url = 'https://www.gnu.org/licenses/gpl-3.0.en.html'
distribution = 'repo'
}
}
developers {
developer {
id = authorId
name = authorName
email = authorEmail
}
}
scm {
url = projectURL
connection = "scm:git:${projectURL}.git"
developerConnection = "scm:git:${projectDevURL}"
}
}
}
}
}
signing {
required {
!version.endsWith("SNAPSHOT")
}
sign publishing.publications.mavenJava
}
tasks.named('test') {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}
}
3
Answers
This cannot be done.
The name of a JAR in the Maven local repository is always
artifactId-version.jar
(or, if you have a classifier,artifactId-version-classifier.jar
). This is a fixed Maven structure.This is 100% a bug. It’s not just a "nice to have", this bug’s presence breaks the ability for consumers of libraries that use modules with common names (i.e. "core") to include the same named JARs, if their dependencies happen to have the same version number.
I ran into the same issue and filed a tracking bug. Hopefully it will be resolved in an upcoming version of Gradle.
You can add module property with desired name(i.e module = ‘desired-name’) to publish sub module jars.