Search code examples
javamavenmaven-jar-pluginmaven-install-plugin

Maven project packaging is war but also building/installing jar


I have a Maven 3.3 project, and the main output is a war file:

<artifactId>pro</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

I am using the maven plugin to also build a jar file, which goes into target/pro-1.0-SNAPSHOT.jar and this works.

I would like to install this jar to the local maven repo, so I'm using the maven install plugin to do this:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-install-plugin</artifactId>
    <version>2.5.2</version>
    <configuration>
        <classifier>jar</classifier>
        <packaging>jar</packaging>
        <file>target/pro-1.0-SNAPSHOT.jar</file>
    </configuration>
    <executions>
        <execution>
            <id>do-jar-install</id>
            <phase>install</phase>
            <goals>
                <goal>install</goal>
            </goals>
        </execution>
    </executions>
</plugin>

The whole build works fine except the jar install step is installing the war, and not the jar. How do I override this?

I'm looking here to see what I can use: http://maven.apache.org/plugins/maven-install-plugin/examples/installing-secondary-artifacts.html

Here is the log from my build:

**

Building jar: /Users/mike/code/workspace/pro/target/pro-1.0-SNAPSHOT.jar

[INFO] --- maven-install-plugin:2.5.2:install (do-jar-install) @ pro

[INFO] Installing /Users/mike/code/workspace/pro/target/pro-1.0-SNAPSHOT.jar to /Users/mike/.m2/repository/net/mikeski/pro/1.0-SNAPSHOT/pro-1.0-SNAPSHOT.war

Note the last line - it's picking up the jar but installing a war

How can I fix that?

As requested, here is the jar plugin config:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <executions>
        <execution>
            <id>create-jar</id>
            <phase>install</phase>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

It creates a jar of the files in the project, and it's the correct jar. If I copy the war that is installed in my repo to a jar (so I just change the extension) my other project can pick it up just fine.


Solution

  • Your current output is the result of multiple considerations, one of them being maven-jar-plugin too permissive in version 2.4.

    First of all, you need to remember that inside a Maven repository, all the artifacts share a single naming convention, which is artifactId-version(-classifier).packaging. This means that whatever the local name of the file your build is producing (let it be foo.jar), it will be installed and it will be deployed with this conventional name. All that matters when artifacts are installed are the Maven coordinates, i.e. the groupId, the artifactId, the version, the classifier and the packaging.

    What is happening here is:

    1. Your project has a packaging war. Running Maven with mvn install, the default-install phase will be invoked first and the maven-install-plugin:install goal will be run a first time, installing your WAR project. On your logs, you will find:

      [INFO] --- maven-install-plugin:2.5.2:install (default-install) @ test-war ---
      [INFO] Installing ...\test-war\target\test-war-0.0.1-SNAPSHOT.war to ...\test-war\0.0.1-SNAPSHOT\test-war-0.0.1-SNAPSHOT.war
      [INFO] Installing ...\test-war\pom.xml to ...\test-war\0.0.1-SNAPSHOT\test-war-0.0.1-SNAPSHOT.pom
      
    2. Then, you are using the maven-jar-plugin:jar goal to create a JAR. This plugin creates a JAR for the current Maven project - so it will create it alright, but the Maven coordinates of this new artifact will be exactly the same as those of your WAR project (you didn't specify a classifier). Therefore, you effectively replace the file of the main artifact (which is a WAR), by a JAR file: you end up with a local file having an extension of jar (because the maven-jar-plugin created it this way) that is the file of the main artifact of a Maven project of packaging war. Quite confusing.

      Remember that I said that the maven-jar-plugin was too permissive? If you update to version 3.0.2 of the plugin, you will get an error right here (MJAR-198):

      You have to use a classifier to attach supplemental artifacts to the project instead of replacing them. -> [Help 1]

      which summarizes what is said above.

    3. Finally, you declared another execution of the maven-install-plugin called do-jar-install, that is supposed to install this local JAR file. And this is what it does: it installs the local JAR file inside your target folder to your local Maven repository using the coordinates of the artifact. The confusion comes from the fact that the type (packaging) of the artifact is in fact WAR, so what gets installed is a WAR file (being effectively a JAR)...


    Now that we've explained the issue, the question is: what do you want to do? It looks like you want to attach to your WAR project an additional artifact composed of the classes of it. There is no need for all this configuration, you can just use the attachClasses parameter of the maven-war-plugin.

    <plugin>
      <artifactId>maven-war-plugin</artifactId>
      <version>2.6</version>
      <configuration>
        <attachClasses>true</attachClasses>
      </configuration>
    </plugin>