Maven (Java)
  • 27 Oct 2023
  • 8 Minutes to read
  • Dark
    Light
  • PDF

Maven (Java)

  • Dark
    Light
  • PDF

Article Summary

A Maven feed in ProGet acts as a "maven2-compatible" artifact repository. Clients such as Maven, Gradle, and SBT can publish and consume artifacts in a Maven feed, and you can browse artifacts using the ProGet web application.

Prerequisite Configuration

Maven Client Configuration

We recommend using newer versions of the Maven client; see Maven Releases History to learn which versions are considered end of life.

To install packages and plugins from ProGet, you need to modify Maven's settings.xml file. This is the Maven configuration file, which is described in detail in the Maven's Settings Reference Documentation.

If you are not familiar with how to edit this file, you can follow the steps below. For simplicity, these steps assume that you have a single feed that contains all the public and private artifacts that you want to use.

1. Locate your Settings.xml File

The settings.xml file may exist in two different places:

  • «maven-install-directory»/conf/settings.xml - global-level settings for all users on the machine
  • «user-home-directory»/.m2/settings.xml - user-level settings that can override any global settings

You can find your «maven-install-directory» by running mvn --version, and the «user-home-directory» is ~/ on Linux or %UserProfile% on Windows. If both files are available, we generally recommend editing the global settings file,

If you can't find a settings.xml file in either location, you can create one using the template below.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository/>
  <interactiveMode/>
  <offline/>
  <pluginGroups/>
  <servers/>
  <mirrors/>
  <proxies/>
  <profiles/>
  <activeProfiles/>
</settings>

2. Add a ProGet profile

Profiles are used by Maven to store repository settings and we recommend adding an active profile called ProGet. To do this, you need to edit the profiles and activeProfiles nodes as follows:

<profiles>
    <profile>
        <id>ProGet</id>
        <repositories />
        <pluginRepositories />
    </profile>
</profiles>
<activeProfiles>
    <activeProfile>ProGet</activeProfile>
</activeProfiles>

3. Configure ProGet Feed as Repositories

Maven uses two types of repositories:

  • normal repositories, which are used for libraries and other artifacts
  • plugin repositories, which are used for the many plugins that Maven requires

When searching for content (i.e. ordinary artifacts or plugins), Maven will look in the settings.xml files for a repository named central. If this isn't found, the default repository on maven.org will be used.

Therefore, we recommend adding a central repository to your settings.xml by editing the repositories and pluginRepositories nodes as follows:

<repositories>
    <repository>
        <id>central</id>
        <url>«maven-feed-api-endpoint»</url>
        <snapshots><enabled>true</enabled></snapshots>
        <releases><enabled>true</enabled></releases>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>central</id>
        <url>«maven-feed-api-endpoint»</url>
        <snapshots><enabled>true</enabled></snapshots>
        <releases><enabled>true</enabled></releases>
    </pluginRepository>
</pluginRepositories>

The «maven-feed-api-endpoint» can be found on the browse feed page in ProGet.

4. Add a Repository Mirror

A POM file can reference a Maven repository directly, bypassing your settings.xml configuration. To prevent this, we recommend also configuring a mirror to ensure that all artifact requests go to your feed.

<mirrors>
	<mirror>
	  <id>proget</id>
	  <name>ProGet</name>
	  <url>«maven-feed-api-endpoint»</url>
	  <mirrorOf>*</mirrorOf>
	</mirror>
</mirrors>

If you want to mirror a specific repository, you can change the mirrorOf to be the ID of a repository.

5. (Optional) Authenticate to Your Feeds

If you've configured a restricted feed, you must configure Maven to authenticate with ProGet.

To do this, we recommend that you first create an API key that has the appropriate permissions for your Maven feed (generally, read and publish). Once you have that, you can edit the servers node of your settings.xml file as follows:

<servers>
    <server>
        <id>central</id>
        <username>api</username>
        <password>«api-key»</password>
    </server>
