Summary
When using maven-install-plugin:install-file to install maven jar package all dependencies are ignored and this plugin write a dumb/broken pom file.
Context
I have a local Maven package jar file foo-java-1.2.3.jar which contains its own pom.xml in META-INF/maven/org.mizux.foo/foo-java/pom.xml with few dependencies
<dependencies>
<dependency>
<groupId>org.mizux.foo</groupId>
<artifactId>foo-linux-x86-64</artifactId>
<version>1.2.3</version>
<type>jar</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.12.2</version>
</dependency>
</dependencies>
Then, I tried to install it locally using:
mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=foo-java.1.2.3.jar
mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=foo-linux-x86-64.1.2.3.jar
ref: https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html
note: net.java.dev.jna:jna-platform and com.google.protobuf:protobuf-java can be found on maven central...
Then when using it in a Bar project pom.xml:
...
<dependencies>
<dependency>
<groupId>org.mizux.foo</groupId>
<artifactId>foo-java</artifactId>
<version>1.2.3</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
while mvn compile pass ?
I can't run my Bar's main since all transitive dependencies of foo-java are not passed to Bar so I got some java.lang.NoClassDefFoundError
mvn exec:java -Dexec.mainClass="org.mizux.bar.Test"
...
java.lang.NoClassDefFoundError: com/sun/jna/Platform
Looking at ~/.m2/repository/org/mizux/foo/foo-java/1.2.3/foo-java-1.2.3.pom this one seems to only contains the minimum (groupID, artifactID...) but the whole dependencies part is not present !!
questions:
How I can install local maven jar package so the pom installed is the full one and not a truncated version.
Why install plugin generate this dummy pom while the complete one is present inside the jar artifact ?
note: When using mvn install on a local build of foo-java the pom exported in .m2 is vastly different i.e. it's a copy of the foo-java original pom.xml !
i.e.
%diff ~/.m2/repository/org/mizux/foo/foo-java/1.2.3/foo-java-1.2.3.pom .../foo-java/pom.xml
note2: here a github project to reproduce the issue
https://github.com/Mizux/java-ortools you can take a look at action to see a full log https://github.com/Mizux/java-ortools/actions on linux/macos/windows and a docker ubuntu container
Why install plugin generate this dummy pom while the complete one is present inside the jar artifact ?
According to the doc
Generate a minimal POM for the artifact if none is supplied via the parameter pomFile. Defaults to true if there is no existing POM in the local repository yet.
ref: https://maven.apache.org/plugins/maven-install-plugin/install-file-mojo.html#generatePom
Now I don't know if we can force the maven-install-plugin to copy the pom.xml present in the jar file itself (ed which is already parsed by the plugin !!!)
Ugly workaround
I could extract the pom.xml from the .jar file (which contains it!) then pass it along the jar in the install-file command.
unzip -j foo-java-1.2.3.jar META-INF/maven/org.mizux.foo/foo-java/pom.xml
mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file \
-Dfile=foo-java-1.2.3.jar -DpomFile=pom.xml
mvn compile
mvn exec:java -Dexec.mainClass="org.mizux.bar.Bar"
Since the feature you are expecting does not work:
Either use the latest version of the plugin (3.0.0-M1) to see if this is fixed
Either run maven in debug (mvnDebug -X) and place a break point in the line below; for all that matters, your JAR file is probably broken.
At the point where JAR entries are matched
Where the JAR entries are processed
Since you will have to debug in your IDE, you may also want to clone the GIT repository and switch to the tag as to match the version of the plugin you use.
Either extract the pom manually and pass it.
Related
Maven has repositories and dependecies. Some plugins allow to use s3 or github as repository. But is there something to use direct URL? Like:
<dependency>
<groupId>my-group-id</groupId>
<artifactId>artifact-id</artifactId>
<version>some-version</version>
<url>https:someurl</url>
</dependency>
May be define URL and dependency info (group and artifact) in properties and for it installed during some maven phase.
Is it possible?
No.
Maven resolves dependencies from Maven repositories. So you cannot just add a JAR that is present at some URL. The JAR has to come from a Maven repository and (if it is not MavenCentral or already specified in your settings.xml or POM), you need to add it.
Yes this is officially supported but not in as convenient a mechanism as you perhaps desire.
Maven resolves dependencies against your local repository. If it can't find them there, it then tries to resolve them against any remote repositories you have configured.
Therefore, if you manually install the jar into your local repository, Maven will find it and use it.
To do this you must:
Download the jar
You have to do this yourself manually or automate the process e.g. using curl or wget
Specify the Maven Install Plugin version in your pom
You are going to be relying on the Maven Install Plugin so you should install you specify the version in your pom.xml, rather than relying on the default version.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
</plugins>
</build>
Install the jar to your local repo
If the jar has been built with Maven, then it will include a pom.xml inside it. If you are unsure, open the jar with any archive manager and look inside the directory /META-INF/maven. You should find another directory named after the group ID, then another for the artifact ID, and then finally the pom.xml itself.
If the pom.xml is included, you can just run this and the tool will read the pom.xml to find the group ID and artifact ID so it can be placed in the right location in your repository:
mvn install:install-file -Dfile=/path/to/downloaded.jar
If the pom.xml is not included, you will need to specify all of this information yourself. It does not matter what you choose but you should choose something that isn't going to confuse you later:
mvn install:install-file -Dfile=/path/to/downloaded.jar -DgroupId=my-group-id -DartifactId=artifact-id -Dversion=some-version -Dpackaging=jar
Update your pom.xml
You can now just reference the dependency as normal in your pom.xml:
<dependency>
<groupId>my-group-id</groupId>
<artifactId>artifact-id</artifactId>
<version>some-version</version>
</dependency>
I can't compile the files directly. I use mvn package.
I can't run the files directly. I use storm (Apache).
I don't know much about Maven.
I tried to just put the .jar in the same folder as the code and use import com.path.of.jar. It did compile, but when I tried to run, gave a NoClassDefFoundError.
Try this way to add dependencies directly, like this:
<dependency>
<groupId>sample</groupId>
<artifactId>com.sample</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/yourJar.jar</systemPath>
</dependency>
When you work on a maven based project, you manage dependencies through the pom.xml file at the root of the project. POM stands for Project Object Model and contains information about the project and configuration details used by Maven to build the project (Introduction to the POM).
A maven project produces an artifact uniquely identified by its coordinates: The <groupId>, <artifactId> and <version> that you normally find at the top of your pom.xml file. Once an artifact is published to a repository other maven projects can depend on it.
If you look at the content of your POM file you should see a <dependencies> element containing all dependencies that your project needs. If you want to import classes from a jar in your code you will need to find the maven coordinates of this jar (for example on search.maven.org or mvnrepository.com).
Once you have the coordinates add a corresponding dependency section. It should look like this:
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
Next time you run mvn package, the jar will be downloaded, used during compilation and packaged with your artifact.
And if you would like to get a good understanding of maven the following free book is excellent: Maven: The Complete Reference
I have imported a Maven Project in Eclipse (EE Developer) and I have in my pom.xml file the following error, “Missing artifact com.oracle:ojdbc7:jar:12.1.0.2″ in this code:
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
I have done so by downloading the ojdbc7.jar and run this command:
mvn install:install-file -Dfile=/Path-to-jar/ojdbc7.jar
-DgroupId=com.oracle
-DartifactId=ojdbc7
-Dversion=12.1.0.2
-Dpackaging=jar
-DgeneratePom=true
After that, I got as an output BUILD SUCCESS, and if I go to the .m2 folder I see in the com->oracle->ojdbc7 two files called “ojdbc7-12.1.0.1.jar.lastUpdated” and “ojdbc7-12.1.0.1.pom.lastUpdated” but still Eclipse brings me the code into the pom.xml file as an error?!?!?!
Can some one help?
This artifact version (12.1.0.2) has been removed to an another dependency.
See: https://mvnrepository.com/artifact/com.oracle/ojdbc7
Try to change the new dependency:
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
</dependency>
After successfully running the "mvn install" command right click your Project -> Maven -> Update Project (or Alt+F5).
I would get rid of those 2 files manually (lastUpdated) then re-run your install command and finally build your project. Those 2 files have been created by mvn as flags to avoid refetching them for a certain amount of time. They certainly have been created prior to your manual install-file command.
I recommend you to follow the instruction given in this link.
"http://javabycode.com/build-tools/maven/add-oracle-jdbc-driver-maven.html"
As per your dependency in pom.xml there should be 4 files generated inside "m2repo\com\oracle\ojdbc7\12.1.0.2" folder.
ojdbc7-12.1.0.2.jar
ojdbc7-12.1.0.2.jar.lastUpdated
ojdbc7-12.1.0.2.pom
ojdbc7-12.1.0.2.pom.lastUpdated
But as you are saying you checked for "ojdbc7-12.1.0.1.jar.lastUpdated", that should not be the case. I recommend you to delete your dependency folder and then start from scratch.
Some how the jar is not getting downloaded into the local pc. I opened the maven site https://mvnrepository.com/artifact/com.oracle/ojdbc7/12.1.0.2 and downloaded the required jar and placed it in to the .m2 folder, and the error is gone.
I just needed to use a 3rd party JAR in my project and deployed the JAR in my local maven repo. I followed these steps while doing this:
->Runned the belowed statement:
mvn install:install-file -Dfile=c:\DEVEL\gsa-japi-src-1.3.jar -DgroupId=net.sf.gsaapi
-DartifactId=gsaapi -Dversion=1.3 -Dpackaging=jar
->I saw "BUILD SUCCESSFUL" message, checked local repo files and it seemed the deployment was succesfull.
->After installed and deployed, i just added following statements in pom.xml file.
<dependency>
<groupId>net.sf.gsaapi</groupId>
<artifactId>gsaapi</artifactId>
<version>1.3</version>
</dependency>
But I still can not reach the library's methods. Am I missing something?
gsa-japi-src-1.3.jar contains only source files (.java) and apidocs. You need a jar with .class files
Correct dependency is:
<dependency>
<groupId>net.sf.gsaapi</groupId>
<artifactId>gsa-japi-src</artifactId>
<version>1.3</version>
</dependency>
You have installed JAR use net.sf.gsaapi:gsaapi artifact identifier but in dependency you are using com.google.code:kaptcha. So, you should use the same artifact identifier in dependencies.
How do I take a jar file that I have and add it to the dependency system in maven 2? I will be the maintainer of this dependency and my code needs this jar in the class path so that it will compile.
You'll have to do this in two steps:
1. Give your JAR a groupId, artifactId and version and add it to your repository.
If you don't have an internal repository, and you're just trying to add your JAR to your local repository, you can install it as follows, using any arbitrary groupId/artifactIds:
mvn install:install-file -DgroupId=com.stackoverflow... -DartifactId=yourartifactid... -Dversion=1.0 -Dpackaging=jar -Dfile=/path/to/jarfile
You can also deploy it to your internal repository if you have one, and want to make this available to other developers in your organization. I just use my repository's web based interface to add artifacts, but you should be able to accomplish the same thing using mvn deploy:deploy-file ....
2. Update dependent projects to reference this JAR.
Then update the dependency in the pom.xml of the projects that use the JAR by adding the following to the element:
<dependencies>
...
<dependency>
<groupId>com.stackoverflow...</groupId>
<artifactId>artifactId...</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
You can also specify a dependency not in a maven repository. Could be usefull when no central maven repository for your team exist or if you have a CI server
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>commons-utils</artifactId>
<version>1.3</version>
<scope>system</scope>
<systemPath>${basedir}/lib/commons-utils.jar</systemPath>
</dependency>
Actually, on investigating this, I think all these answers are incorrect. Your question is misleading because of our level of understanding of maven. And I say our because I'm just getting introduced to maven.
In Eclipse, when you want to add a jar file to your project, normally you download the jar manually and then drop it into the lib directory. With maven, you don't do it this way. Here's what you do:
Go to mvnrepository
Search for the library you want to add
Copy the dependency statement into your pom.xml
rebuild via mvn
Now, maven will connect and download the jar along with the list of dependencies, and automatically resolve any additional dependencies that jar may have had. So if the jar also needed commons-logging, that will be downloaded as well.
I'd do this:
add the dependency as you like in your pom:
<dependency>
<groupId>com.stackoverflow...</groupId>
<artifactId>artifactId...</artifactId>
<version>1.0</version>
</dependency>
run mvn install it will try to download the jar and fail. On the process, it
will give you the complete command of installing the jar with the error message. Copy that command and run it! easy huh?!
I'll assume that you're asking how to push a dependency out to a "well-known repository," and not simply asking how to update your POM.
If yes, then this is what you want to read.
And for anyone looking to set up an internal repository server, look here (half of the problem with using Maven 2 is finding the docs)