Install local jar dependency as part of the lifecycle, before Maven attempts to resolve it

Here's the few solutions I tried, but weren't great for my uses:

1. maven-install-plugin

The idea is to add the install-file goal as part of the install lifecycle by adding this to the pom:

<plugin>
  <artifactId>maven-install-plugin</artifactId>
  <version>2.5.2</version>
  <executions>
    <execution>
      <phase>validate</phase>
      <goals>
        <goal>install-file</goal>
      </goals>
      <configuration>
        <file>lib/my-custom-jar-1.0.0.jar</file>
      </configuration>
    </execution>
  </executions>
</plugin>

[...]

<dependency>
  <groupId>org.me</groupId>
  <artifactId>my-custom-jar</artifactId>
  <version>1.0.0</version>
</dependency>

However, even on the very first goal, validate, Maven will try to resolve dependencies before install-file is run.

I saw the idea of using the clean goal. Annoyingly, this works when you do separate commands (mvn clean && mvn install) but if you do both in one mvn command (mvn clean install), Maven will resolve dependencies first. Could there be a solution to this?

2. Multi Module Project

The idea, seen in this Stack Overflow answer, is that you install-file in your parent pom, and add the dependency in your child pom. Maven will only resolve dependencies separately so this should work.

However my project is a single module, and making a fake parent just to solve this problem seems like an over-complication and an ugly hack.

3. System scope with basedir

<dependency>
  <groupId>org.me</groupId>
  <artifactId>my-custom-jar</artifactId>
  <version>1.0.0</version>
  <scope>system</scope>
  <systemPath>${basedir}/lib/my-custom-jar-1.0.0.jar</systemPath>
</dependency>

Although this looks like this was made exactly for this kind of situation, the system scope actually expects the dependency to be on every system where you'll run your project, and so it will not be packaged in the .war, making my project non-functional.

4. addjars-maven-plugin

This custom plugin found here includes a .jar in your .war file, then adds it to your pom during compilation.

<plugin>
  <groupId>com.googlecode.addjars-maven-plugin</groupId>
  <artifactId>addjars-maven-plugin</artifactId>
  <version>1.0.5</version>
  <executions>
    <execution>
      <goals>
        <goal>add-jars</goal>
      </goals>
      <configuration>
        <resources>
          <resource>
            <directory>${basedir}/lib</directory>
            <includes>
              <include>**/my-custom-jar-1.0.0.jar</include>
            </includes>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

This will work in most normal cases. However, since you don't indicate any dependency to your custom .jar in your actual pom, your IDE will be missing a lot of classes, so you'll need to manually add your custom .jar as an external library.

This still is somewhat hacky and does not work with some special cases (hpi:run for Jenkins debugging for example throws some errors). Plus I preferred that my code did not rely on third-party plugins.

5. In-directory Maven repository

I found this solution after creating this post, and I'm pretty happy with it.

This is pretty much the same result as doing the mvn install-file command in my question, except you save the result and keep it as part of your project by installing the custom library in a repository located inside your project.

You will need to pre-install the library using this command.

mvn org.apache.maven.plugins:maven-install-plugin:2.5.1:install-file \
-Dfile=lib/cloudfoundry-client-lib-shaded-1.0.3.jar \
-DlocalRepositoryPath=lib

Once that's done your repository is created in the lib folder and you won't need to do this command ever again.

Indicate that you want to use this repository in your pom:

<repository>
  <id>Local repository</id>
  <url>file://${basedir}/lib</url>
</repository>

[...]

<dependency>
  <groupId>org.me</groupId>
  <artifactId>my-custom-jar</artifactId>
  <version>1.0.0</version>
</dependency>

This solution forces you to commit a bunch of extra folders to your SCM, but that was a manageable drawback for me and I'm satisfied with this.