How to register a custom Maven repository layout

Maven repositories have a defined directory layout. In the standard installation Maven comes with 2 implementations, the default layout for Maven 2 and legacy layout for Maven 1.x. The layout is configured in the repository setting either in POMs or settings.xml file.

   <settings>
        ...
      <pluginRepositories>
        <pluginRepository>
          <id>codehausSnapshots</id>
          <name>Codehaus Snapshots</name>
          <releases>
            <enabled>false</enabled>
            <updatePolicy>always</updatePolicy>
            <checksumPolicy>warn</checksumPolicy>
          </releases>
          <snapshots>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
            <checksumPolicy>fail</checksumPolicy>
          </snapshots>
          <url>http://snapshots.maven.codehaus.org/maven2</url>
          <layout>default</layout>
        </pluginRepository>
      </pluginRepositories>
      ...
</settings>

Normally the default structure is sufficient, but if what to do if forever which reason the layout should be changed? Basically what needs to be done is to provide an implementation of the ArtifactRepositoryLayout interface, register the implementation to Maven and configure repositories with a custom layout identifier, e.g.
<layout>custom</layout>

The Maven core is extensible, based on the Plexus IoC container. Plexus components are configured in META-INF/plexus/components.xml. Component implementations are looked up from the Plexus container with a key identified by role and optionally role-hint. A components.xml with a custom ArtifactRepositoryLayout looks like this:

<component-set>
    <components>
        <component>
            <role>org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout</role>
            <role-hint>custom</role-hint>
            <implementation>com.itemis.example.maven.repolayout.CustomRepositoryLayout</implementation>
        </component>
    </components>
</component-set>

The role-hint value is the identifier that is matched with the repository’s <layout> configuration.

Let’s assume a project artifact should be deployed to a Maven repository with custom layout. The corresponding section in the pom.xml file is for example:

  <distributionManagement>
    <snapshotRepository>
      <id>testrepo.snapshot</id>
      <url>/tmp/repository</url>
      <layout>custom</layout>
    </snapshotRepository>
  </distributionManagement>

Without proper setup a “mvn deploy” would fail with exception:
mvn deploy
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error building POM (may not be this project's POM).

Project ID: com.itemis.example.maven:custom-repository-test
POM Location: /Users/thoms/Development/workspaces/sandbox-jsf/custom-repository-test/pom.xml
Reason: Cannot find layout implementation corresponding to: 'custom' for remote repository with id: 'testrepo.snapshot'. for project com.itemis.example.maven:custom-repository-test at /Users/thoms/Development/workspaces/sandbox-jsf/custom-repository-test/pom.xml

The jar with the custom layout implementation has to be deployed to $MAVEN_HOME/lib (on my machine /usr/share/maven/lib for example). All libraries from that directory are automatically included. It might be necessary to adjust $MAVEN_HOME/bin/m2.conf and add the following section and put the jar containing the custom repository layout implementation into a custom folder:
[plexus.core.maven]
load ${maven.home}/custom/*.jar

After doing so a deployment should be successful and use the customized layout:

> mvn deploy
...
[INFO] [deploy:deploy {execution: default-deploy}]
[INFO] Retrieving previous build number from testrepo.snapshot
Uploading: /tmp/repository/com/itemis/example/maven/1.0.0-SNAPSHOT/custom-repository-test/custom-repository-test-1.0.0-20091013.164125-2.jar

The custom implementation here changes the order of the base version and artifact id in the repository layout structure. The normal Maven2 repository structure is groupId/artifactId/version, this here uses groupId/version/artifactId. The sourcecode for this example can be downloaded here.

4 thoughts on “How to register a custom Maven repository layout

  1. Hi

    Does this also work with maven3?

    I followed this nut I get:
    Caused by: org.sonatype.aether.transfer.NoRepositoryConnectorException: No connector available to access repository testrepo.snapshot (/tmp/repository) of type custom using the available factories WagonRepositoryConnectorFactory

    —————-

    Thanks
    Lucas

Leave a reply to kthoms Cancel reply