I only recently stumbled upon Maven after seeing how Ruby and node.js have their respective package management systems. Well, actually, I’ve been stumbling upon pom.xml files for a while now but it never really clicked with me what they were for. After a bit of exploring during a new project setup, I figured it’s time to include a bit more package management into my Java projects so that I can be a little more versed with how things are done in modern Java development.
So, enter the Maven setup guide.
I’m writing this as a companion piece to the Java Development post since the concept is going to be related. This guide will assume some setup from that post for the basic Eclipse bootstrap, and the rest will diverge from there to help you get up and running with Maven and Eclipse and a simple project setup. Or something like that. We’ll see how it fares by the end of the post.
So here’s the plan:
- Get Maven installed on the OS and in Eclipse
- Create a new Java project with Maven support
- Setup the various configuration files
- Integrate the project into Eclipse
- Make sure the project can be run independent of Eclipse
You’ll want to get Maven installed on your OS, since part of the point of Maven is to be able to compile and run things independent of a platform (like Eclipse). For something like Ubuntu, you can easily do:
sudo apt-get install maven
and that should do the trick. For other OSes, you’ll have to do your due diligence to get it installed :). For Eclipse, you’ll need these repositories. Though technically, I think you just need the second one:
“Maven” : http://download.eclipse.org/technology/m2e/releases/
“Maven Integration for WTP” : http://download.eclipse.org/m2e-wtp/releases/
With that, your system should be ready for Maven use at the OS and Eclipse level.
This is where the bizarre Maven commands come into play. For my case, I develop web applications aimed to be run on servlets, so this is the Maven command to create a project as such:
mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp
Just run that from your project parent directory and it will eventually create a project with the specified artifactId you will provide during the prompted walk through. In a nutshell:
- groupId: Your Java package. For me, I use something like com.subdigit
- artifactId: The application package. So I may do something like testapp if my project package is com.subdigit.testapp
- version: I usually downgrade my version to something like ‘0.0.1-SNAPSHOT’ just for starters. Keep the -SNAPSHOT bit as it actually as semantic meaning.
- package: should be fine to leave as is, as it will just mirror the groupId.
And that’s it, you should now have a “testapp” directory populated with an outdated servlet web.xml. Congrats. Which of course means…
Fix Defaults: web.xml
Why the default archetype for a webapp is not up to date with modern servlet standards, I don’t know. But it’s an easy enough fix.
You’ll want to update the src/main/webapp/web.xml from the dark ages to at least the current standard of the 3.0 framework. So, just replace everything in there with this:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>User Module</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
That should give you the basics to start with. And if you do it now, Eclipse will be much happier giving you the proper settings during the import.
Fix Defaults: pom.xml
For the most part, the pom file is ok. But it could use some version updating. The default junit version that’s hardcoded in is 3.8.1 so you might want to update it to something like 4.11.
You’ll also want to force Maven to use a modern JRE as the default is something rather ancient. To do so, you’ll need to explicitly specify the JRE version you want Maven to use in the pom file’s <build>/<plugins> section:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.0</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin>
The rest you get to have fun modifying it to your needs adding in all sorts of dependencies and whatever you need. I wont cover that here, but you can see the pom.xml I use in this project.
Once all the above is set, you can import it into Eclipse. Some sites will tell you to use “mvn eclipse:eclipse -Dwtpversion=2.0” from the commandline to prepare the project, but the instructions that worked for me didnt like it, so I don’t use it for my projects. All you should need to do is:
File -> Import -> Existing Maven Projects
And just follow the prompts. If you already updated your web.xml per the above, the Dynamic Web Module version should already be at 3.0. Which is what you want.
Fix Defaults: Eclipse
You’ll most likely have some of the directories you need, but not all of them. Odd isn’t it. Just go ahead and make sure you have at least these 4 directories:
- /src/main/java: Java files go here
- /src/main/resources: Property files go here
- /src/main/webapp: jsps go here
- /src/test/java: Unit tests go here
If not, you can just right click on the project and do a “New -> Folder” and create the missing ones. Again, why they’re not already all there, I have no clue.
One thing that didn’t catch for me at times were my Maven dependencies. Basically, with Maven, you’ll no longer be directly hosting the various dependency jars in “WEB-INF/libs”, instead they all go into a central repo on your machine that Eclipse needs to reference in its classpath. So you need to make sure your “Maven Dependencies” are linked properly, or else you’ll end up with a bunch of “ClassNotFound” exceptions.
Open up your project properties, and find “Deployment Assembly”. In that, there should be:
"Maven Dependencies" -> WEB-INF/lib
If it’s not there, add it. If it’s there, golden. Just to make sure, you should also have your main java and resources directories pointing to “WEB-INF/classes” and the webapp directory pointing to “/”.
At this point, you should be able to create your servlet, configure the web.xml or use the @WebServlet annotation and have it get registered properly (assuming you went through and configured a servlet container like Tomcat). You’re all golden.
Now we need to take advantage of the whole package and independence Maven is supposed to give you.
Personally, I never want to have to muddy my development environment just to test out a cool project I’ve see somewhere or to run the samples of a project without the hassles of setup. I love seeing all these node.js projects just be able to run everything from a lightweight commandline instance so that you don’t have to do any setup. Maven also lets you do the same.
For me, I’m currently using Tomcat, so I would love to just have Maven be able to run my project from the commandline so that people can easily test it out without hassle. To make that happen, you need to make sure you have a dependency in your pom.xml that points to the servlet API so that Maven can compile against it, and then you also need to have it call a server to run the compiled code on a localhost port.
So, for the servlet API dependency, make sure you have this as part of your pom’s <dependencies> section:
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency>
And in your <build> section’s <plugins> area, you’ll need the Tomcat plugin installed:
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.0</version> <configuration> <url>http://localhost:8080/manager</url> </configuration> </plugin>
Once that’s in place, you can then call:
From the commandline and voila, you should now see your app running on http://localhost:8080 Congratulations. You’ve now achieved IDE independence.
So in theory, if you put your code up on GitHub, tell people to clone it locally, all they need to do to run it is to type the above. No setup, no IDE needed, no hassles. Quick and simple. You can try it with my project and see if it does indeed work.
There’s a lot I’m leaving out about Maven and pom.xml setup, but I’m just not versed enough to write about it, nor if I did, would this post be readable in length. It’s already pretty long and talking about the nuances of the pom.xml is just way beyond this post. Best bets: Go search for pom.xml files in GitHub and use them as examples. I’m sure there will be a few referential ones around :).
I think I have most of my setup complete, so I want to start concentrating on creating some projects. You can get a peek at what I’m up to on my GitHub account if you’re curious. It’s going to be a series of modules that offer some good reuse and bootstrapping for starting a user login capable website… or so I think.
setup always takes so long to do. I hope this speeds it up for some people. At least it does for me. Also, maven image sourced from ideyatech