Install Jar Dependency to Local Repository as Part of Maven Build Process
Solution 1
I suggest you modeling the external dependency as a separate project (think of it as a wrapper). Your current project may then be dependent on your own project that as part of its build can download the external JAR and package it into its own distributable.
Solution 2
The solution from http://randomizedsort.blogspot.com.es/2011/10/configuring-maven-to-use-local-library.html is based on having a file-based, project-scoped maven repository. Thus, the library is under your source code versioning. Install is one-time manual process, rather than a something specified in the pom.xml
file
Three steps:
- Create a folder in your project where you will keep the repo. Say
lib
. -
Use Maven to install your jar to the lib directory.
mvn install:install-file -Dfile=path_to_mylib.jar ^ -DgroupId=com.mylib ^ -DartifactId=mylib ^ -Dversion=1.0 ^ -Dpackaging=jar ^ -DlocalRepositoryPath=path_to_my_project/lib
3.Update your pom.xml
<repositories>
<repository>
<!-- DO NOT set id to "local" because it is reserved by Maven -->
<id>lib</id>
<url>file://${project.basedir}/lib</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.mylib</groupId>
<artifactId>mylib</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
Solution 3
Saw this question while looking for a solution to a similar problem. I know it's old, but wanted to share my solution. I ended up solving my problem by using the maven-install-plugin directly:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>whatevs</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
<packaging>jar</packaging>
<file>${basedir}/dev-setup/lib/ojdbc6.jar</file>
</configuration>
</execution>
</executions>
</plugin>
Works perfectly.
Solution 4
Alrighty, arguing and preference aside, I did go with Sander's recommendation; it was the only one that really worked without custom Mojos, etc. I have a parent Maven project with a packaging of type pom
and all it does is install the third-party jar (which could be any number of jars or dependencies) to my local repository. The parent pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>project-evip</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>EvipSoapServerJar</name>
<packaging>pom</packaging>
<modules>
<module>webservices</module>
</modules>
<build>
<plugins>
<!-- This plugin installs the Evip jar from the project's lib to the local
repository for normal Maven consumption -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<inherited>false</inherited>
<executions>
<execution>
<id>install-evip-jar</id>
<phase>validate</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>mvn</executable>
<arguments>
<argument>install:install-file</argument>
<argument>-Dfile=${basedir}\src\main\resources\EVIPSoapServer.jar</argument>
<argument>-DgroupId=com.company</argument>
<argument>-DartifactId=EVIPSoapServer</argument>
<argument>-Dversion=1.0.0</argument>
<argument>-Dpackaging=jar</argument>
</arguments>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.codehaus.mojo
</groupId>
<artifactId>
exec-maven-plugin
</artifactId>
<versionRange>
[1.2.1,)
</versionRange>
<goals>
<goal>exec</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Then, I created a Maven module under the parent Maven project and used the org.apache.cxf.archetype:cxf-jaxws-javafirst:2.7.7
archetype. I simply list the third-party jar as a compile-time dependency, and it's resolved and added to the resulting war. The child module's pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>project-evip</artifactId>
<groupId>com.company</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.company</groupId>
<artifactId>webservices</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Web Services</name>
<description>This project will handle communication.</description>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<!-- INCLUDE SOURCE FILES WITH WAR -->
<resource>
<directory>${project.build.sourceDirectory}</directory>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<!-- mvn clean install tomcat:run-war to deploy Look for "Running war
on http://xxx" and "Setting the server's publish address to be /yyy" in console
output; WSDL browser address will be concatenation of the two: http://xxx/yyy?wsdl -->
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>start-tomcat</id>
<goals>
<goal>run-war</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<port>${test.server.port}</port>
<path>/webservice</path>
<fork>true</fork>
<useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<projectNameTemplate>[artifactId]-[version]</projectNameTemplate>
<wtpmanifest>true</wtpmanifest>
<wtpapplicationxml>true</wtpapplicationxml>
<wtpversion>2.0</wtpversion>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<!-- COMPILE DEPENDENCIES -->
<dependency>
<groupId>com.company</groupId>
<artifactId>EVIPSoapServer</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.7.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.7.RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- PROVIDED/TEST DEPENDENCIES -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
I appreciate all the help, thank you.
Related videos on Youtube
liltitus27
Updated on September 17, 2022Comments
-
liltitus27 over 1 year
I have a third-party jar that is a dependency of my project. Because of business constraints, I do not have access to an enterprise or company repository, which would definitely be my preference for this issue. But regardless, this third-party jar is not available publicly, and so it is included in the web project under
src\main\resources
.This is a Maven project, and so I list this third-party jar as a compile time dependency, and include in my pom a build plugin that will install the third-party jar to my local repository as part of the build process; I tell Maven to perform this goal during the
validate
phase of the build lifecycle, which to my knowledge would be before any other Maven phase.However, when I run a
clean install
and have my local repository cleared out, the build fails due to the third-party jar not being resolvable locally or in the Maven central repository. As far as I know, I have set up the pom correctly and I should be seeing Maven attempt to install the third-party jar locally before it begins dependency resolution.The issue is that if the dependency is listed before the jar has ever been installed locally, the build will fail due to being unable to resolve that dependency. If I remove the third-party jar declaration and run the build, after dependency resolution occurs (which is the very first thing it does after the clean), but before any other phase, it will locally install the jar and things are fine. But to my knowledge, it should run the
validate
phase before it collects and resolves dependencies, and so the jar should be locally installed before it's resolved by Maven. Any ideas or thoughts?My pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.company</groupId> <artifactId>project</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>Web Services</name> <description>This project will handle communication.</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <!-- This plugin installs the Evip jar from the project's resource folder to the local repository for normal Maven consumption --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <inherited>false</inherited> <executions> <execution> <id>install-evip-jar</id> <phase>validate</phase> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <executable>mvn</executable> <arguments> <argument>install:install-file</argument> <argument>-Dfile=${basedir}\src\main\resources\EVIPSoapServer.jar</argument> <argument>-DgroupId=com.company</argument> <argument>-DartifactId=EVIPSoapServer</argument> <argument>-Dversion=1.0.0</argument> <argument>-Dpackaging=jar</argument> </arguments> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <!-- EXCLUDE EVIPSOAPSERVER JAR FROM CLASSES DIRECTORY --> <packagingExcludes> ${basedir}\src\main\resources\EVIPSoapServer.jar </packagingExcludes> <webResources> <!-- INCLUDE SOURCE FILES WITH WAR --> <resource> <directory>${project.build.sourceDirectory}</directory> <targetPath>WEB-INF/classes</targetPath> </resource> </webResources> </configuration> </plugin> </plugins> <pluginManagement> <plugins> <plugin> <!-- mvn clean install tomcat:run-war to deploy Look for "Running war on http://xxx" and "Setting the server's publish address to be /yyy" in console output; WSDL browser address will be concatenation of the two: http://xxx/yyy?wsdl --> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.0</version> <executions> <execution> <id>start-tomcat</id> <goals> <goal>run-war</goal> </goals> <phase>pre-integration-test</phase> <configuration> <port>${test.server.port}</port> <path>/webservice</path> <fork>true</fork> <useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <configuration> <projectNameTemplate>[artifactId]-[version]</projectNameTemplate> <wtpmanifest>true</wtpmanifest> <wtpapplicationxml>true</wtpapplicationxml> <wtpversion>2.0</wtpversion> </configuration> </plugin> <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. --> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> <pluginExecutionFilter> <groupId> org.codehaus.mojo </groupId> <artifactId> exec-maven-plugin </artifactId> <versionRange> [1.2.1,) </versionRange> <goals> <goal>exec</goal> </goals> </pluginExecutionFilter> <action> <ignore></ignore> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement> </build> <dependencies> <!-- COMPILE DEPENDENCIES --> <dependency> <groupId>com.company</groupId> <artifactId>EVIPSoapServer</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>2.7.7</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>2.7.7</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>3.0.7.RELEASE</version> <scope>compile</scope> </dependency> <!-- PROVIDED/TEST DEPENDENCIES --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </project>
-
Sander Verhagen over 10 yearsIt sounds like the other way around:
SNAPSHOT
means you're still developing it. It was just a side-remark, not related to your question so much.
-
-
liltitus27 over 10 yearsIt's not a very Maven thing to do, though. And that's a heck of a lot of effort to simply include a jar dependency that doesn't live in central repository. The way I figure it is that the jar that I need is not a separate project, and Maven is meant to handle dependency management and build lifecyle of projects, so my needs should be perfectly within Maven's capabilities. The manner by which I'm attempting to resolve this issue is accepted and recommended as well: stackoverflow.com/questions/1355548/…
-
Sander Verhagen over 10 yearsWhat you are trying to do is not a very Maven thing to do, I would say. If it is not in the central repository, put it in your company repository. I was just assuming that you don't have a company repository, otherwise that would have been the obvious solution. With putting it in a separate project, you're abstracting the underlying problem (it not being in any repository that you have access to) away from the user.
-
liltitus27 over 10 yearsYou're correct, I do not have access to an enterprise or company repository; believe me, that's what I'd prefer for sure. That being said, if a project resource (e.g., this third-party jar) is part of the project, then the dependency is packaged along with everything else and all that needs to happen is that it is installed to a local repository at build-time; this way, the entire process is handled completely by Maven and takes no special setup for any other project developer.
-
Sander Verhagen over 10 yearsI agree, but in my solution it would still be handled completely by Maven. You could set up a parent project to get it to build in one go. Your call, and good luck! :)
-
Wiwiweb over 9 yearsWhen I try this (With both
mvn install
ormvn validate
), Maven complains about a missing dependency before trying to run the maven-install plugin. What command do you use exactly, and with what version of Maven? Thank you very much in advance.