How to properly fork a maven project? - maven

I'm trying to fork a discontinued maven library that is already in the main repository.
What are good guidelines to follow when doing so?
Should the groupId/artifactId be changed so that it doesn't clash with the library that's already in the maven repository?
This library will be a dependency to a project that will also be available publicly(in the maven repo) so this library should also be there.
The modifications add improvements and some changes on how the library works, so I would like it to be separate from the old versions.

Sonatype recommends you change the groupId when you fork a project.
B2) upload them under your the forked project
groupId (presumably one you own and appropriate for the fork)

I assume you are forking the other project for internal use? Then I would keep the original groupId/artifactId but add a postfix to the version. If the upstream version is 1.0.0 your custom version would be 1.0.0-custom.
If you create a public fork then you basically have to use a new project name and so a new groupId/artifactId.

Related

Keeping jar version numbers in sync between JitPack and other repositories

I maintain a few Java library projects on GitLab, which I currently build with a GitLab CI workflow and deploy to a GitLab Maven repository. Now I would like to make them available via JitPack while keeping the GitLab Maven repo for a while.
GitLab’s Maven repo, like most of the others out there, uses the contents of the <version> tag in pom.xml for versioning. JitPack, on the other hand, needs a Git ref to work with (a branch name, a tag or a plain hash). I am looking for a way to use the same versioning regardless of the repo, so that version FOO will fetch a jar based on the same code, regardless of whether it is taken from GitLab or JitPack.
For a released, stable version that could be solved by tagging each release with its version number. That is, when I release version 3.7.0, I would ensure the <version> tag in my pom.xml reads 3.7.0, and tag the commit with 3.7.0 as well. I would need to enforce a match between the two (e.g. by teaching CI to bar{k|f} upon detecting a discrepancy), but with some homework, both repos would carry the same version of my code under the same version number.
Things get tricky when it comes to unstable versions. If I am working on the upcoming 3.7.2 release and would already like to make it available for testing, I understand common practice is to set the version tag to 3.7.2-SNAPSHOT, telling everyone that this is not a stable version. The GitLab Maven repo would serve the jar under that version.
For JitPack, versions ending in -SNAPSHOT indicate that the code could have changed since the last build and the jar should be rebuilt from source. A version named 3.7.2-SNAPSHOT would cause JitPack to look for a ref named 3.7.2 (tag or branch) and build it from scratch.
So I would have to ensure that the version name of the upcoming version resolves to the latest commit for the upcoming version. I could do that by developing the upcoming version in a branch named like the version, but that would presumably result in a naming conflict as I release it, as I would then introduce a tag with the same identifier.
Is there a general recommendation for addressing this, i.e. serving unstable versions of a jar via JitPack and a conventional Maven repo under the same version number?

After making a Gradle groovy jar library how to make it re-usable for multiple local projects?

