Enterprise Java

Java EE7 and Maven project for newbies – part 1 – a simple maven project structure – the parent pom

Why ?

Many times, I am trying to resolve several basic or complex Maven /  Java EE  project structure issues, on my day work. In order to provide the solutions,  I often end up   experimenting with the project structure, test my deployment on different application servers and fine grain my configuration.

Maven can have a steep learning curve for newcomers and if you add in the mix the ‘ sometimes‘ complex configuration requirements of a modern Java EE application, the things get more frustrating. I have also seen in my career, that lots of junior java developers, when they join a big team or project, most of the times the project structure is already fine grained and configured for them by more senior members. They assume that it works, and they dont spent time to understand the wiring and configuration. I have done this mistake myself in the past. They are being assigned simple coding tasks and they deep dive on requirements but unfortunately they forget  to study  the application structure.Their senior colleagues forget as well to train them on this particular area, most of the times due to time restrictions. This may lead to accidents when people start messing around  with the structure of the application with no previous experience, while trying to ‘make it’ work. Maven and it’s conventions aim to help a lot on establishing common structures and conventions on how a project should be structure, but the again you need to understand the tool the conventions and then master your ‘ configuration‘.

You can often hear someone saying ‘ I added this library there and it worked‘, if you reply ‘ define there‘, then you might get some interesting answers. Sometimes by accident or luck it works but in a complex multi-module application, most of the times ‘ it just works‘ is an  understatement and problems will start appearing soon enough.

This series of posts is targeting Maven and Java EE newcomers mostly, but feel free to share or use it as a demo if you are a more senior developer. I am going to ‘attack’ on a demo basis some real problems I happen to discover from day to day work and try to provide solutions while providing a basic explanation or links to related resources. Please feel welcome to add comments, corrections or references for something that can be performed / completed in a far cleaner way. The best way to learn Maven and create a ‘complex’ but easy to maintain application is to start from scratch, empty pom files.

The  main message I am trying to pass along to junior developers reading my posts is that studying’ your application structure, asking about the underlying build tools is part of your work and you should never assume that someoene else is always going to take care of it. It is also a stepping in order to challenge more difficult tasks and improve your skills as a Java developer.

Core technologies to be used

  • Java EE 7 based application
  • Will  be packaged as an EAR
  • Will be featuring multiple components (wars, jars, ejb jars)
  • Will be compiled towards Java 7
  • Will be packaged using Maven 3

My demo ear application

My application is going to be an EAR, for this particular post,  this ear is going to include 2 top level modules a war and an ejb-jar. There is also going to be a jar, that will contain the classes that will be my database domain model (JPA entities). I am going to expand the structure adding more resources in future posts. A very abstract image just to give an idea, illustrating what are going to ‘include in our ear’. The war module in the future will contain servlets or jsf compoments, the services module is going to contain a set of common Stateless Sesson Beans (or Message Driven Beans). The domain project is going to have plain Java classes properly annotated with JPA2 constructs.

 

CapturFiles_1

 

Composing the basic structure of our application using Maven

In order to build the ear above we need to define modules and the parts of our application, using Maven which is anyway our building/packaging/configuration tool. This is one of the most steps and if you get this from the start then the rest will be simple technicalities or configuration specifics. What I am proposing is not the ultimate solution but something very close to the standard which is most of the times the ‘ way to go‘ if you start a new app, so no funcy specifics here, let’s follow the standard and start building on a concrete foundation.

So let’s forget the image above at the moment and let’s think Maven, what and how many modules may define, how to interconnect them and define dependencies. Note, my proposed way of work is the standard but it is not the ultimate solution , meaning you can achieve the same results by packaging your application as an ear, define fewer modules and dependencies. Let’s assume that I want to cover highly complex structures so I will define a generic structure, always following the standards.

I assume that you have covered some basic stuff from Maven and you are at least familiar with the terminology.  If not have a look here.

