September 28, 2009, 12:12 pm
Maven is quickly becoming the de facto standard for Java project builds, as more developers realize its benefits and choose to migrate from Ant. Gone are the days when external project dependencies clogged up valuable space in source code control repositories. Once programmers become familiar with Maven, discovering all its advantages along the way, development proceeds as if they couldn‚Äôt get the job done without it. But there is one aspect of Maven-based development that‚Äôs potentially troublesome: the reliance on a remote central repository somewhere on the Internet. When a new developer joins a team, every single dependency is copied from the remote repository to his or her local repository cache. On Linux, this resides in the $HOME/.m2/repository and is usually a substantially large directory ‚Äî especially if the developer has multiple projects under Maven control. This places an unnecessarily large load on the company‚Äôs or individual‚Äôs Internet link for the duration of the dependency download. Even worse, should the Internet link go down, the developer is unable to work.
So what‚Äôs the answer to all that wasted Internet bandwidth? A local Maven proxy. The first time a developer requests a dependency, it is copied from the central repository to the local repository, which resides on the machine running the proxy.¬†Subsequent requests by developers in the team are then fed the copy from the local repository, typically on the same local area network (LAN). That translates to quicker builds and ‚Äî as long as no new dependencies are needed ‚Äî no reliance on the corporate Internet link for builds.
Before You Start
This tutorial¬†covers the setup of Maven on a Linux server, as well as the best free local proxy available today, Nexus. Nexus is available in both a GPL-licensed version (Nexus Community) and a commercially-licensed version (Nexus Pro) that provides additional functionality. We will, of course, focus on the open source version as it is sufficient for most requirements. Well, OK‚Ä¶ also because we dig open source and free stuff!
Meat & Potatoes
Let‚Äôs start off with Maven. Maven runs as a Java process, so we‚Äôll need to make sure we have Java installed first. Download the latest JDK from OpenLogic Exchange (OLEX) or http://java.sun.com/javase/downloads/index.jsp.
You‚Äôll be asked to select the platform and type of installation. We always download the .bin self-extracting archive, and extract it to /usr/local on the Linux host:
# cp <download_location>/jdk-6u16-linux-x64.bin /usr/local
# cd /usr/local
# sh ./jdk-6u16-linux-x64.bin
Follow the prompts and install the Java SDK. You‚Äôll see that at the time of writing, the version of the SDK was 6u16, which will obviously change. Once everything has extracted, a browser window will open and nag you to register. This is optional ‚Äî the SDK will function just fine, even if you choose not to register. Close the browser and look at the new directory under /usr/local. The JDK will be installed in a directory containing the name of the version of the software, in this instance /usr/local/jdk1.6.0_16. A good trick is to make a symbolic link for this directory to /usr/local/java. That way you can keep your $JAVA_HOME environment variable set to the symbolic link. Every time you upgrade Java, simply remove the old symlink and then relink to the new location:
# rm -f /usr/local/java
# ln -fs /usr/local/jdk1.6.0_16 /usr/local/java
If you don‚Äôt already have $JAVA_HOME set up, let‚Äôs do it now. Use your favorite editor to open /etc/profile, and add the following line near the top:
While we‚Äôre here, let‚Äôs also add a needed variable for Maven:
Now look a little further down in the file. You should see a line configuring the $PATH variable. We need to add to the $PATH to include the ./bin directories of both Java and Maven. It should end up looking something like this:
Save /etc/profile and exit the editor. Now it‚Äôs time to install Maven. Download it from OpenLogic Exchange (OLEX) or http://maven.apache.org/download.html.
Get the latest .tar.gz distribution. In our case it was apache-maven-2.2.1-bin.tar.gz:
# cp <download_location>/apache-maven-2.2.1-bin.tar.gz /usr/local
# cd /usr/local
# tar xvzf ./apache-maven-2.2.1-bin.tar.gz
Now log out and back in again for the contents of /etc/profile to be read and for the environment variables and PATH to be updated. Verify both installations:
# java -version
java version "1.6.0_16"
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) 64-Bit Server VM (build 14.2-b01, mixed mode)
Apache Maven 2.2.1 (r801777; 2009-08-06 12:16:01-0700)
Java version: 1.6.0_16
Java home: /usr/local/jdk1.6.0_16/jre
Default locale: en_US, platform encoding: ISO-8859-1
OS name: "linux" version: "126.96.36.199" arch: "amd64" Family: "unix"
Good Job! Now on to the final part of our puzzle, the Nexus repository manager.
Nexus is deployed as a standard J2EE web archive or .war, as it is affectionately known. There are two download options: one as a .war, which you can install into a J2EE compliant server; or a standalone version which contains an embedded Jetty server. We‚Äôre going to focus on the standalone deployment.
Let‚Äôs start off by downloading and installing Nexus:
# cd /usr/local
# wget http://nexus.sonatype.org/downloads/nexus-webapp-1.3.6-bundle.tar.gz
# tar xvzf nexus-webapp-1.3.6-bundle.tar.gz
# ln -fs nexus-webapp-1.3.6 nexus
# cd nexus
# ls ./bin/jsw/
This will show you a list of directories for the supported architectures. In this case we‚Äôre running Linux x86-64, so to start the server we type:
#¬† ./bin/jsw/linux-x86-64/nexus start
You can install Nexus as a Linux service, too. Look for the link to the official documentation at the end of this article for details. To follow the log of the starting up server:
# tail -f logs/wrapper.log
If all runs correctly and you see no ominous-looking error messages, you should now have the proxy up and running. But we still have to tell Maven to look at the repository, instead of at the default central Maven servers. We do this by editing settings.xml, which resides in the .m2 directory under your home directory.
<!--Enable snapshots for the built in central repo to direct -->
<!--all requests to nexus via the mirror -->
<!--make the profile active all the time -->
Remember that each of the developers in your organization will have to do this on their local machines, but replace localhost in http://localhost:8081/nexus/content/groups/public with the name or IP address of your repository server.
We‚Äôre almost there. We still have to tell the repository proxy exactly what it has to proxy! For this task, Nexus has a really cool web-based interface for us to use. Fire up a browser on the machine and point it to http://localhost:8081/nexus.
Above: The Nexus Welcome Screen
Click on the Log In link at the top right hand side, and log in as admin with the password you configured during the setup process.
Above: The Repository View
Your screen may look slightly different. The Repository Path column will reflect either localhost, or the name of your server if you are administering from a remote machine. The next step is to download the Lucene indexes for all of the ‚Äúproxy‚Äù pre-configured repositories. For example, click on the ‚ÄúMaven Central‚Äù proxy and select the Configuration tab below. Change ‚ÄúDownload Remote Indexes‚Äù to True, and then click Save.
Above: Enabling Download of Remote Indexes
Then right-click on the same proxy, and select Re-Index. Repeat the process for each of the proxies.
Well done! You now have a functioning proxy that will start building a repository as you use it from your Maven project builds. If something doesn‚Äôt work, or you‚Äôre confused about some of the Nexus functionality, Sonatype has extremely good online documentation at http://www.sonatype.com/books/nexus-book/reference/index.html, including instructions on how to install Nexus as a service. This is definitely worth doing. You can also add periodic tasks to download and re-index the proxies.
At this point, you should aim to become more familiar with the administration interface and understand all of its functionality. Reference the documentation and examine the system logs for any potential problems.
Grant started writing software at the age of 12 when his father assembled a Sinclair ZX-81 in kit form, and he's been hooked on technology ever since. His experience with software development is as deep as it is unique -- he's been a programmer in the South African Army, IT manager at a merchant bank, VP of IT at a construction and property administration company, and he's an active committer to the Apache community of open source software projects. Grant currently resides in Oregon where he enjoys cycling, racquetball, geocaching, coaching and playing soccer, and spending time with his lovely wife and children.