</servers>

Example: settings.xml

To put it all together, here is an example settings.xml that will push/pull artifacts and plugins from http://progetsv:8624/maven2/my-maven/ using the api key apiKey12345.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"          
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <servers>
        <server>
            <id>central</id>
            <username>api</username>
            <password>apiKey12345</password>
        </server>
    </servers>
    <profiles>
        <profile>
            <id>ProGet</id>
            <repositories>
                <repository>
                    <id>central</id>
                    <url>http://progetsv:8624/maven2/my-maven</url>
                    <snapshots><enabled>true</enabled></snapshots>
                    <releases><enabled>true</enabled></releases>
                </repository>
            </repositories>
            <pluginRepositories>
                <pluginRepository>
                    <id>central</id>
                    <url>http://progetsv:8624/maven2/my-maven</url>
                    <snapshots><enabled>true</enabled></snapshots>
                    <releases><enabled>true</enabled></releases>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>ProGet</activeProfile>
    </activeProfiles>
    <mirrors>
        <mirror>
            <id>proget</id>
            <name>ProGet</name>
            <url>«maven-feed-api-endpoint»</url>
            <mirrorOf>*</mirrorOf>
        </mirror>
    </mirrors>    
</settings>

Installing Packages

To add a Maven package to a Maven project, you need to add a dependency to your project's pom.xml.

<dependency>
   <groupId>joda-time</groupId>
   <artifactId>joda-time</artifactId>
   <version>2.2</version>
</dependency>

These can then be installed using mvn install.

Creating Packages

Maven inherently includes a lifecycle for creating a package. You can create a package by running the following commands:

mvn install
mvn compile
mvn package

Publishing Packages

Publishing Maven packages requires a distribution repository to be added to your pom.xml as follows:

<distributionManagement>
    <repository>
        <id>central</id>
        <name>ProGet</name>   
        <url>«maven-feed-api-endpoint»</url>
        <layout>default</layout>
    </repository>
</distributionManagement>

This distribution repository will use the authentication credentials specified in your settings.xml, under the servers node. In the case above, this will use the central server.

To publish a Maven package and deploy it to ProGet, just run the mvn deploy operation.

Best Practice: Use Properties for Repository URL

Instead of specifying the repository URL directly, we recommend using a property. This not only allows you to override the setting when you run the mvn deploy command, but also allows you to specify the property in the settings.xml file instead of in each project.

To do this, add (or edit) the properties node under the ProGet profile in your settings.xml file:

<profiles>
    <profile>
        <id>ProGet</id>
        <properties>
            <distribution-repository>«maven-feed-api-endpoint»</distribution-repository>
        </properties>
        ... snip ...

You can then use a property in your POM file, like this:

<distributionManagement>
    <repository>
        <id>central</id>
        <name>ProGet</name>   
        <url>${distribution-repository}</url>
        <layout>default</layout>
    </repository>
</distributionManagement>

Snapshot versions

Snapshot versions allow you work with unstable (i.e. pre-release) versions of a library. This is common when you're developing an application—and libraries that the application consumes—at the same time.

Using Snapshot Dependencies

You can use a snapshot version of a dependency by adding -SNAPSHOT to a dependency's version number in your POM file. For example:

<dependency>
   <groupId>corp.kramerica</groupId>
   <artifactId>common-library</artifactId>
   <version>2.2-SNAPSHOT</version>
</dependency>

When specified in a dependency, -SNAPSHOT acts as a wildcard. When you run mvn install, Maven will search the repository for the latest matching version starting with 2.2. In the example above, this means that 2.2-SNAPSHOT could be 2.2.0, 2.2.1, 2.2.4-alpha1, etc.

By convention, any version number containing a - is considered "unstable".

Publishing Snapshot Dependencies

To publish (deploy) an unstable snapshot version of a library, simply append -SNAPSHOT to the version number in your POM file. For example:

