Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

maven install and deploy 3rd party dependencies with simple command line

We have a number of third party dependencies that aren't hosted anywhere. For each of these we have a jar file that we'd like to be able to install and/or deploy to our repository. Some of the jar files have their own dependencies and we also need to declare these.

We've made pom.xml files for each jar file that declare the groupId, artifactId, dependencies, etc. These pom.xml files all have a common parent pom that declares some of the common info (e.g. <repositories> and <distributionManagement>).

I'd like to be able to install or deploy these dependencies with something as simple as mvn install and mvn deploy (or maybe mvn install:install-file and mvn deploy:deploy-file) and have all the necessary properties for these commands (artifactId, repositoryId, etc.) be read from the pom.xml files.

To get this to work, at least for deploying, I tried putting the following in my parent pom:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-deploy-plugin</artifactId>
      <version>2.4</version>
      <configuration>
        <file>${jarfile}</file>
        <pomFile>pom.xml</pomFile>
        <repositoryId>our-id</repositoryId>
        <url>our-url</url>
      </configuration>
    </plugin>
  </plugins>
</build>

and then having each of the child poms define the jarfile property. That allows me to run mvn deploy:deploy-file to deploy all the child pom artifacts. Presumably I could do something similar to get mvn install:install-file to work.

But with this approach, I'm unable to release the parent pom (which I must do since the child poms depend on it), and if I try to mvn release:perform on the parent pom, I get errors like:

Cannot override read-only parameter: pomFile

I feel like I'm probably going about this the wrong way. All I really want to do is:

  • Put the common code for all the third party jars in one shared parent pom
  • Write an additional minimal pom for each third party jar
  • Be able to run something like mvn install or mvn deploy without having to specify all those complicated command line properties

How can I best accomplish that?

Edit: Made it clearer above that ideally I'd like to be able to run something as simple as mvn install or mvn deploy and not have to specify properties on the command line.

like image 456
Steve Avatar asked Jan 08 '11 06:01

Steve


2 Answers

When Maven is missing a dependency, it will give you an error in it's output that contains the command line to issue to add the jar to a remote repository. That command line will automatically create a POM for you and upload the two together. Is that not sufficient for your needs?

Using this facility, if I know that I have a dependency with no remote repository representation, I usually just go ahead and define it in my build with the GAV that I want, run the build once, then look at the build errors. Copy out the command for the deployment, then run that command. You'll want to make sure that you have the <repository> elements set up properly in the parent POM plus also set up corresponding <server> elements in your settings.xml with the repository upload password. Other than that, you should be good to go.

I would add that you should check out Nexus before getting to far. It's worth the hassle to set up now! :-)

like image 76
Brian Topping Avatar answered Oct 22 '22 13:10

Brian Topping


Ok, I found a solution that allows me to run just mvn install or mvn deploy and have the jar file installed to the local or remote repository. Inspired by a post to the maven-users list and using the build-helper plugin, in the parent pom, I have:

<pluginManagement>
    <plugins>
        <!-- Attach the jar file to the artifact -->
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>1.5</version>
            <executions>
                <execution>
                    <id>attach-artifacts</id>
                    <phase>package</phase>
                    <goals>
                        <goal>attach-artifact</goal>
                    </goals>
                    <configuration>
                        <artifacts>
                            <artifact>
                                <file>${artifactId}-${version}.jar</file>
                                <type>jar</type>
                            </artifact>
                        </artifacts>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</pluginManagement>

And then in the child poms, I have:

<packaging>pom</packaging>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
...
<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Some of the pieces of this that initially tripped me up:

  • The attach-artifact execution should be under <pluginManagement> so it doesn't get executed if you mvn install or mvn deploy the parent pom.
  • The children need to specify the build-helper-maven-plugin under the build plugins so that code from the parent <pluginManagement> gets run.
  • The children have to be declared as having <packaging>pom</packaging> because you can't add a jar to an artifact if it has the same name as the artifact.

The only downside I see to this approach is that the artifact gets deployed as type pom instead of type jar. But I haven't seen any real consequences of that.

like image 29
Steve Avatar answered Oct 22 '22 14:10

Steve