Remember Maven is about, placing your files to the right places according to a well defined structure , and defining the maven plugins, which are some kind of tools to do specific things compile, package, copy files, etc. The plugins are being invoked by Maven, so yes again you need to define the plugins to the correct place and with the appropriate configuration. You are not writing your make or ant scripts, you just ‘insert’ plugins and ask maven to execute them in a well define order.

As good ex-colleague of mine (wrote in a email recently), it is good to break conventions in your life and in your coding, but never with Maven. He is right!

If you are not sure how to install maven, have a look here Windows  or Mac

My Maven Project Structure – Abstract

We are building with Maven, so we need to think in terms of maven pom (s) and modules. In order to create out required ear packaging (see above) we need 5 poms

  • A pom – acting as a parent
  • A pom that will contain/define the final ear – responsible for configuring the final package.
  • A pom that will contain/define the code of the web application, meaning our .war
  • A pom that will contain/define the code of the ejb-module, the module that we are going to package our EJB(s)
  • A pom that will contain the classes that are going to be our JPA (Database Entities)

 

CapturFiles_4
As you can see, every module has it’s own pom, and there is the parent, one of the things that still lot’s of people do not add in their structure, assuming that they don’t need it, since their project is small, and the after a while while more modules are being added, you end up with havoc. So make a note here ‘ the parent pom is really nice to have and configure‘. This is the pom where you define all your dependency versions (that is libraries) and you configure the maven plugins, so that all the child poms, inherit a common configuration.

My Maven Project Structure – the Parent pom

As I have already elaborated we are going to start from scratch, so I am creating a new folder called ‘ sample-parent‘ and in this folder I add a new file called ‘ pom.xml‘.

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>
            <groupId>gr.javapapo</groupId>
            <artifactId>sample-parent</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <packaging>pom</packaging>
     
           
    </project>

Yeap not excited, just make note on the packaging element which is defining ‘ pom‘.The parent is called parent, because it ‘defines’ and manages the children modules, this is done in the modules definition section. Our original pom becomes something like that. That means that we must create the related folders under our sample-parent, and then add a pom.xml to each one of them.

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>
            <groupId>gr.javapapo</groupId>
            <artifactId>sample-parent</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <packaging>pom</packaging>
     
            <modules>
                    <module>sample-ear</module>
                    <module>sample-web</module>
                    <module>sample-services</module>
                    <module>sample-domain</module>
            </modules>
           
    </project>

Let’s continue adding some more configuration…

This is an important section since we define versions for

  • the maven plugins we are going to use and configure
  • any libraries – dependencies used and reference from other modules
  • other generic properties, like the version of the Java runtime we are going to compile
  • The default encoding for source files or other assets.
    <properties>
            <!--  encoding-->
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <!--java version -->
            <java-version>1.7</java-version>
           
            <!-- plugin versions -->
            <ejb-plugin-version>2.3</ejb-plugin-version>
            <war-plugin-version>2.4</war-plugin-version>
            <ear-plugin-version>2.9</ear-plugin-version>
            <compiler-plugin-version>3.1</compiler-plugin-version>
     
            <!-- dependency versions -->
            <javaee-api-version>7.0</javaee-api-version>
                   
            <!-- EJB spec version -->
            <ejb-spec-version>3.2</ejb-spec-version>
    </properties>

Let’s add after the properties section, another important one, the dependencyManagement .This is where we will define the dependencies and their versions that can be potentially used in our application modules. In this section we actually care about the version, the inclusion or exclusion of the dependencies it is up to the child pom (meaning they are not added automatically), their scope as well. So the DependencyManagement section is the one to control, in one central place the versions.

    <dependencyManagement>
            <dependencies>
                    <dependency>
                            <groupId>javax</groupId>
                            <artifactId>javaee-api</artifactId>
                            <version>${javaee-api-version}</version>
                    </dependency>
                    <dependency>
                            <groupId>junit</groupId>
                            <artifactId>junit</artifactId>
                            <version>${junit-version}</version>
                    </dependency>
            </dependencies>
    </dependencyManagement>

