180

It's my first couple of days learning Maven and I'm still struggling with the basics. I have an external .jar file (not available in the public repos) that I need to reference in my project and I'm trying to figure out what my best option is.

It's a small scale project without a central repository for libraries, so it has to be either a local repository (somehow added to source control, don't know if it's supposed to work that way?) or the .jar needs to be stored on disk outside of any formal repository.

1) What's my best option for adding the .jar file to my project's references with maven given that I want both the project and the library to be in source control?

2) I still can't seem to have Eclipse see the dependency. I manually added it to the section of the pom, and it shows up fine in the Dependencies list in m2eclipse. mvn compile and mvn package both succeed, but running the program results in:

Exception in thread "main" java.lang.Error: Unresolved compilation problems:
        LibraryStuff cannot be resolved to a type

This is after editing the POM as:

<dependency>
  <groupId>stuff</groupId>
  <artifactId>library</artifactId>
  <version>1.0</version>
  <systemPath>${lib.location}/MyLibrary.jar</systemPath>
  <scope>system</scope>
</dependency>

Should I be executing mvn install:install-file even thought I already have the pom.xml edited as above?

Thanks!

Alexandr Kurilin
  • 7,685
  • 6
  • 48
  • 76

15 Answers15

226

You can create an In Project Repository, so you don't have to run mvn install:install-file every time you work on a new computer

<repository>
    <id>in-project</id>
    <name>In Project Repo</name>
    <url>file://${project.basedir}/libs</url>
</repository>

<dependency>
    <groupId>dropbox</groupId>
    <artifactId>dropbox-sdk</artifactId>
    <version>1.3.1</version>
</dependency>

/groupId/artifactId/version/artifactId-verion.jar

detail read this blog post

https://web.archive.org/web/20121026021311/charlie.cu.cc/2012/06/how-add-external-libraries-maven

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
Charlie Wu
  • 7,657
  • 5
  • 33
  • 40
  • 2
    Using the above solution shown a warning while doing "mvn clean package" - The POM for project is missing, no dependency information available. – Jignesh Gohel Apr 22 '14 at 11:10
  • That's the best solution for those cases where you need to add one or just few jar files. Thanks. – Antonio Sesto Nov 03 '14 at 15:41
  • 2
    Or, you can add local dependencies directly as in http://stackoverflow.com/a/22300875/640378 – mauryat Mar 11 '15 at 21:18
  • 3
    I had to use file:///${project.basedir}/libs (3 forwarded slashes) instead of file://${project.basedir}/libs – Loc Phan Nov 30 '16 at 11:11
  • 3
    If the jar being installed, isn't an maven compiled jar, you will also need to add a new pom file to define the metadata. To save yourself all of these manual trouble, I would recommend to use `mvn install:install-file` and then copy the entire directory structure from your local repository to your in-project repository. – Isen Ng Jun 14 '17 at 08:49
  • 2
    Beware that when you create folder structure `/groupId/artifactId/version/artifactId-verion.jar`, don't make the mistake of using pakage name as `groupId`; instead it should be divided in a folder tree. E.g. for the groupId `org.json` the path should look like `org/json/2.0/json-2.0.jar`, and not `org.json/2.0/json-2.0.jar` – dnang Nov 15 '17 at 10:35
  • **2019** Original URL doesnt work, use this: https://web.archive.org/web/20121026021311/charlie.cu.cc/2012/06/how-add-external-libraries-maven/ – Oliver Oct 10 '19 at 13:39
  • 1
    Note that instead of constructing the libs directory structure manually, you can also do this: mvn install:install-file -Dfile=dropbox-sdk-1.3.1.jar -DgroupId=dropbox -DartifactId=dropbox-sdk -Dversion=1.3.1 -Dpackaging=jar -DlocalRepositoryPath=lib -DcreateChecksum=true This will create the structure for you and also create the checksum metadata to avoid the Maven warning. – Jonas_Hess Jun 30 '20 at 20:15
68

I think you should use mvn install:install-file to populate your local repository with the library jars then you should change the scope from system to compile.

If you are starting with maven I suggest to use maven directly not IDE plugins as it adds an extra layer of complexity.

