With Maven, Eclipse and Java EE

When it comes to developing a Java EE app in Eclipse you have two choices. You can use the native project structure of Eclipse or you can use a Maven managed project. If you are using a third party framework like Spring or Struts2, you might find that Maven is the easier of the two options. I found Maven is also a better option when your Java EE project depends on other in-house Java projects. If you are not sure if you should move to Maven, this tutorial will be useful.

There are tons of tutorials on how to create a basic web or Spring MVC project using Maven. There are a few things missing. Very few properly show how to do this from Eclipse and almost none I have seen show how to build a full stack Java EE 6 app with CDI, JPA and other API. Hopefully, this tutorial will fill that gap.

Software Setup

I am using Eclipse Kepler. It comes with Maven already integrated. You do not need to install any extra plug-ins or have Maven installed on the OS. Although, if you choose to build your project from the command line then you will need to install Maven on the OS. We will get to command line build later in this tutorial.

Since I will be using full stack Java EE, I am using TomEE as the test server. You can use JBoss as well. But, Tomcat will not work.

Create a Maven Managed Java EE 6 Web Project

In Eclipse, choose File > New > Project from the menubar.

image

Choose Maven > Maven Project and click Next.

image

Accept the defaults. Click Next.

Now, we will need to choose an archetype for the project. The good old “maven-archetype-webapp” is a good start for any web project. We will use it.

image

Enter webapp in the Filter. Select maven-archetype-webapp. Click Next.

Now, we will need to enter the coordinates of this Maven artifact.

image

Enter a group ID and an artifact ID. The artifact ID will also be used as the Eclipse project name. In our case, the name of the project will be SimpleWeb. Also, if you build the WAR file for the project, Maven will call it SimpleWeb.war.

You don’t need to worry about the package name.

Click Finish. This will create the SimpleWeb project.

Unfortunately, the project is woefully incomplete. We will need to do a few things before we can start coding.

First, we will need to add dependency for the Java EE API.

image

Double click pom.xml of the project to open it in the editor.

image

At the bottom of the editor, click the pom.xml tab.

Add the following lines within the <depdnedncies></dependencies> section.

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>6.0</version>
    <scope>provided</scope>
</dependency>

Note that, we set the scope to “provided”. We do not want to ship the JAR file with the WAR. We expect the server to provide the Java EE API classes in the run time classpath.

Save changes.

Finally, we will need to create the directory structure where Java code will go.

image

Within the src/main folder, create a folder called java. As per Maven’s conventions, all Java code should go in that folder.

Write Some Code

Let’s first write a basic Servlet.

Right click SimpleWeb project and select New > Class.

image

Enter a package and class name as shown above.

Note that Eclipse has correctly chosen the right source folder.

Click Finish.

Extend HttpServlet and add the @WebServlet annotation as shown below.

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
}

Add a simple doGet method as follows.

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("Servlet is called.");
}

Organize imports. Save changes. There should be no compilation error. Maven has added all necessary Java EE API classes to the build path.

Test the Application

image

In the Servers view, right click TomEE and select Add Remove. Add SimpleWeb project to the server this way.

Restart the server.

Using curl, execute the Servlet:

curl http://localhost:8080/SimpleWeb/hello

The console should show the output from the server.

image

If you change any code in the web project, Eclipse will automatically redeploy the app and restart it within a few seconds.

Build a Utility Library

If you have a very large web application it can help to develop some of the code in other projects. This code may need to access Java EE API such as CDI, EJB and JPA. Eclipse doesn’t provide any easy way to create a Java project that depends on Java EE API. Also, consider the challenge of constantly building these utility projects and adding the resulting JAR files to the WEB-INF/lib folder of your web project. Eclipse Maven plug-in really shines in this department.

Create another Maven project. This time, choose maven-archetype-quickstart as the archetype.

image

Enter SimpleUtility as the artifact ID. This will also be the name of the project.

Open the pom.xml file and add the dependency for the Java EE 6 API the same way we did for the web project.

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>6.0</version>
    <scope>provided</scope>
</dependency>

image

In the SimpleWeb project, add a new class called com.mobiarch.util.Greeter.

Add the following method to the class.

public void sayHello() {
    System.out.println("Hello from utility library.");
}

Save changes.

We intend to inject this class to our Servlet. For CDI to work, we need to add beans.xml to the utility JAR file. In a Maven project, the file needs to be in src/main/resources/META-INF/beans.xml.

image

Create an empty beans.xml file as shown above. After a build, the file will be in the META-INF folder of the JAR file.

Use the Utility Library

Back in the SimpleWeb project, open pom.xml and add the dependency to the utility library project.

<dependency>
    <groupId>com.mobiarch</groupId>
    <artifactId>SimpleUtility</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

Save changes.

Open the HelloServlet class. Add an injected instance of the Greeter class as shown below.

public class HelloServlet extends HttpServlet {
    @Inject
    Greeter greeter;
...
}

From the doGet method, use the Greeter.

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    greeter.sayHello();
}

Save changes.

Before we can test the changes, we have to do a bit of project management. Every time dependency between projects changes you need to update the projects. This is a pain in the neck and hopefully will go away some day. Right click SimpleWeb and select Maven > Update Project.

image

Select both SimpleUtility and SimpleWeb and click OK.

Restart the server.

Use curl to execute the Servlet.

curl http://localhost:8080/SimpleWeb/hello

image

Console should show the output from the injected class.

A huge advantage of Maven based utility project is that you can update the code in these projects and Eclipse will automatically redeploy the web application and restart it within a few seconds. Try changing the message printed by the Greeter class and re-execute the URL from curl. You should see changes.

Building the Final Package

At the end of development, you need to produce a WAR file. The WAR file should include all dependent JAR files in WEB-INF/lib unless they are marked as provided. This can be done from within Eclipse. More commonly, this will be done from a command line in a separate build machine.

First, we will learn how to package from Eclipse. The depndent projects need to be built first and installed in the local Maven repository. Right click SimpleUtility project and select Run As > Maven Install. Next, do the same for the SimpleWeb project.

image

If you expand the target folder, you will see the WAR file. The WAR file will include the JAR file for SimpleUtility.

Now, we will do packaging from the command line.

Install Maven in your OS. For example, in Ubuntu:

sudo apt-get install maven2

Then, from a terminal window, go into the SimpleUtility and run:

mvn clean install

This will do a clean build and install the articfact in the local repository.

Go into SimpleWeb and run:

mvn clean install

The WAR file will be created in the target folder.

Benefits of Maven Based Eclipse Projects

In summary, these are benefits. All of them are quite significant in my mind:

  • Ability to build projects from command line without the need for Eclipse. This is essential for an automated git clone/pull and clean build of the projects.
  • Ability to easily write Java code in external projects and use these projects from a web application. The Java projects can have full access to the Java EE API. Any change made to the external Java projects are reflected immediately during testing.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s