iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🐘

Storing Library Dependencies as In-Project Files in Maven Repository Format (Preparing for JCenter Shutdown)

に公開

When it comes to Maven repositories, you likely use repositories published on the internet such as JCenter or Maven Central. However, you can also create a directory within your project in the Maven repository format and refer to it.

If the library is something used across various projects, I recommend publishing it to public Maven repositories on the internet, or setting up an internal Repository Manager (such as Sonatype Nexus or JFrog Artifactory) if it cannot be disclosed outside the company. However,

  • It is only used in a few projects
  • You want to do it without much effort

In such cases, I think creating and referencing a directory in the Maven repository format within the project is one possible option.

Also, I believe this is one of the solutions for the problem of what to do with libraries that are only published on JCenter, in preparation for the JCenter shutdown.

Directory structure of a Maven repository

The directory structure of a Maven repository is as follows.
This structure is the same for URLs.

  • One folder level for each . in the Group ID
    • Example: com.github.onozaty -> becomes three levels of folders: com/github/onozaty
  • Under that, the Artifact ID folder
  • Further under that, the Version folder
  • Under the Version folder, a group of files like the following
    (There are also signature files and files representing hash values, but they are omitted for now)
    • {Artifact ID}-{Version}.pom *Required
    • {Artifact ID}-{Version}.jar
    • {Artifact ID}-{Version}-sources.jar
    • {Artifact ID}-{Version}-javadoc.jar

For example, in the following case:

  • Group ID: com.github.onozaty
  • Artifact ID: postgresql-copy-helper
  • Version: 1.0.0

The folder structure would be as follows:

  • com
    • github
      • onozaty
        • postgresql-copy-helper
          • 1.0.0
            • postgresql-copy-helper-1.0.0.pom
            • postgresql-copy-helper-1.0.0.jar
            • postgresql-copy-helper-1.0.0-sources.jar
            • postgresql-copy-helper-1.0.0-javadoc.jar

The pom file is mandatory and contains information about the library plus dependency information.
By following this dependency information, it will fetch further required libraries.

How to specify the repository URL

Once you have a directory in the Maven repository format within your project, you set it up to be referenced. That said, it's as simple as specifying the directory path instead of a URL for the Maven repository.

Below is an example using Gradle as the build tool, but you can do something similar with Maven.

Add the following to your build.gradle. Two patterns are shown, but both point to the same directory.

repositories {
    maven {
        url "file://${projectDir}/local-repo"
    }
}
repositories {
    maven {
        url "./local-repo"
    }
}

You can also trace back to the parent directory using relative paths, so you can prepare something shared across multiple projects in a folder at the same level as each project.

repositories {
    maven {
        url "./../local-repo"
    }
}

Placing Libraries with maven-publish

If you want to save your own library in the Maven repository format, use the maven-publish plugin.

The following is an example description. (Confirmed with Gradle 6)
The Artifact ID will be the project name in Gradle as it is.

plugins {
    id 'java'
    id 'maven-publish'
}

group = 'com.github.onozaty'
version = '1.0.0'

java {
    withJavadocJar()
    withSourcesJar()
}

publishing {
    publications {
        maven(MavenPublication) {
            from components.java
        }
    }
    repositories {
        maven {
            url './../local-repo' // Specify the directory to publish to
        }
    }
}

The publish task places various files in the designated folder in the Maven repository format.

Preparing for the JCenter Shutdown

The motivation for writing this article was the announcement of the JCenter shutdown.

Libraries that are being maintained will likely move to Maven Central or other repositories. However, there is a possibility that libraries that are no longer maintained will not be migrated and will disappear from the Maven repositories on the internet.

Before that happens, by placing libraries that are only published on JCenter into a Maven repository within your project, you can continue to use them even after JCenter is shut down.

I created a tool called mvndl to download libraries from JCenter.

With mvndl, you can download libraries from JCenter to a local directory in the Maven repository format.

$ ./mvndl -r jcenter -g com.github.onozaty -a postgresql-copy-helper -v 1.0.0 -d local-repo
https://jcenter.bintray.com/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0.pom -> saved
https://jcenter.bintray.com/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0.jar -> saved
https://jcenter.bintray.com/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0-sources.jar -> saved
https://jcenter.bintray.com/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0-javadoc.jar -> saved

$ find local-repo/ -type f
local-repo/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0-javadoc.jar
local-repo/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0-sources.jar
local-repo/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0.jar
local-repo/com/github/onozaty/postgresql-copy-helper/1.0.0/postgresql-copy-helper-1.0.0.pom

There is also a way to pick them up from the Maven local cache (~/.m2), but I created this command because reproducing the directory structure manually is tedious.

I am not sure if any libraries published only on JCenter will remain in the projects I am involved in, but if they do, I plan to handle it using this tool and the method described here.

Discussion