Maven: Add a Dependency to a Jar by Relative Path

Maven: add a dependency to a jar by relative path

I want the jar to be in a 3rdparty lib in source control, and link to it by relative path from the pom.xml file.

If you really want this (understand, if you can't use a corporate repository), then my advice would be to use a "file repository" local to the project and to not use a system scoped dependency. The system scoped should be avoided, such dependencies don't work well in many situation (e.g. in assembly), they cause more troubles than benefits.

So, instead, declare a repository local to the project:

<repositories>
<repository>
<id>my-local-repo</id>
<url>file://${project.basedir}/my-repo</url>
</repository>
</repositories>

Install your third party lib in there using install:install-file with the localRepositoryPath parameter:

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<myGroup> \ 
-DartifactId=<myArtifactId> -Dversion=<myVersion> \
-Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

Update: It appears that install:install-file ignores the localRepositoryPath when using the version 2.2 of the plugin. However, it works with version 2.3 and later of the plugin. So use the fully qualified name of the plugin to specify the version:

mvn org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file \
-Dfile=<path-to-file> -DgroupId=<myGroup> \
-DartifactId=<myArtifactId> -Dversion=<myVersion> \
-Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

maven-install-plugin documentation

Finally, declare it like any other dependency (but without the system scope):

<dependency>
<groupId>your.group.id</groupId>
<artifactId>3rdparty</artifactId>
<version>X.Y.Z</version>
</dependency>

This is IMHO a better solution than using a system scope as your dependency will be treated like a good citizen (e.g. it will be included in an assembly and so on).

Now, I have to mention that the "right way" to deal with this situation in a corporate environment (maybe not the case here) would be to use a corporate repository.

How to add local jar files to a Maven project?

Install the JAR into your local Maven repository (typically .m2 in your home folder) as follows:

mvn install:install-file \
-Dfile=<path-to-file> \
-DgroupId=<group-id> \
-DartifactId=<artifact-id> \
-Dversion=<version> \
-Dpackaging=<packaging> \
-DgeneratePom=true

Where each refers to:

<path-to-file>: the path to the file to load e.g → c:\kaptcha-2.3.jar

<group-id>: the group that the file should be registered under e.g → com.google.code

<artifact-id>: the artifact name for the file e.g → kaptcha

<version>: the version of the file e.g → 2.3

<packaging>: the packaging of the file e.g. → jar

Reference

  • Maven FAQ: I have a jar that I want to put into my local repository. How can I copy it in?
  • Maven Install Plugin Usage: The install:install-file goal

Can I add a directory containing a jar and its dependant jars as a maven dependency?

Install all the dependencies mentioned in the manifest file that are available from public maven repositories directly from there as mentioned by @Christian Schneider. Those that are not available can be installed manually to a project-local maven repository in the project scope. To do this, define the in-project maven repository in your parent pom.xml file:

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

Then install the library some.library.jar and the dependencies listed in the manifest that are not openly available to the in-project repository:

mvn install:install-file \
-Dfile=path/to/some-library-1.2.3.jar \
-DgroupId=com.example \
-DartifactId=some-library \
-Dversion=1.2.3 \
-Dpackaging=jar \
-DlocalRepositoryPath=lib \
-DcreateChecksum=true

This will then generate the structure in your local maven repo (lib) and also generate the checksums for maven.

Maven get relative path of dependency

This is a bad idea and is poor practice when it comes to Maven dependencies.

First and foremost, your projects will always need to be relatively locateable to one another, which means that your build environment will have to have them together. This translates to builds which may not be repeatable because there is absolutely no guarantee that the second project would not have changed between builds of the first project.

Second, the conventional way to combine multiple related projects is to have subprojects instead. This way you can have your first project depend on your second project without any headaches.

Failing any of that, then the best alternative is to publish the second project to your local m2 repository or your repository store, and pulling it down in your first project.

Is there a way to create maven dependency in pom file from a local jar

This code

    public static void main(String[] args) throws IOException {
Set<String> missingMavenData = new HashSet<String>();
String FOLDER = "/path/to/your/folder/with/jars";

Files
.walk(Paths.get(FOLDER), FileVisitOption.FOLLOW_LINKS)
.map(Path::toFile)
.filter(f -> f.isFile())
.filter(f -> f.getName().endsWith(".jar"))
.map(f -> {
try {
return new JarFile(f);
} catch (IOException e) {
e.printStackTrace();
return null;
}
})
.filter(Objects::nonNull)
.map(jar -> {
Properties properties = null;
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
if (jarEntry.getName().matches("^META-INF/maven/.*/pom\\.properties$")) {
try {
properties = new Properties();
properties.load(jar.getInputStream(jarEntry));
break;
} catch (IOException e) {
e.printStackTrace();
}
};
}
if (properties == null) {
missingMavenData.add(jar.getName());
}
return properties;
})
.filter(Objects::nonNull)
.forEach(properties -> {
System.out.println("< dependency>");
System.out.println(" <groupId>" + properties.getProperty("groupId")+ "</groupId>");
System.out.println(" <artifactId>" + properties.getProperty("artifactId")+ "</artifactId>");
System.out.println(" <version>" + properties.getProperty("version")+ "</version>");
System.out.println("</dependency>");
});

System.out.println("Those JAR files do not contain Maven metadata:");
missingMavenData.forEach(System.out::println);
}

will iterate over your jar files and try to find the Maven metadata in them. It will generate the POM entries for those who have it and will list those that don't have it so you can add it manually. I hope this helps.

UPDATE:

I added bom-helper:fromJars goal to BOM Helper Maven Plugin which does more or less the same thing as the above code. One can now simply add the plugin

<plugin>
<groupId>com.commsen.maven</groupId>
<artifactId>bom-helper-maven-plugin</artifactId>
<version>0.2.0</version>
</plugin>

and configure it to call fromJars goal. It can also be called form command line. For example:

mvn bom-helper:fromJars \
-Dbom-helper.jarsFolder=/path/to/folder/with/jars \
-Dbom-helper.inplace=true \
-Dbom-helper.recursive

will update current pom with entries for all jars that have Maven metadata in them.

IntelliJ add external jar as dependency from relative path

If the library is inside the project root, the path will be stored relatively using the placeholder.

In the library .xml file or in the project .iml file you'll see something like this:

<component name="libraryTable">
<library name="log4j-1.2.17">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/log4j-1.2.17.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

Maven: best way of linking custom external JAR to my project?

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.



Related Topics



Leave a reply



Submit