Here I read about how to make a Groovy library .jar ... i.e. pretty much the same as making a Groovy (standalone) project. But I'm not clear what you do then with the resultant .jar...
Say I have two Eclipse "proper"/"standalone" projects (I'm using Groovy for everything) and I want them to share a third Gradle library project of mine as a dependency, which is merely a library of classes... how are my standalone projects expected to find the latest .jar version of the library which they're both using...?
My expectation would be that somehow these versions of the library .jar would have to under GRADLE_USER_HOME (i.e. same location as all other dependency .jars).
Then I would assume that in the build.gradle of both standalone projects you'd have a line like
compile 'mylibrary:mylibrarymodule:3.+'
... of course the first part of these compile directives normally involves a "domain name in reverse" ... and this is normally used by a repository like Maven. How does it work with something which doesn't need to be published?
NB at the time of writing I don't have a Maven account as such and have no idea whether "publication" for re-use of a local common library project like this is essential or not.
Naturally, when I distribute versions of my standalone projects they will need to be packaged up with the library .jar in question.
A link to a how-to for a case like this would be more than welcome: I haven't found it under gradle.org.
If you are developing by yourself, you can use maven-publish plugin to publish your artifacts to local maven repository(you don't have to install maven for this) and on your dependent project you can simply say use mavenLocal repository for dependencies.
If you are on a company, I suggest installing a repository manager and deploy your artifacts to this repository so others can use. You can use their respective plugins to deploy easily. (Gradle Artifactory Plugin, Gradle Nexus Plugin, these are just deployment plugins, you have to setup respository manager to. There are other repository management tools also.) Doing the above process from CI server is the preferred way.
To use latest version of a dependency, you can use Gradle Versions Plugin. If the versioning happen often, using snapshot versions also a possibility.

Best practice to change version of dependencies in nexus

Consider a project that is used in other projects, and this project has version 1.0 and is present in the Nexus.
After that, some changes are done in this project.
Now there are two solutions:
Increment the version of the project to 2.0, and delete the version 1.0 from Nexus. When the developers try to get the dependencies from the Nexus with version 1.0 they will get an error that this version does not exist and need to change the version to 2.0.
Change the functionalities of this project and inform the crew that some changes are done, but this is not the practice at all.
Is there any functionality in Maven and Nexus to simplify this task and make this all happen in the backend so the developers can't do anything, or is this not possible?
If you have an old version of an artifact that must not be used anymore because it has some dangerous bug, or it does not work with the new database structure or something like this, it may be advisable to move it to some non-public Nexus repository (and also delete it from the local repository of the build server), so that nobody can use it for release builds (people can use it for local builds, but this is usually not dangerous).
If you want to manage standard versions throughout your company, it is a good idea to have a parent pom or some boms which collect versions in a <dependenyManagment> section and can be included by the developers. This way, you only need to inform them to change one version number (namely the one of the parent pom or bom) instead of many.
Still, you are left with the problem that people do not read company newsletters. I know the problem that many developers of jars compile and test their source code against very old versions of their dependencies while the war/ear (that includes the jar) uses new versions.

Upload newer version of strangers project to central maven repo

JBox2d is at version 2.3.1-SNAPSHOT ..
https://github.com/jbox2d/jbox2d/blob/master/jbox2d-library/pom.xml
However the latest version of the library at Maven repository is 2.2.1.1 ..
http://mvnrepository.com/artifact/org.jbox2d/jbox2d-library
Is there a way that I can upload this newer version of JBox2d to the central repo for everyone's use?
In short, no. Without the current maintainer's permission you can't upload a new artifact with the same groupId/artifactId. To quote from the Guide to uploading artifacts to the Central Repository FAQ:
I have a patched version of the foo project developed at foo.com, what groupId should I use?
When you patch / modify a third party project, that patched version becomes your project and therefore should be distributed under a groupId you control as any project you would have developed, never under com.foo. See above considerations about groupId.
Either pick a new groupId, for what is effectively your fork of the project, or collaborate with the current maintainers to get the newer version into Central with their permission.

How to depend on a local library with maven

I have a project contains two sub projects:
A. a common library for external api
B. a program depends on above library
They are inside same directory. How I made B refer to A with maven?
Normally you will always share through a maven repository. That is mavens way to ensure a consistent and correct solution and a solution shareable by all developers.
You should search for a public maven repository with project A (e.g. http://search.maven.org or http://mvnrepository.com) and include in your pom
If it does not exist in public (is proprietary in someway or other), consider using an enterprise-wide maven repository such as nexus or artifactory to push to repositories.
Finally, some developers resort to either installing a mvn-local file if you are ever only going to work on an explicit workstation.
If you still prefer a filebased acces, it is possible to define a maven file repository and reference it in your pom. E.g. Heroku use this for bundling extra dependencies into their system.
Declare A as dependency in B's pom.xml. Make sure A has valid pom.xml and is deployed to your repository (local/nexus). We do that all the time. Take care to assign SNAPSHOT version if you always want latest to be pulled from repository.

Resources