Search code examples
mavenmaven-3maven-install-plugin

How to create a private JAR in a local subdirectory which I have designated as an additional repository?


In a subdirectory under a project, I have a library module of code I write and maintain that must be shared with other modules in the larger project. For convenience, it's developed simultaneously alongside all the modules consuming it.

project
  libs
  module-A
  module-B
  module-N
  library-module

For complicated reasons imposed by how our build is done after it leaves our hands, we don't want it deployed to the build host's local Maven repository (~/.m2/repository). Instead, we want it in a subdirectory local to the project, here libs.

From the command line, I know the following will put it into the local Maven repository, but I don't want to do this from the command line and I don't want the result to go to the local Maven repository. I want this to happen when mvn install is run by the build system in the library-module subdirectory.

mvn install:install-file -Dfile=your-artifact-1.0.jar \
                         [-DpomFile=your-pom.xml] \
                         [-Dsources=src.jar] \
                         [-Djavadoc=apidocs.jar] \
                         [-DgroupId=org.some.group] \
                         [-DartifactId=your-artifact] \
                         [-Dversion=1.0] \
                         [-Dpackaging=jar] \
                         [-Dclassifier=sources] \
                         [-DgeneratePom=true] \
                         [-DcreateChecksum=true]

(Note that the answer I'm looking for would not be IDE-dependent.)


Solution

  • To meet the provided requirements, two configuration steps are then required:

    • Disable the default artifact installation to the local repository, via the skip option of the Maven Install Plugin
    • Configure the install-file goal within the POM in order to have it as part of your build (hence no need to invoke it manually from command line)

    The following configuration would provide it:

    <properties>
        <library.repository.folder>../libs</library.repository.folder>
    </properties>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>install-artifact</id>
                        <phase>install</phase>
                        <goals>
                            <goal>install-file</goal>
                        </goals>
                        <configuration>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>${project.artifactId}</artifactId>
                            <version>${project.version}</version>
                            <packaging>${project.packaging}</packaging>
                            <file>${project.build.directory}/${project.build.finalName}.${project.packaging}</file>
                            <localRepositoryPath>${library.repository.folder}</localRepositoryPath>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    

    Please note the library.repository.folder property used to point to the desired target lib folder (to change in case of different path). The configuration provided above makes use of standard maven properties (for project coordinates and packaging), but you can change them (or hard-code real values) as required.

    Also note that the install-file goal will recreate under the lib folder the same folders structure as in the local repository (lib\groupId\artifactId\version\file.jar). If you instead would like to have the file straight under the lib folder (lib\file.jar) you could then move to the following configuration:

    <properties>
        <library.repository.folder>../libs</library.repository.folder>
    </properties>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <outputDirectory>${library.repository.folder}</outputDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    This time we are not using the install-file goal but rather the jar goal of the Maven Jar Plugin to place the packaged artifact directly to the lib folder (instead of the standard target folder) and during the package phase (not install).

    If by any reason you want to keep the final artifact in the target folder AND have it straight copied to the lib folder (no maven folders hierarchy) AND during the install phase, then you could move to the following configuration:

    <properties>
        <library.repository.folder>../libs</library.repository.folder>
    </properties>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>re-package-into-lib</id>
                        <phase>install</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${library.repository.folder}</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>