We have a private repository at work so once a while we need to download artifacts from the central repository and upload them.
Someone wrote a program a while ago for that which didn't always work perfectly: it would download all dependencies for each artifact separately, it would first scan the dependency tree and only then download them, it wouldn't download sources and javadocs, was slow, etc.
Recently I have come across this useful maven plugin called dependency and its goal get.
So now to download some artifact, let's say for instance com.sparkjava.spark-core:2.5.4, I would type on my terminal:
mvn dependency:get -Dartifact=com.sparkjava:spark-core:2.5.4
mvn dependency:get -Dartifact=com.sparkjava:spark-core:2.5.4:sources
mvn dependency:get -Dartifact=com.sparkjava:spark-core:2.5.4:javadoc
Which would download the artifact along with all its dependencies to the directory ~/.m2/repository which I can later transfer to our private repository.
This method works good but has 2 problems:
I have to run the command 3 times when each time the classifier is different and I would like to get all classifiers at once.
It always downloads the artifacts into ~/.m2/repository, which can sometime contain other artifacts I'm not intrested in having on the private repository. I need be able to choose another directory destination.
What can I do about these issues? About the first one I can work it around with an alias (which will still run the same command 3 times) but I have no idea what to do about the second issue and it's not mentioned on the plugin's documentation either.
To solve (2), you can update the settings.xml with a tag
<localRepository>C:\Users\my\custom\existing\directory</localRepository>
and make sure when you are building the project, the same settings.xml looked into which can be done using
mvn clean install -gs <pathToDirectory>
Note - Please modify the path accordingly.
To solve (1), adding the following to settings.xml should work as well -
<profiles>
<profile>
<id>downloadSources</id>
<properties>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>downloadSources</activeProfile>
</activeProfiles>
Source - Maven – Always download sources and javadocs
Other maven command that could help here is -
resolve command with classifier :
mvn dependency:resolve -Dclassifier=javadoc #downloads all the documentation
Related
This question already has answers here:
Add a dependency in Maven
(5 answers)
Closed 3 years ago.
My area of expertise is not Java. I develop in other languages on other platforms.
Right now I'm developing a series of Java servlets for a project. The servlets are to run on a CentOS server running FileNetP8.
I actually got all of the planned items finished and running.
Now when I am trying to add a few more services, the library I came across is available via Maven. I have no idea what Maven is. Read up on it today. Created a test project to try it out.
My development environment is Eclipse Photon on Windows 10.
Now my problem is I can't figure out how to add the Filenet JARs to the project. I can't upload them to some Maven repo. Searching the Web says to add them to the local repo, but I don't understand how to do that to the Local repo in Eclipse's builtin Maven.
I think that the JARs don't need to be packaged within the deployment WAR because the app will be deployed to the Websphere server that runs Filenet so they should be available on it. Should I add them as external JAR references to get the project to compile?
I provide below the following approaches to check based upon your suitability.
Approach-1: Install manually
If you have only 1 jar file, execute the following command by replacing as per your requirements.
mvn install:install-file \
-Dfile=<file path location> \
-DgroupId=<your own custom group id> \
-DartifactId=<your own custom artifact id> \
-Dversion=<some version number> \
-Dpackaging=jar \
-DgeneratePom=true
Once it is done, use the following in your project pom.xml in the dependency section.
<dependency>
<groupId>your own custom group id</groupId>
<artifactId>your own custom artifact id</artifactId>
<version>some version number</version>
</dependency>
The downside of the above approach is, only you can use it as it installs in your .m2 directory. For other developers, they have to follow the same approach. It is not a suggested approach.
Approach-2: Manually add the location of jar file
Add the following dependency in pom.xml
<dependency>
<groupId>some.group.id</groupId>
<artifactId>some.artifat.id</artifactId>
<version>some.version.no</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/yourActualJarFileName.jar</systemPath>
</dependency>
The downside of the above approach is, you have to put all the jar files in a directory and you have to provide the path. All the jar files should be part of your project, it means all the jar file should be put in source code repository. Although it servers the purposes, still it is not a good approach. If you got a newer/higher version of jar file, again you have to put it inside your lib directory. It means you have manage all the old and new versions of jar files.
Best Approach
Maintain Nexus or Artifactory, or any artifactory management system in the organisation and put all the jar files and provide the definition of your custom jar file. It will provide you pom definition. Based upon this, you have to add the dependencies in your project pom.xml. Here you can maintain n number version of your custom jar files.
Seeing as every answer involves maven i'll try to provide a different and somewhat old school approach. You could always import your jars directly into your project by right clicking on it -> properties -> Add Jars. Apply when done and Voilà. This is far easier than understanding the complexity of maven.
Dependencies need to be added in pom.xml under dependencies tag. Maven will download the specified jars from maven central repository for the first time, and it will be saved in your local repo.
If the dependencies are not available in central repo and if they have their own repo, you to need specify it in the repositories tag.
<repositories>
<repository>
<id>repo-id</id>
<name>repo-name</name>
<url>http://repourl</url>
</repository>
</repositories>
Any change in the pom.xml, maven will automatically download it.
<dependencies>
<dependency>
<groupId>dependency-id</groupId>
<artifactId>artifactid</artifactId>
<version>1</version>
</dependency>
</dependencies>
If the jars are available in Maven Central repo then all you hvae to do is add dependency under dependencies section in your pom.xml file. Set the scope as required, like you said jars don't needed to be packaged in WAR file as they might be available on server then you can set scope to provided.
<dependency>
<groupId>groud-id</groupId>
<artifactId>artifact-id</artifactId>
<version>version-numbe</version>
<scope>scope</scope>
</dependency>
If jars are not available in central repo and you want to install them on your local repo then below command should help you. More information here.
mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>
I have a project where I use Maven as the build tool.
In my pom.xml file I have these dependencies:
<dependency>
<groupId>com.my.group1</groupId>
<artifactId>MyArtifact1</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.my.group2</groupId>
<artifactId>MyArtifact2</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.my.group3</groupId>
<artifactId>MyArtifact3</artifactId>
<version>1.3</version>
</dependency>
Within the folder where I have my pom.xml, I also have a subfolder, \external. In this subfolder, I have the above listed artifacts as jars: MyArtifact1-1.0.jar, MyArtifact2-1.1.jar, MyArtifact3-1.3.jar.
The problem is that when I run mvn install, I get this:
[ERROR] Failed to execute goal on project my-project: Could not resolve dependencies for project com.my.group4:sample-project:jar:20161207.3: The following artifacts could not be resolved: com.my.group1:MyArtifact1:jar:1.0, com.my.group2:MyArtifact2:jar:1.1, com.my.group3:MyArtifact3:jar:1.3: Failure to find com.my.group1:MyArtifact1:jar:1.0 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced
So far, I tied running this:
mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=./external/MyArtifact1-1.0.jar -DgroupId=com.my.group1 -DartifactId=MyArtifact1 -Dversion=1.0 -Dpackaging=jar
I tried the above for all 3 packages, but still it looks like it didn't have any effect.
You are trying to include in the maven compilation .jar files you downloaded in your computer ?
Remember that Maven will try to get your dependencies from the local repository first (a folder in your computer) and from the global repositories later. If your dependencies (.jar) are not in those repositories, you will get an error message.
Here I give you some ideas/solutions:
If the .jar files resulted from other maven projects
If the .jar files are the product of other maven projects you created in your computer. You can install the outputs of that project in your local repository. Once they are installed, maven will find the dependencies locally.
// in the other projects
mvn clean install
If you have many local projects, you may setup your own maven repository to manage all your reusable components. Many companies setup their own repository in their local network. You can use software such as Artifactory
or Nexus Repository Manager. You can even built a repository using your filesystem. Note that, in order to use these repositories, you have to configure them in the pom.xml file of your project.
<project>
...
<repositories>
<repository>
<id>my-internal-site</id>
<url>http://myserver/repo</url>
</repository>
</repositories>
...
</project>
If the .jar files were downloaded from other websites
Sometimes you need .jar files that exist in global maven repositories. You may try first to search in these repositories. You can go to sites such as MVN repository to search or browse the existing packages in the repositories. If you find the dependencies you need, you can obtain too the required dependency to include in the pom.xml.
If the .jar files does not exist in any repository, you can install the file in your local repository. There is a tutorial in the Heroku's devcenter and another one in Mkyong. You must pick a groupId-artifactId-version for the file, install the file and add the dependency to the pom.xml of the project.
Note that, if the .jar was not created using maven, you must provide all the parameters
mvn install:install-file -Dfile=path-to-your-artifact-jar \
-DgroupId=your.groupId \
-DartifactId=your-artifactId \
-Dversion=version \
-Dpackaging=jar \
-DlocalRepositoryPath=path-to-specific-local-repo
If the .jar was generated with Maven, that file will include their own pom.xml with metadata. If you use Maven 2.5+, you do not need to provide the groupId-artifactId and version.
mvn install:install-file -Dfile=path-to-your-artifact-jar \
-DlocalRepositoryPath=path-to-specific-local-repo
There is another option. You can use the system scope with a local systemPath. However, I think this solution requires that people keep the library in the same location for all the developers, or requires to include the .jar file in the project/code repository. Using a repository is a better idea.
<dependency>
<artifactId>..</artifactId>
<groupId>..</groupId>
<scope>system</scope>
<systemPath>${basedir}/lib/dependency.jar</systemPath>
</dependency>
Please check whether these jars present in your local repository.
You can find it's location from your maven setting.xml file , if not mentioned there then it will take the default path i.e. .m2 folder inside c drive.
You need to check first whether these jars are present there or not. If not, then either you need to copy those in proper folder structure or you can install those jars on your local firing below command :
mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>
The recommended way is:
use a Maven Repository manager such as Nexus
configure Maven to use a Single Repository Group
configure proxy repos to other Maven Repositories as needed and add them to the group you specified in your settings file (see previous step)
if not already available, configure a repo for 3rd party libs in your repository manager and add it to the group you specified in your settings file (see previous step)
if your dependencies are not available from any repo, then add them to your 3rd party repo
remove all JARs from the source code
I have multiple maven projects, to add dependencies between them I just add it to the POM, for example :
<dependency>
<groupId>com.company</groupId>
<artifactId>XMLManagement</artifactId>
<version>1.0</version>
</dependency>
I am working with eclipse, and everything runs and works great until I try to release a jar.
**Problem1: ** Maven throws an error because it can't find the jars of the other maven projects it depends on in the local repository,
and this means that I have to figure out myself the dependencies between the projects, and go to each and every project in the right order and run "mvn clean install"
This does not seem logical since that is the main purpose of maven, there must be a way to tell maven to do it himself.
**Problem2: ** If project A depends on B that depends on C, and I want to use C in A then in eclipse its enough that I added B in the POM of A and it works, but when I run "mvn clean install" maven throws an error that it is missing dependency of C.
This means I have to add the dependency between A and C, which doesn't make sense because in eclipse I already see it under "Maven Dependencies", so if eclipse recognizes it why mvn clean install doesn't?
Note that I am able to produce the jar I need at the end, but only after a lot of hard work as described above.
I know I can use something like nexus or artifactory, but it's an overkill for me and I want to be able to do it in local repository.
I am looking for the proper way to do it, any suggestions?
What you need is a top-level pom that lists each of the things you want build as modules. In maven jargon, this is known as a reactor build.
Something like:
<groupId>this.that</groupId>
<artifactId>build.root</artifactId>
<name>A name</name>
<packaging>pom</packaging>
<modules>
<module>../a.b</module>
<module>../a.c</module>
Try this, find your file settings.xml configure path repository how:
<localRepository>E:\repositoryMavem</localRepository>
Hability your Eclipse (or IDE in use) for this file settings.xml
After go to path your project has pom.xml
run de command
mvn install:install-file -Dfile=E:\repositoryMavem\XMLManagement-1.0.jar -DgroupId=com.company -DartifactId=XMLManagement -Dversion=1.0 -Dpackaging=jar
if you want to use IDE Eclipse (you can).
if run clean for artifact, you need run install again
I have a project which I am attempting to install with maven. The pom.xml has a few properties in it which are modified when the maven install command is run depending on whatever version of a library we are attempting to build with:
<properties>
<some-version>0</some-version>
</properties>
The zero here is a placeholder, as we'll always specify a legitimate version during our build process. The version is then referenced later in the pom.xml to specify a few dependencies:
<dependencies>
<dependency>
<groupId>com.mycompany.myproduct</groupId>
<artifactId>someOtherProject</artifactId>
<version>${some-version}</version>
</dependency>
</dependencies
Building is done via make with the following commandline:
mvn -Dsome-version=1.6.2
Maven is able to correctly resolve the version and build as expected. However, the version being installed in my local maven repository (/home/user/.m2) doesn't have the correct version. The pom.xml that is installed does not have the updated version I set in the command line:
user#ubuntu:~/$ cat /home/user/.m2/repository/com/mycompany/myproduct/myproject/1.0.0/myproject-1.0.0.pom | grep some-version -C 1
<properties>
<some-version>0</some-version>
</properties>
--
<artifactId>someOtherProject</artifactId>
<version>${some-version}</version>
</dependency>
user#ubuntu:~/$
This is preventing any other project which depends on myproject from being able to build, as maven will complain that it can't find version 0 of someOtherProject:
[ERROR] Failed to execute goal on project myproject:
Could not resolve dependencies for project mycompany.myproduct:myproject:jar:1.0.0:
The following artifacts could not be resolved: com.mycompany.myproduct:someOtherProject:jar:0,
Could not find artifact com.mycompany.myproduct:someOtherProject:jar:0 in central (https://mycompany.com/artifactory/repo/) -> [Help 1]
What do I need to do for maven to install with the updated version in the pom? Obviously a terrible hackish solution would be to use sed and modify the pom file directly, but it seems that Maven should be able to actually leverage the command line settings when installing the pom. Otherwise the ability to set arguments on the command line seems remarkably limited in effectiveness.
Better you may set your property in pom.xml in <properties> tag like this -
<properties>
<property>
<name>some-version</name>
<value>1.6.2</value>
</property>
</properties>
If you use this then you don't have to provide the property each time you issue a mvn command from terminal.
mvn -Dsome-version=1.6.2 works as a substitution value for the scope of building than replacing the original POM with the new values. Hence is the behavior you see. I am not aware of any maven support to do so.
Under #JoopEggen's advice, I looked deeper into the maven versions plugin. It offered an update-property target which will actually update the pom.xml value on disk, rather than just passing in an overwrite during the build phase. I was able to solve my issue by calling
mvn versions:update-property -Dproperty=some-version -DnewVersion=1.6.2 -DsearchReactor=false -DallowSnapshots=true
in the makefile before calling mvn install. Disabling the reactor was necessary to prevent the plugin from rejecting values it couldn't find in the remote repo (see here), and allowSnapshots allows me to use version numbers such as 1.6.2-SNAPSHOT, useful when testing.
in my J2EE project I've a couple of dependencies, which are not available in any Maven repository, because they're proprietary libraries. These libraries need to be available at runtime, so that have to be copied to target/.../WEB-INF/lib ...
Right now, I'm listing them as system dependency in my POM, but with this method the problem is, that aren't being copied to the target build during compilation. Also this method is not very elegant.
So which is the best way to integrate them in Maven?
Note: I don't want to create my own Maven repository.
For people wanting a quick solution to this problem:
<dependency>
<groupId>LIB_NAME</groupId>
<artifactId>LIB_NAME</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${basedir}/WebContent/WEB-INF/lib/YOUR_LIB.jar</systemPath>
</dependency>
just give your library a unique groupID and artifact name and point to where it is in the file system. You are good to go.
Of course this is a dirty quick fix that will ONLY work on your machine and if you don't change the path to the libs. But some times, that's all you want, to run and do a few tests.
EDIT: just re-red the question and realised the user was already using my solution as a temporary fix. I'll leave my answer as a quick help for others that come to this question. If anyone disagrees with this please leave me a comment. :)
As you've said you don't want to set up your own repository, perhaps this will help.
You can use the install-file goal of the maven-install-plugin to install a file to the local repository. If you create a script with a Maven invocation for each file and keep it alongside the jars, you (and anyone else with access) can easily install the jars (and associated pom files) to their local repository.
For example:
mvn install:install-file -Dfile=/usr/jars/foo.jar -DpomFile=/usr/jars/foo.pom
mvn install:install-file -Dfile=/usr/jars/bar.jar -DpomFile=/usr/jars/bar.pom
or just
mvn install:install-file -Dfile=ojdbc14.jar -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=10.2.0 -Dpackaging=jar
You can then reference the dependencies as normal in your project.
However your best bet is still to set up an internal remote repository and I'd recommend using Nexus myself. It can run on your development box if needed, and the overhead is minimal.
Create a repository folder under your project. Let's take
${project.basedir}/src/main/resources/repo
Then, install your custom jar to this repo:
mvn install:install-file -Dfile=[FILE_PATH] \
-DgroupId=[GROUP] -DartifactId=[ARTIFACT] -Dversion=[VERS] \
-Dpackaging=jar -DlocalRepositoryPath=[REPO_DIR]
Lastly, add the following repo and dependency definitions to the projects pom.xml:
<repositories>
<repository>
<id>project-repo</id>
<url>file://${project.basedir}/src/main/resources/repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>[GROUP]</groupId>
<artifactId>[ARTIFACT]</artifactId>
<version>[VERS]</version>
</dependency>
</dependencies>
You need to set up a local repository that will host such libraries. There are a number of projects that do exactly that. For example Artifactory.
None of the solutions work if you are using Jenkins build!! When pom is run inside Jenkins build server.. these solutions will fail, as Jenkins run pom will try to download these files from enterprise repository.
Copy jars under src/main/resources/lib (create lib folder). These will be part of your project and go all the way to deployment server. In deployment server, make sure your startup scripts contain src/main/resources/lib/* in classpath. Viola.
you can install them in a private, local repository (e.g. .m2/repository under your home directory): more details here
If I am understanding well, if what you want to do is to export dependencies during the compilation phase so there will be no need to retrieve manually each needed libraries, you can use the mojo copy-dependencies.
Hope it can be useful in your case (examples)
#Ric Jafe's solution is what worked for me.
This is exactly what I was looking for. A way to push it through for research test code. Nothing fancy. Yeah I know that that's what they all say :) The various maven plugin solutions seem to be overkill for my purposes. I have some jars that were given to me as 3rd party libs with a pom file. I want it to compile/run quickly. This solution which I trivially adapted to python worked wonders for me. Cut and pasted into my pom. Python/Perl code for this task is in this Q&A: Can I add jars to maven 2 build classpath without installing them?
def AddJars(jarList):
s1 = ''
for elem in jarList:
s1+= """
<dependency>
<groupId>local.dummy</groupId>
<artifactId>%s</artifactId>
<version>0.0.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/manual_jars/%s</systemPath>
</dependency>\n"""%(elem, elem)
return s1
Continue to use them as a system dependency and copy them over to target/.../WEB-INF/lib ... using the Maven dependency plugin:
http://maven.apache.org/plugins/maven-dependency-plugin/examples/copying-artifacts.html
Install alone didn't work for me.
mvn deploy:deploy-file -Durl=file:///home/me/project/lib/ \
-Dfile=target/jzmq-2.1.3-SNAPSHOT.jar -DgroupId=org.zeromq \
-DartifactId=zeromq -Dpackaging=jar -Dversion=2.1.3