Skip to main content

Maven Repository with NetBeans 5.0

Posted by ddevore on February 17, 2006 at 8:21 AM PST

This entry is for using a Maven repository in NetBeans with the ant build process. I have seen a lot of discussion over Maven and its repositories. Personally I would like to use Maven in the NetBeans build but there currently is no direct integration of Maven in the NetBeans. Before you post a comment about the Mevenide, yes I know about that project http://mevenide.codehaus.org/ and http://docs.codehaus.org/display/MEVENIDE/MevenideNetbeans2.0 but the last time I checked it was not integrated into the current build process. I would like to see NetBeans have a switch that would allow you to choose between ant and Maven for building. Until then I am going to stick with the ant build process because NetBeans does such a good job with it.

Now on with adding a Maven repositories into the ant build process within NetBeans. If you are not familiar with Maven please look here for more information about Maven http://maven.apache.org/.

If you are familiar with Maven or have read the above link you will know that there was a version 1 and now a version 2 Maven. Each version has its own repository and setup which is outside of this blog. I will save that discussion for another day. For more information on repositories please see the following links.
Introduction to Repository definitions and artifact resolution
Introduction to Repositories

In integrating Maven I kept the build clean for 2 reasons. First I wanted to make it easily movable from project to project without a lot of modifications. Second it was written so that it could be removed easily because it tries to download the repository files each time you do a build. So on with the files.

There are 3 files needed for this integration. First is the maven-artifact-ant-2.0.2-dep.jar which can be downloaded from here. Second is a POM or Project Object Model which is the build file for Maven. Third is a repository xml file, created originally by someone else that I modified to fit better in the NetBeans build, which is imported into the build.xml.

POM
The POM which we are using is a scaled down version from a complete Maven POM, it is only the dependencies section.


<project>
&nbsp&nbsp&nbsp&nbsp<modelVersion>3.0.0</modelVersion>
&nbsp&nbsp&nbsp&nbsp<groupId>BMGCH</groupId>
&nbsp&nbsp&nbsp&nbsp<artifactId>core_lib</artifactId>
&nbsp&nbsp&nbsp&nbsp<version>1.0-SNAPSHOT</version>

&nbsp&nbsp&nbsp&nbsp<dependencies>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<dependency>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<groupId>log4j</groupId>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<artifactId>log4j</artifactId>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<version>1.2.9</version>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</dependency>

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<dependency>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<groupId>j2ee</groupId>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<artifactId>j2ee</artifactId>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<version>1.4.2</version>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</dependency>

&nbsp&nbsp&nbsp&nbsp</dependencies>

</project>

The first section; modelVersion, goupId, artifactId, and version are settings for the project and do not have any affect on the build except for they must be there. If you want more information about these fields please see the Maven links above. To be honest I just wanted to get this working so I didn't really care what those values were since they didn't make a difference to the build. The next section is the dependencies section. This is where you define what you are downloading. If you look in a Maven repository it is setup with a directory which coorlates to the groupId, the artifactId is the first part of the jar file name with the dash before the version number. So for instance the log4j dependency listed above is in the directory log4j off the root of the repository then there is a jar directory with the file log4j-1.2.9.jar in it. Now most of the time you will not browsing the repository but we don't have a repository directory setup so I need to.

repository.xml
The repository.xml is where the work actually happens in this process. It looks like the following.


<?xml version="1.0" encoding="UTF-8"?>

