Maven install-file won't generate pom.xml - maven-2

I've installed some third party jars to my repository using the following command:
mvn install:install-file -Dfile=/home/anotherCoder/Downloads/nifty-1.0.jar -DgroupId=nifty-gui -DartifactId=nifty-gui -Dversion=1.0 -Dpackaging=jar
However, once I do mvn compile, maven complains that there is no pom file in the repository and attempts to download it, but can't cause it is not published at any remote repository.
Here is the exact message from maven:
Downloading: http://repo1.maven.org/maven2/nifty-gui/nifty-gui/1.0/nifty-gui-1.0.pom
[INFO] Unable to find resource 'nifty-gui:nifty-gui:pom:1.0' in repository central (http://repo1.maven.org/maven2)
So how do I get maven to generate a pom file for that jar and put it in my local repository?

You tell it to! :-)
mvn install:install-file
-Dfile=/home/anotherCoder/Downloads/nifty-1.0.jar
-DgroupId=nifty-gui
-DartifactId=nifty-gui
-Dversion=1.0
-Dpackaging=jar
-DgeneratePom=true
(Command placed on multiple lines so you can easily see the last parameter.)
Nice, huh? In the future you can go to a plug-in's documentation, view its goals, and you can see all the parameters it accepts. For example, the install-file goal.
Edit:
Regarding the question of the default behavior of the generatePom flag, the documentation indicates it defaults to true, and the code appears to support that. However, using Maven 2.0.9 with the maven-install-plugin version 2.2 (both versions are slightly out of date), it does not generate a POM. So, perhaps incrementing the version(s) will allow the default to work.
> touch DeleteMe.jar
> mvn install:install-file -DgroupId=Delete -DartifactId=Me -Dversion=0.0.0 -Dpackaging=jar -Dfile=DeleteMe.jar
...
[INFO] BUILD SUCCESSFUL
...
> ls ~/.m2/repository/Delete/Me/0.0.0/
Me-0.0.0.jar
(No generated POM.)

The install:install-file goal has an optional parameter generatePom (since version 2.1) that allows to:
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.
This parameter defaults to true since version 2.3 (and false in 2.1, 2.2). So if you're using a version of the install plugin prior to 2.3, you'll have to pass the parameter in the command.
Just in case, the syntax to explicitly use the version 2.3 of the install plugin would be:
mvn org.apache.maven.plugins:maven-install-plugin:2.3:install-file \
-Dfile=/home/anotherCoder/Downloads/nifty-1.0.jar -DgroupId=nifty-gui \
-DartifactId=nifty-gui -Dversion=1.0 -Dpackaging=jar

I had the same issue I think as you, I had a shell script using the install:install-file goal like this:
mvn -o install:install-file -e
-DgroupId=org.jfree.jcommon
-DartifactId=jcommon
-Dversion=1.0.15
-Dpackaging=jar
-Dfile=jcommon-1.0.15.jar
Couple of things to note:
artifactId cannot contain '.' ... not sure why but the install would fail if this contained '.'
Running the above command only generated a pom with maven 3.x. By adding the following arguments, I was able to get the jar's to be copied:
-DgeneratePom=true -DupdateReleaseInfo=true

Well and in case your third party library really is "nifty gui" all you need to do is to add the nifty maven repository to your pom.xml:
<repositories>
<repository>
<id>nifty-maven-repo.sourceforge.net</id>
<url>http://nifty-gui.sourceforge.net/nifty-maven-repo</url>
</repository>
</repositories>
and your maven project will automatically download nifty :D
PS: I know that this was not your actual question but it might help with nifty integration :)

Related

How can I create local Maven repository for my own libraries?

I need to have my own libraries in Maven repository, and I only need these my own libraries (about 2-7 libs). Is it possible to copy these jars to some local folder and then use that as repository in Maven?
Assuming these libraries only need to be available for your local build, you can just install them in to your repo from the cmd line:
mvn install:install-file -DgroupId=<your_group_name> -DartifactId=<your_artifact_name> -Dversion=<snapshot> -Dfile=<path_to_your_jar_file> -Dpackaging=jar -DgeneratePom=true
You can use any artefact/group/version you likr - but these then need to be used in your pom when listing the dependency