As for the error, do you put the required jars on your classpath? If you are using types from the library, you need to have access to it in the runtime as well. This has nothing to do with maven itself.

I don't understand why you want to put the library to source control - it is for sources code not binary jars.

stalker
  • 1,300
  • 1
  • 13
  • 16
  • 36
    for more on `mvn install::install-file`: http://www.mkyong.com/maven/how-to-include-library-manully-into-maven-local-repository/ – Doug T. Dec 17 '12 at 16:34
  • 8
    Using `mvn install::install-file` on your local repository would mean that anyone who clones your source code would have to do this manual step as well. Otherwise, the build is broken out-of-the box – Isen Ng Jun 14 '17 at 08:46
  • that won't add the jar to the war file though. – Prachi Sep 06 '19 at 21:17
38

This can be easily achieved by using the <scope> element nested inside <dependency> element.

For example:

 <dependencies>
   <dependency>
     <groupId>ldapjdk</groupId>
     <artifactId>ldapjdk</artifactId>
     <scope>system</scope>
     <version>1.0</version>
     <systemPath>${basedir}\src\lib\ldapjdk.jar</systemPath>
   </dependency>
 </dependencies>

Reference: http://www.tutorialspoint.com/maven/maven_external_dependencies.htm

Nathan
  • 8,093
  • 8
  • 50
  • 76
Jignesh Gohel
  • 6,236
  • 6
  • 53
  • 89
  • This method works very well when you only have the Eclipse Embedded Maven, and you lack the install plugin (offline system), so you can't run `install` goal on the depend-ed project. Ofc having an airgapped system and having all plugins but the install plugin, is quite a rare situation. – Cardin Nov 23 '18 at 07:18
  • 2
    Cleanest and easiest. – Ajay Kumar Mar 21 '19 at 18:58
  • how to add local dependency path which is outside ${project.basedir} folder, like I want ${basedir}\src\lib\ldapjdk.jar path 1 level up in other folder – Naveen Kumar Feb 13 '20 at 12:45
  • I am getting error - `"The POM for … is missing, no dependency information available” even though it exists in Maven Repository` – garg10may Jun 17 '20 at 08:22
  • how to make this work on kubernetes – Girish Oct 25 '22 at 17:46
29

The Maven manual says to do this:

mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar
jacobq
  • 11,209
  • 4
  • 40
  • 71
Vladislav Rastrusny
  • 29,378
  • 23
  • 95
  • 156
  • 6
    this command install the lib into your maven repo. The downside of this is if you try to work on a project in a different computer, you have to run this again. – Charlie Wu Nov 05 '14 at 00:43
25

update We have since just installed our own Nexus server, much easier and cleaner.