<project>
  ... snip ...
   <groupId>corp.kramerica</groupId>
   <artifactId>common-library</artifactId>
   <version>2.2-SNAPSHOT</version>
  ... snip ...   
</project>

After doing this, when you run the mvn deploy command, Maven will simply replace the -SNAPSHOT with a timestamp of when it was published. For example, if your POM file specified 2.2-SNAPSHOT, then Maven will deploy something like 2.2-20230308.201920-3 to the repository instead.

Don't Use deploy:deploy-file with -SNAPSHOT Artifacts

Maven has a deploy:deploy "mojo" that publishes (deploys) a file directly to a repository. You can specify a version number with this command; if you do, Maven will not replace it with a timestamp. This leads to unpredictable behavior in both Maven and ProGet.

Use Standardized Versioning with SNAPSHOT Versions

Maven uses a 5-part scheme for version numbers: major, minor, incremental, build, and qualifier. This is "documented" in the Maven source code, and explained in detail in an archived Codehaus article.

If you don't use "standard" versions (for example, if you were to use a 6-part version number), then both Maven and ProGet will behave in unpredictable ways.

ProGet and Snapshot Versions

Although Maven has built-in support for separate snapshot and non-snapshot repositories, we recommend using a single ProGet feed for both artifacts. This makes things easier and you can automatically configure retention rules to clean up old, unstable versions.

Note that when browsing a Maven feed of snapshot versions, you shouldn't see a version that ends in -SNAPSHOT. Instead, you'll see artifacts with timestamps instead of the string -SNAPSHOT. However, when a snapshot version is used for a dependency, Maven looks for files named -SNAPSHOT. To handle these requests, ProGet will simply return the latest version of the artifact.

Bulk Importing Using a Drop Path

ProGet 2023.21 and Above

ProGet 2023.21 adds Drop Path support to Maven Feeds. Maven packages are made up of a POM file and one or more artifacts, like jar, war, ear, xml, etc... When adding Maven packages to a drop folder, each package should be its own folder that contains the POM file and all related artifacts. When Maven packages are imported via a drop path, ProGet will first find all files that end with .pom and then will add any artifacts in the same folder as that POM file.

SNAPSHOTS are not supported

Due to how Maven handles SNAPSHOT packages, packages using a SNAPSHOT version cannot be imported using a drop path.

ProGet 2023.20 and Below

ProGet 2023.20 and below does not currently support import drop paths for Maven, but we are considering adding this in a future release. Please consider joining the existing discussion in our forums if this feature would be of interest to you.

To work around this limitation, follow this approach:

  1. Go through all directories and upload all POM files with a path relative to the root directory
  2. Go through all directories again and upload all files that do not have POM and a checksum (like .md5)

Errors will occur, especially if you have invalid POM files or your directory structure does not conform to the required MAVEN convention. So check on a case by case basis if this matters (a bad artifact from 5 years ago can probably be ignored).

You can use a tool like curl or even maven deploy:deploy to deploy individual files.

Technical Limitations

Maven works differently than other feed types in that Maven artifacts are not self-contained archives; instead, an artifact is more like a grouping of files with some associated metadata. The Maven "API" is essentially just file requests.

Connectors & Local Indexing

Many public Maven repositories do not support search or indexing. Some (including Maven Central) have a large Lucene-based database that can be downloaded and contains all of the repository's artifacts.

ProGet will attempt to routinely download this index from the connectors, but this can be a very resource intensive process. If you do not need this search feature, we recommend disabling this task in ProGet. Artifacts accessed directly by name do not need this index.

This indexing is performed on a schedule. To manually trigger the index task, navigate to Admin > Scheduled Jobs and select FullMavenConnectorIndex. If this connector index is not available, go to Admin > Service page and trigger the Scheduled Job Dispatcher. This will reconfigure any missing scheduled jobs for the connector index.


Was this article helpful?