<!--
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Document : repository.xml
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Created on : September 30, 2005, 8:15 AM
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Author : ddevore
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Description:
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp This is a ant scripting document for utilizing the repository
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp functionality included in Maven2. To use this correctly you must have
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp the maven-artifact-ant jar file in the maven.lib.dir location. The libs
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp downloaded will be located in the lib.dir location. The lib.dir will
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp be removed with the clean target for the project.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp For this file to be run correctly you must import it into the main
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp build.xml with the following line.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp <import file="repository.xml"/>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp The downloading can be called independently of the build process by
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp using the download-libs tagret.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Upon first checking out a project from CVS which uses the repository
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp you will get unresolved references. To fix this simply do a build or
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp download-libs on the project, which will download the libs in the proper
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp directory.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp NOTE: The libs still need to be added to the NetBeans project.

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp This script is setup for the NetBeans build scripts and is dependent
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp on them so it will not work without them.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Properties:
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp lib.dir = The directory for the dependent libs.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp maven.lib.dir = The directory for the maven ant jar file.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp maven.lib.jar = The name of the maven ant jar file.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp maven.remote.repository = The remote repository name to use.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp maven.repository.type = The type of repository. Valid values are
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp legacy = Maven 1 repository.
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp default = Maven 2 repository.
-->

<project name="core_lib-repository" default="default" basedir="."
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp xmlns:artifact="urn:maven-artifact-ant-batch">
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<description>Downloads dependent libs defined in the pom.xml.</description>

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<property name="lib.dir" value="build/dependent_libs"/>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<property name="maven.lib.dir" value="src/lib"/>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<property name="maven.lib.jar"
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp value="maven-artifact-ant-2.0.2-dep.jar"/>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<property name="maven.remote.repository"
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp value="http://dev.columbiahouse.com/maven"/>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<property name="maven.repository.type" value="legacy"/>

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<typedef resource="org/apache/maven/artifact/ant/antlib.xml"
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp uri="urn:maven-artifact-ant-batch">
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<classpath>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<pathelement location="${maven.lib.dir}/${maven.lib.jar}" />
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</classpath>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</typedef>

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<target name="download-libs" depends="init">
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<artifact:pom id="maven.project" file="pom.xml" />
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<artifact:dependencies pathId="dependency.classpath"
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp filesetId="dependency.fileset">
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<pom refid="maven.project"/>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<remoteRepository url="${maven.remote.repository}"
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp layout="${maven.repository.type}" />
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</artifact:dependencies>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<copy todir="${lib.dir}" flatten="true">
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<fileset refid="dependency.fileset" />
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</copy>
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</target>

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<target name="-pre-compile" depends="download-libs"/>

</project>

What this all means is this. First the project name attribute. I put the project name with a -repository at the end to make it unique, if you don't do this you will get a warning running the project because the name is already declared. The properties are fairly easy to see. The lib.dir is where where the libs will be downloaded to, I put them in the build directory so they will not be put into CVS. The maven.lib.dir and maven.lib.jar is the directory and file name for the maven-artifact-ant jar file. The maven.remote.repository is the location of the repository with the maven.repository.type being the type, legacy means it is a Maven 1 repository. After that it is defining and running the task. The last target is telling the NetBeans build process to download the libs before doing a compile.

To get this to be included in the build you must include it in the build.


<import file="repository.xml"/>
<import file="nbproject/build-impl.xml"/>

The repository.xml must be before the build-impl import or it will not be imported.

maven-artifact-ant-2.0.2-dep.jar
The only thing left is to put the maven-artifact-ant-2.0.2-dep.jar in the proper place. From my repository.xml you can see that I put it in the src/lib directory. Put it in the proper directory and you will be good to go.

Good and Bad
This allows you to pull libs from a Maven repository so you don't have to store them in CVS and you always have the latest. There are 3 problems with this though.
1. When you check out a project you will have unresolved dependencies so you will have to either run the download-libs target or do a build.
2. Wnen you clean you will again get unresolved dependencies. This is a problem with where I put the libs. If you put them outside the build or dist directory you won't loose them upon a clean but NB will then want to put them into CVS.
3. It wants to download them each and every time you build which is not that big of a problem unless you have a large project or a lot of dependent projects then it could take some time. This can be fixed by either removing the import for the repository.xml from the build, which will remove the repository capabilities completely, or take out the -pre-compile target from the repository.xml. Taking out the -pre-compile would be the safest since you can still run the download-libs target with this method.

Related Topics >>