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
How to Assert That a Certain Exception Is Thrown in Junit Tests
How to Force Garbage Collection in Java
"Error: Main Method Not Found in Class Myclass, Please Define the Main Method As..."
Jcomponents Not Showing Up With Picture Background
How to Find All Subclasses of a Given Class in Java
Dates With No Time or Timezone Component in Java/MySQL
What Are Java Command Line Options to Set to Allow Jvm to Be Remotely Debugged
Wait For Page Load in Selenium
Java: Prefix/Postfix of Increment/Decrement Operators
Including Dependencies in a Jar With Maven
How to Lock a File Using Java (If Possible)
Nullpointerexception When Creating an Array of Objects
Javac Is Not Recognized as an Internal or External Command, Operable Program or Batch File
Which @Notnull Java Annotation Should I Use
Java: Date from Unix Timestamp