When using some third party dependencies in a maven project you realize that sometimes some of jars are not available in any of the public maven repositories available (e.g. the oracle jdbc driver that is not available for copyright reasons)
When developing a team project and that you are required to use a jar of this type you have mainly 3 options :
1. Using Maven repository repository manager
There are a few maven repository managers out there which allow mainly to mirror distant maven repositories such as maven central, by storing the remote jars locally and making them available inside the company
This is where you can store your companies jars and wars and some other jar not available in the public repositories
I will not go into the details of the different repository managers but there are mainly 3
I never used Archiva but I really like Nexus. There is a nice comparison matrix over here so you can make and educated choice
Anyhow if you or your company have a repository manager you can easily install the required JAR on your repository.
Once the JAR is installed in the repository it will be available to anyone that uses the repository as long as your settings.xml file or pom.xml file are properly configured.
The main advantage if this approach is that once the JAR downloaded and installed in the repository manager it will be available for all the users and future projects
The main inconvenient is the fact that you need to install a repository manager
2. Installing the JAR in the maven local repository
Installing a JAR in the user's maven local repo is quite straightforward
a) Download the JAR to the local machine
b) Install the JAR in the local repository
mvn install:install-file -Dfile=/data/downloads/ojdbc6.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.3
c) Declare the JAR as a maven dependency
..... =com.oracle ojdbc6 11.2.0.3
This is the quickest and simplest approach to implement
The major inconvenient is that every new developer will need to install the JAR in their local repository
3. Using the addjars shade plugin and system as dependency scope
Maven allows you to easily defined dependencies with a system scope. But there is a problem with system scoped jars. When packaging the application (WAR, JAR, etc.) the system scoped jars will not be included in the packaged result. Here is where the addjar plugins comes in handy, this plugin allows you to include system scoped jars when packaging the application
Below is a quick example of a simple java web app with system scoped jar (ojdbc6.jar) :
my-app |-- pom.xml `-- src |-- main | `-- java | `-- webapp |-- external | `-- ojdbc6.jar
As stated before if I run a mvn package on this project I will get a WAR file but the ojdbc6.jar JAR will not be included under WEB-INF/lib
Thankfully the addjars plugins comes to the rescue here this plugin will include your third party jar in your project's classpath when packaging
You can see below a sample configuration for the plugin in the pom.xml file :
... ... com.googlecode.addjars-maven-plugin addjars-maven-plugin 1.0.5 add-jars ${basedir}/external/
The main advantage is that once the pom.xml configured with the dependency and the plugin and the JAR committed into the source control the building becomes transparent for the users
The main inconvenient comes from the fact that you will need to commit the JAR file in your source control repository and handle JAR versions manually
It's good to note that the add-jars plugin requires maven 3.0.3+
Hi there, nice tutorial.
ReplyDeleteIt's been a long time since you have published this, but I hope you could help me with a problem I have with this plugin.
Here you can see the artifactId and version I gave to my project in POM.xml file:
DesktopApp
1.0.0
So, when I execute MVN Install inside Eclipse IDE, all libraries all copied correctly to the target folder, however, addjars-plugin changes the name of dependencies and appends artifactId and version of the project to the definition.
For example, I use a JAR dependency called "Tidy.jar", and it has the same name in target/lib folder, but in classpath defined in executable JAR, it is deifned as "lib/DesktopApp-Tidy.jar-1.0.0.jar"
Any ideas why does this happen? :/
Thanks in advance for any advice.
Hi it has been some time since I wrote this article.
ReplyDeleteHow are you building your runnable jar? maven plugin? do you have some special structure in your project?
Maybe you can provide me your full pom.xml file so I can look at the other build plugins that might interact with the addjars plugin.
Thanks a lot! It helped me resolve a critical issue.
ReplyDeletehi thanks for the comment, glad it helped you out
ReplyDelete