---
title: "Maven (Java)"
order: 8
---

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](https://maven.apache.org/docs/history.html) 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](https://maven.apache.org/settings.html). 

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.
```xml
<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:

```xml
<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:

```xml
<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.

```xml
<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](/docs/proget/administration-security/proget-howto-configure-permissions-and-restrictions-on-feeds), you must configure Maven to authenticate with ProGet.

To do this, we recommend that you first [create an API key](/docs/proget/reference-api/proget-apikeys) 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:

```xml
<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`.

```xml
<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:

```xml
<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:

```xml
<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:

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

## Snapshot versions
[Snapshot versions](https://maven.apache.org/guides/getting-started/index.html#What_is_a_SNAPSHOT_version) 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.


:::(Error) (Don't Use `deploy:deploy-file` with `-SNAPSHOT` Artifacts)
Maven has a [deploy:deploy "mojo"](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) 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.
:::
:::(Warning) (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](https://web.archive.org/web/20150308195657/http://docs.codehaus.org/display/MAVEN/Versioning).

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](/docs/proget/administration/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](/docs/proget/feeds/feed-overview/proget-bulk-import-with-droppath) 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.

::: (Warning) (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](https://forums.inedo.com/topic/3128) 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.