At our company we had some jars that we some jars that were common but were not hosted in any maven repositories, nor did we want to have them in local storage. We created a very simple mvn (public) repo on Github (but you can host it on any server or locally):
note that this is only ideal for managing a few rarely chaning jar files

  1. Create repo on GitHub:
    https://github.com/<user_name>/mvn-repo/

  2. Add Repository in pom.xml
    (Make note that the full path raw file will be a bit different than the repo name)

    <repository>
        <id>project-common</id>
        <name>Project Common</name>
        <url>https://github.com/<user_name>/mvn-repo/raw/master/</url>
    </repository>
    
  3. Add dependency to host (Github or private server)
    a. All you need to know is that files are stored in the pattern mentioned by @glitch
    /groupId/artifactId/version/artifactId-version.jar
    b. On your host create the folders to match this pattern.
    i.e if you have a jar file named service-sdk-0.0.1.jar, create the folder service-sdk/service-sdk/0.0.1/ and place the jar file service-sdk-0.0.1.jar into it.
    c. Test it by trying to download the jar from a browser (in our case: https://github.com/<user_name>/mvn-repo/raw/master/service-sdk/service-sdk/0.0.1/service-sdk-0.0.1.jar

  4. Add dependency to your pom.xml file:

    <dependency>
        <groupId>service-sdk</groupId>
        <artifactId>service-sdk</artifactId>
        <version>0.0.1</version>
    </dependency>
    
  5. Enjoy

uı6ʎɹnɯ ꞁəıuɐp
  • 3,431
  • 3
  • 40
  • 49
Kenny Cason
  • 12,109
  • 11
  • 47
  • 72
12

If you meet the same problem and you are using spring-boot v1.4+, you can do it in this way.

There is an includeSystemScope that you can use to add system-scope dependencies to the jar.

e.g.

I'm using oracle driver into my project.

<dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc14</artifactId>
        <version>10.2.0.3.0</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/src/main/resources/extra-jars/ojdbc14-10.2.0.3.0.jar</systemPath>
    </dependency>

then make includeSystemScope=true to include the jar into path /BOOT-INF/lib/**

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <includeSystemScope>true</includeSystemScope>
    </configuration>
</plugin>

and exclude from resource to avoid duplicated include, the jar is fat enought~

<build>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>**/*.jar</exclude>
            </excludes>
        </resource>
    </resources>
</build>

Good luck!

chendu
  • 534
  • 5
  • 10
  • I was looking for a solution like this one, simply because when a new developer arrives, this simplify the installation procedure. When you don't have an artifactory server, its way easier to have the custom dependency in your project. Also when you use a CI, this solution avoid to manually install the jar on the CI server. – Dalc Sep 16 '19 at 13:20
  • How about multiple jars?? – mithun_ghose Jun 06 '20 at 06:27
  • ` true ` this is the main thing i believe – Danyal Sandeelo Oct 15 '21 at 11:23
  • This worked for me, had a jar library that is not available in a repository but only locally within a lib folder. This setup resolved the issue I was having and new machines/developers avoid the install:install issue. – fleed Oct 27 '21 at 17:08
12

Don't use systemPath. Contrary to what people have said here, you can put an external jar in a folder under your checked-out project directory and haven Maven find it like other dependencies. Here are two crucial steps:

  1. Use "mvn install:install-file" with -DlocalRepositoryPath.
  2. Configure a repository to point to that path in your POM.

It is fairly straightforward and you can find a step-by-step example here: http://randomizedsort.blogspot.com/2011/10/configuring-maven-to-use-local-library.html

Nehc
  • 121
  • 1
  • 2
11

Maven way to add non maven jars to maven project

Maven Project and non maven jars

Add the maven install plugins in your build section

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-install-plugin</artifactId>
        <version>${version.maven-install-plugin}</version>
        <executions>

            <execution>
                <id>install-external-non-maven1-jar</id>
                <phase>clean</phase>
                <configuration>
                    <repositoryLayout>default</repositoryLayout>
                    <groupId>jar1.group</groupId>
                    <artifactId>non-maven1</artifactId>
                    <version>${version.non-maven1}</version>
                    <file>${project.basedir}/libs/non-maven1.jar</file>
                    <packaging>jar</packaging>
                    <generatePom>true</generatePom>
                </configuration>
                <goals>
                    <goal>install-file</goal>
                </goals>
            </execution>
            <execution>
                <id>install-external-non-maven2-jar</id>
                <phase>clean</phase>
                <configuration>
                    <repositoryLayout>default</repositoryLayout>
                    <groupId>jar2.group</groupId>
                    <artifactId>non-maven2</artifactId>
                    <version>${version.non-maven2}</version>
                    <file>${project.basedir}/libs/non-maven2.jar</file>
                    <packaging>jar</packaging>
                    <generatePom>true</generatePom>
                </configuration>
                <goals>
                    <goal>install-file</goal>
                </goals>
            </execution>
            <execution>
                <id>install-external-non-maven3-jar</id>
                <phase>clean</phase>
                <configuration>
                    <repositoryLayout>default</repositoryLayout>
                    <groupId>jar3.group</groupId>
                    <artifactId>non-maven3</artifactId>
                    <version>${version.non-maven3}</version>
                    <file>${project.basedir}/libs/non-maven3.jar</file>
                    <packaging>jar</packaging>
                    <generatePom>true</generatePom>
                </configuration>
                <goals>
                    <goal>install-file</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

Add the dependency

<dependencies>
    <dependency>
        <groupId>jar1.group</groupId>
        <artifactId>non-maven1</artifactId>
        <version>${version.non-maven1}</version>
    </dependency>
    <dependency>
        <groupId>jar2.group</groupId>
        <artifactId>non-maven2</artifactId>
        <version>${version.non-maven2}</version>
    </dependency>
    <dependency>
        <groupId>jar3.group</groupId>
        <artifactId>non-maven3</artifactId>
        <version>${version.non-maven3}</version>
    </dependency>
</dependencies>

References Note I am the owner of the blog

craftsmannadeem
  • 2,665
  • 26
  • 22
  • How do u know the versions of the jars and of the maven install plugin? – osk Jan 19 '18 at 07:57
  • versions of the jars are just made up, maven install plugin versions is the latest – craftsmannadeem Jan 21 '18 at 17:20
  • I get could not resolve depedencies... for the corresponding jars It looks like the timing is wrong Does it really install the jars before it tries to resolve the dependencies? However I ran 'mvn clean package' – ka3ak Jan 28 '22 at 12:44
5

Change your systemPath.

<dependency>
  <groupId>stuff</groupId>
  <artifactId>library</artifactId>
  <version>1.0</version>
  <systemPath>${project.basedir}/MyLibrary.jar</systemPath>
  <scope>system</scope>
</dependency>
Aung Myat Hein
  • 4,018
  • 1
  • 36
  • 42
3

Note that all of the example that use

<repository>...</respository> 

require outer

<repositories>...</repositories> 

enclosing tags. It's not clear from some of the examples.

3

The pom.xml is going to look at your local repository to try and find the dependency that matches your artifact. Also you shouldn't really be using the system scope or systemPath attributes, these are normally reserved for things that are in the JDK and not the JRE

See this question for how to install maven artifacts.

Community
  • 1
  • 1
Tim Sparg
  • 3,294
  • 2
  • 27
  • 40
2

With Eclipse Oxygen you can do the below things:

  1. Place your libraries in WEB-INF/lib
  2. Project -> Configure Build Path -> Add Library -> Web App Library

Maven will take them when installing the project.

senderle
  • 145,869
  • 36
  • 209
  • 233
Rick
  • 21
  • 1
2

The best solution here is to install a repository: Nexus or Artifactory. If gives you a place to put things like this, and further it speeds things up by caching your stuff from the outside.

If the thing you are dealing with is open source, you might also consider putting in into central.

See the guide.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
0

If the external jar is created by a Maven project only then you can copy the entire project on your system and run a

mvn install

in the project directory. This will add the jar into .m2 directory which is local maven repository.

Now you can add the

<dependency>
     <groupId>copy-from-the=maven-pom-of-existing-project</groupId>
     <artifactId>copy-from-the=maven-pom-of-existing-project</artifactId>
     <version>copy-from-the=maven-pom-of-existing-project</version>
</dependency>

This will ensure that you

mvn exec:java 

works. If you use suggested here

<scope>system</scope>

Then you will have to add classes individually while using executing through command line.

You can add the external jars by the following command described here

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> \
-DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>
Bug Killer
  • 49
  • 7
0

The most efficient and cleanest way I have found to deal with this problem is by using Github Packages

  1. Create a simple empty public/private repository on GitHub as per your requirement whether you want your external jar to be publicly hosted or not.

  2. Run below maven command to deploy you external jar in above created github repository

    mvn deploy:deploy-file \ -DgroupId= your-group-id \ -DartifactId= your-artifact-id \ -Dversion= 1.0.0 -Dpackaging= jar -Dfile= path-to-file \ -DrepositoryId= id-to-map-on-server-section-of-settings.xml \ -Durl=https://maven.pkg.github.com/github-username/github-reponame-created-in-above-step

    Above command will deploy you external jar in GitHub repository mentioned in -Durl=. You can refer this link on How to deploy dependencies as GitHub Packages GitHub Package Deployment Tutorial

  3. After that you can add the dependency using groupId,artifactId and version mentioned in above step in maven pom.xml and run mvn install

  4. Maven will fetch the dependency of external jar from GitHub Packages registry and provide in your maven project.

  5. For this to work you will also need to configure you maven's settings.xml to fetch from GitHub Package registry.

Nitish Kumar
  • 721
  • 1
  • 10
  • 26