Building Products with Maven

I'm fairly new to Maven and I'd like to use it to build a multi-module project.
Lets assume I have the following svn repository structure:
- /trunk/common-services/login-service
(.jar) [re-usable components]
- /trunk/services/mybusiness-service
(.jar)
- /trunk/webservices/mybusiness-rest
(.war)
- /trunk/products/myproduct
(pom) [issue mvn command here]
What I'd like to be able to do is to checkout and build the entire "product" from a single pom using a single mvn command (from a developers pov as well as a CI pov). It's safe to assume that I have the trunk checked out.
How do I do this using Maven? I've looked at the Maven reactor plugin, but I can't figure out how to use it correctly (if it is the correct plugin to use).
The reactor plugin assumes each module has its pom.xml.
For your use case, you would want to create a pom.xml for each module (login-service, mybusiness-service and mybusiness-rest). You would specify the dependencies in each of the modules. For instance, if your mybusiness-rest depends on login-service and mybusiness-service, you would specify these projects as dependencies.
You would have a pom.xml in /trunk which specifies each of the modules to be built. You can use the reactor features in this pom.xml to determine, when to build (or not build) specific modules.
Your developers and CI can build using this single pom.

Using Maven ant task to install jar to local repository

At the end of my ant build id like it to call the equivalent of the command line call
mvn install:install-file -Dfile=my.jar -DgroupId=com.company.project -DartifactId=my_project -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true
so that it will add the newly built jar to a maven repository which another project will rely on.
Ive tried using the maven-ant-task and have added the maven-ant-task jar to the ant built project and the following code to the build.xml:
<target name ="minstall" depends="jar">
<artifact:pom id="maven_install" file="maven_install.xml" />
<artifact:install file="${out.dir}/my_project.jar">
<pom refid="maven_install"/>
</artifact:install>
</target>
but seem to be missing something as it wont work for me. To begin with i get the error in the build.xml (ant build file) saying
The prefix "artifact" for element "artifact:pom" is not bound.
What am I doing wrong. I am fairly new to ant?
On a realted question what is the purpose of the associated POM file? I would not normally have a POM in this project as it is an ant build
Perhaps maven-ant-task jar is not installed, i.e. not in your ant CLASSPATH. You can follow this instruction for this.
As mentioned previously, you need to make sure the tasks are defined in your ant script, and the artifact namespace is understood.
The POM file is used (in this case) to tell the Maven repositories the dependencies of the JAR you are putting in the repository. The POM should also specify the JAR's identification information (groupId, artifactId, version number, license, etc.).
Strictly speaking, you do not need an external POM, you could define the information in your build.xml file as follows:
<!-- Assuming tasks defined, and 'artifact' namespace exists -->
<artifact:pom id="maven_install" groupId="com.whatever" artifactId="some-jar"
version="1.0" packaging="jar">
<dependency groupId="..." artifactId="..." version="..."/>
<dependency groupId="..." artifactId="..." version="..."/>
<license name="apache" url="http://www.apache.org"/> <!-- can be omitted -->
</artifact:pom>
<target name ="minstall" depends="jar">
<artifact:install file="${out.dir}/my_project.jar" pomRefId="maven_install"/>
</target>
When you install the JAR in the 'minstall' task, the POM should be generated with the appropriate dependencies in the local Repository.
That message means you are missing an xmlns:artifact attribute in your build.xml. Have a look at the installation page in the docs for an example.
As to the purpose of the POM file, it's mostly metadata so that maven can figure out dependencies properly. In a real maven build it also describes how to build, test and package. But in your case all that is done by ant instead.
I think that it makes no sense to put such commands in Ant's build.xml. If you want to have your jar file installed in your maven repo just use mvn install command.
Besides that, I guess that you are somehow confusing the purpose of Maven and Ant tools in your project. What I'd suggest is to use Maven as your main build tool. You can configure invokation of Ant targets in your POM file if you really need that. Personally, I think it is the best solution to have Ant called by Maven. Maven goals (such as clean, test, package, install and so on) are very simple to use and powerful (I guess that you can read it in every Maven tutorial).