Another last but important section in our parent pom is similar to dependencyManagemt is called pluginManagement, and is the section where we will define, the versions and common configuration of all the maven plugins that are going to referenced and used during our application configuration and packaging.In the sample below I have defined one of the most basic, the compiler plugin, but of course I am going to need more!

    <!-- Plugin management -->
    <build>
      <pluginManagement>
         <plugins>
            <!-- compiler plugin -->
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>${compiler-plugin-version}</version>
              <configuration>
                <source>${java-version}</source>
                <target>${java-version}</target>
                <encoding>${project.build.sourceEncoding}</encoding>
             </configuration>
          </plugin>
       </plugins>
      </pluginManagement>
    </build>

Let’s add and configure some more plugins that we are going to use later on.Add those within the plugin management section. We define the ejb plugin that is going to compile and package our ejb(s) and the war plugin that is going to package our war.

    <!-- ejb plugin -->
    <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ejb-plugin</artifactId>
            <version>${ejb-plugin-version}</version>
            <configuration>
                    <ejbVersion>${ejb-spec-version}</ejbVersion>
            </configuration>
    </plugin>
     
    <!-- war plugin -skinny wars mode! -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <version>${war-plugin-version}</version>
      <configuration>
            <failOnMissingWebXml>false</failOnMissingWebXml>
            <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
            <archive>
                    <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
            </archive>
            <webResources>
                    <resource>
                            <filtering>true</filtering>
                            <directory>src/main/webapp</directory>
                            <includes>
                                    <include>**/web.xml</include>
                            </includes>
                    </resource>
            </webResources>
      </configuration>
    </plugin>

That’s for now

You can  download our minimal sample here (tag post1, bitbucket). At the time being, it seems that we have not completed anything, but eventually defining a clean and concrete parent pom, is going to be the basis for the rest of the work we are going to do in the upcoming posts.

Points to study

  • the maven standard layout
  • the parent pom
  • the importance of dependencyManagement & pluginManagement

 Resources

Paris Apostolopoulos

Paris is a senior software engineer focusing on J2EE development, loves Business process modelling and is keen on software quality challenges. He is passionate about Java and Java communities. He is a co-founder and administrator of the first Java User Group in greece(JHUG.gr) and occasional speaker on meet-ups and seminars and regular blogger. For his contributions and involvement on the Java community he has been awarded the title of Java Champion in 2007 by Sun Microsystems.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
ken
ken
10 years ago

This is a great article. I’m new to Java EE and I was looking for some advice.

On question: Why = pom ?

All example I have seen till now has = war

thanks

ken
ken
10 years ago
Reply to  ken

sorry I was meaning package = pom and package = war

Paris Apostolopoulos
Paris Apostolopoulos
10 years ago

Hello, many thanks for your kind words. If I understand correctly the question is why we choose to package the application in an EAR while most of the examples out there + the new trend is indicating that you can do the same thing with war? In general yes you can use war as the main packaging ‘format’ of your JEE application, but in bigger applications where you have many modules, maybe different wars and multiple wars, the war packing is limiting. EAR is still a valid and ‘generic’ way to package your application. I continue resume today with the… Read more »

WD
WD
10 years ago

Hello Paris! Thanks for this nice post!
I would like to snap a question with you.How to commit this structure in git? Using for example, Egit for eclipse.I have encountered some difficulties in finding the best way to commit a multi module structure in GIT for use in continuous integration with Jenkins.

javapapo
10 years ago

I use a GUI based client SourceTree by Atlassian, which invokes of course my local git installation.

Artur
Artur
9 years ago

Where does “junit-version” property come from? I can see that I can put non existing property there. Is it for the needs of future substitution?

Hans Meyer
Hans Meyer
6 years ago

Cool!

Back to top button