A simple command line to download a remote maven2 artifact to the local repository?

I have a library that I distribute using maven 2. The typical user of this library doesn't use maven to build their applications, but is likely somewhat familiar with maven and probably has it installed.
I'd like to document a "simple" one line command they can use to download my library's artifacts to their local ~/.m2/repository without requiring that they set up a pom.xml to do it.
I thought there was a way to do this, but I can't seem to find it after looking through the install:install-file and dependency plugin documentation. I tried things like:
mvn install:install-file -DrepositoryId=java.net -Durl=http://download.java.net/maven/2/ -Dfile=robo-guice-0.4-20091121.174618-1.jar -DpomFile=robo-guice-0.4-20091121.174618-1.pom -DgroupId=robo-guice -DartifactId=robo-guice -Dversion=0.4-SNAPSHOT -Dpackaging=jar
but I think I'm barking up the wrong tree since it appears that the install plugin is used to copy locally built files into the local repository, rather than download remote artifacts into the local repository.
This is the artifact I'd like to install: http://download.java.net/maven/2/robo-guice/robo-guice/0.4-SNAPSHOT/
Is this possible using maven?
Since version 2.1 of the Maven Dependency Plugin, there is a dependency:get goal for this purpose. To make sure you are using the right version of the plugin, you'll need to use the "fully qualified name":
mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:get \
-DrepoUrl=http://download.java.net/maven/2/ \
-Dartifact=robo-guice:robo-guice:0.4-SNAPSHOT
Give them a trivial pom with these jars listed as dependencies and instructions to run:
mvn dependency:go-offline
This will pull the dependencies to the local repo.
A more direct solution is dependency:get, but it's a lot of arguments to type:
mvn dependency:get -DrepoUrl=something -Dartifact=group:artifact:version
As of version 2.4 of the Maven Dependency Plugin, you can also define a target destination for the artifact by using the -Ddest flag. It should point to a filename (not a directory) for the destination artifact. See the parameter page for additional parameters that can be used
mvn org.apache.maven.plugins:maven-dependency-plugin:2.4:get \
-DremoteRepositories=http://download.java.net/maven/2 \
-Dartifact=robo-guice:robo-guice:0.4-SNAPSHOT \
-Ddest=c:\temp\robo-guice.jar

Installed package with Maven

How do I install a specific package, like derbytools, with Maven without specifying it as a dependency of project?
Here is a sample using the mvn install goal. I used windows style env vars in place of parameters you will need to provide.
mvn install:install-file -DgroupId=%DERBYTOOLS_GROUP_ID% \
-DartifactId=%DERBYTOOLS_ARTIFACT_ID% \
-Dversion=%DERBYTOOLS_VERSION% \
-Dpackaging=jar \
-Dfile=%DERBYTOOLS_FILE_PATH%
For Maven to be able to use a jar, the jar needs to be declared as a dependency.
If you have a jar that doesn't already exist on a Maven repository you can install it to your local repository using the install-plugin's install-file goal (as rich's answer says). This generates a pom using the values you provide and installs the pom and the jar to the local repository. Once that is done you would then add the dependency to your project's pom and use it as normal.
In this case the dependency does exist on the central Maven repository (you can simply search for artifacts using the Sonatype public repository btw), so you can simply add this dependency to your POM:
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbytools</artifactId>
<version>10.4.2.0</version>
</dependency>
If you do not want to install a dependency for whatever reason, you can alternatively use the system scope to reference a jar by it's absolute file system path. This approach is not recommended though as it obviously affects portability.
From the documentation:
Dependencies with the scope system are always available and are not looked up in repository. They are usually used to tell Maven about dependencies which are provided by the JDK or the VM.
You could reference your derbytools jar as a system-scoped dependency like this:
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbytools</artifactId>
<version>10.4.2.0</version>
<scope>system</scope>
<systemPath>/path/to/derbytools.jar</systemPath>
</dependency>