Maven wasn’t very popular and wide used when it was first released, but after version 2, it had gain lots of traction amount Java developers and it then became widely used as a project build and management tool not only for private projects, but we can also see that there are a tremendously large amount of open source projects being managed, maintained and build by Maven.

As popular as it may seem, but unfortunately, it might not be easily learned as certain concepts are definitely foreign (if I may use this word) especially for folks migrating from Apache Ant, because Maven is not only just a build tool, but it is termed as a software project management tool as some may say. Yes, I’ve been through the pain of migration from Ant to Maven…painful to just clear the fog of just understanding what Maven truly is about, had spent lots and lots of hours understanding its concepts and directory structure; getting it to build my Java project properly and let’s not mentioned about getting it deploy (install in Maven’s terminology) SUCCESSFULLY to the targeted Application Server, solving dependency issues and using the right plugin…Phew! That is the very core reason of my motivation to write this article and hopefully it could save someone’s time that happened to be going through the pain of Maven.

Let’s not be negative, Maven when done right, is a beauty of its own and there are many advantages to it.

Objective & Targeted Readers

This series “Building and Deploying Java EE EAR with Maven to Java EE Application Server” will be written in parts. I’ll just begin with getting the build directory structure right (only for the Java EE EAR file for now), the next other parts will be about where to place the source codes and the deployment to major Application Servers like Glassfish, JBoss, WebLogic and any other major Application Server in the market that I can find a solution to deploy the EAR through Maven. I’ll try to document as much as short but precise as possible.

I’m writing this specifically for readers who are struggling with the migration from Ant to Maven. But having said that, this series will not be the introduction of Maven and what is it used for as there are already many documentations and web sites about that. But if you are a Java EE developer, have read and knew what Maven is, had at least seen what’s inside a pom.xml file but no idea how to meddle with it, or had at least explored its commands but having a hard time to just find a workable directory structure or ways to lay the proper foundation for your project (with unit tests and integration tests) and find it difficult to even deploy your project to a specific App Server, the articles in this series is definitely for you. Let’s begin.

Introduction to Maven’s Java EE EAR Directory Structure

Aligning Expectations

Unlike Ant, where by you could freely script the build.xml file to accommodate your development and deployment requirements – asking it to pick up and pack your files from whichever source directories, resource directories or other facilitating file directories that you’ve made and specified; Maven on the other hand works with predefined directory structure specified by Maven as it goes along with the song “convention over configuration”. The POM.xml file in Maven pretty much defines the project structure, which dependency (external jar(s)/libraries from other projects including open source ones) from the local or remote repository that it needs, plus plugins that the project would require. A Maven project will include modules and sub-modules. As I have mentioned earlier, Maven is more than a build tool, it’s a project build, maintenance and management tool.

Maven’s Java EE EAR Directory Structure

Maven works with predefined directory structure for your source codes, application resource files, unit test(s), integration-test and even reports. This is a good thing considering that it standardizes the directory path and naming convention so that other developers who are currently or in future maintain the software project will know where to look for the files when they are involve with the project.

To give you an idea, I will build a demo project for this tutorial, let’s call it DummyDemoJavaEE5 (you may use this for your Java EE 6 application as well). In this demo project, it will include the following modules:

  • DummyDemo-ejb – a module where you put your EJBs (codes and unit tests)
  • DummyDemo-web – a module for web presto files like html, css, javascripts and front controller classes (codes and unit tests)
  • DummyDemo-api – a module for common used codes such as utilities, helpers, tools etc. specifically for the project (codes and unit tests)
  • DummyDemo-appclient – a module for Enterprise App Client (codes and unit tests)
  • DummyDemo-ear – a module specifically to package everything to an EAR file for deployment and to access the app server
  • integration-test – Lastly, a module solely existed for integration tests (not unit tests). This is where you place all of the integration test codes in this module.

You may not use every module in your project as describe as the above, for example, some projects will not need the Enterprise App Client. You may exclude any of them in your actual project. But for now, this is quite a good repertoire of modules for a Java EE project. The below shows the directory structure for the mentioned modules. Do take note on the folders for your source codes, unit tests and integration tests, at the same time, where to place the pom.xml for their respective modules…this is how it works in Maven. You may create them manually or you can use one of the handy command in Maven call archetype:generate, which we’ll go through it later.

** Directories are highlighted in BOLD

DummyDemoJavaEE5 (The root folder)
    |---project (contains the core enterprise application codes with the 
    |    |       below modules)
    |    |---DummyDemo-ear (used for producing the EAR file - no codes here
    |    |    |             please...)
    |    |    |---pom.xml (The pom file that defines what is to be included
    |    |                 in the EAR)
    |    |
    |    |---DummyDemo-ejb (contains codes for EJBs)
    |    |    |---src
    |    |    |    |---main
    |    |    |    |    |---java (this is the folder where you should put
    |    |    |    |              your EJB codes - with package folders)
    |    |    |    |
    |    |    |    |---test
    |    |    |         |---java (this is the folder where you should put
    |    |    |                  unit test that has to do with DummyDemo-ejb
    |    |    |                   - with package folders)
    |    |    |             
    |    |    |---pom.xml (The pom file that defines the DummyDemo-ejb
    |    |                 module as packaging type "ejb" with the needed 
    |    |                 maven dependencies)
    |    |
    |    |---DummyDemo-web (contains web presto stuff like
    |    |    |             JSP, JSF, CSS, JS, etc.)
    |    |    |
    |    |    |---src
    |    |    |    |---main
    |    |    |    |    |---java (this is the folder where you
    |    |    |    |    |         should put your servlet, JSF 
    |    |    |    |    |         or MVC related codes - with
    |    |    |    |    |         package folders)
    |    |    |    |    |
    |    |    |    |    |---webapp (this is the folder for the
    |    |    |    |          |     JSPs, xhtml, css, javascripts)
    |    |    |    |          |
    |    |    |    |          |---WEB-INF
    |    |    |    |                |---web.xml (here's you should define
    |    |    |    |                             your web.xml file)
    |    |    |    |---test
    |    |    |        |---java (this is the folder where you should put
    |    |    |               unit test that has to do with the classes in 
    |    |    |               DummyDemo-web - with package folders)
    |    |    |               
    |    |    |---pom.xml (The pom file that defines the DummyDemo-web 
    |    |                 module as packaging type "war" with the needed
    |    |                 maven dependencies)
    |    |
    |    |---DummyDemo-api (contains commonly used classes as part of the 
    |    |    |             library)
    |    |    |
    |    |    |---src
    |    |    |    |---main
    |    |    |    |    |---java (this is the folder where you should put
    |    |    |    |              codes e.g. utility codes, parsers, etc.
    |    |    |    |              - with package folders)
    |    |    |    |
    |    |    |    |---test
    |    |    |         |---java (this is the folder where you should put 
    |    |    |                      unit test that has to do with 
    |    |    |                      DummyDemo-api - with package folders)
    |    |    |
    |    |    |---pom.xml (The pom file that defines the DummyDemo-api
    |    |                 module with the needed maven dependencies)
    |    |    
    |    |---DummyDemo-appclient (contains codes for
    |    |    |                   Enterprise Application Client)
    |    |    |
    |    |    |---src
    |    |    |    |---main
    |    |    |    |    |---java (this is the folder where you
    |    |    |    |              should put your codes for the
    |    |    |    |              Enterprise Application Client
    |    |    |    |              - with package folders)
    |    |    |    |---test
    |    |    |        |---java (this is the folder where 
    |    |    |            you should put your unit test that 
    |    |    |            has to do with DummyDemo-apiclient
    |    |    |            - with package folders)
    |    |    |
    |    |    |---pom.xml (The pom file that defines the DummyDemo-appclient 
    |    |                 module as packaging type "app-client" with the 
    |    |                 needed maven depencencies)
    |    |
    |    |---pom.xml (pom file for project folder)
    |---integration-test (contains only integration test classes)
    |    |---src
    |    |    |---test
    |    |        |---java (this is the folder where you 
    |    |                  should put your integration 
    |    |                  tests - with package folders)
    |    |
    |    |---pom.xml (The pom file that defines the integration-test 
    |                 module as with the needed maven dependencies 
    |                 for running integration tests)
    |---pom.xml (root pom file)

These directories are what you should expect from a decent Java EE project being packaged in an EAR as a target deployment file format later. Since the name of the project is DummyDemoJavaEE5, let’s make DummyProbeJavaEE5 as the root folder for the rest of the sub-modules. Next, under the DummyProbeJavaEE5 root project folder, what we could do is to have two separated folders, one is called project, which consists of the core contents of the modules (that includes source codes, resource files and unit tests – yes, only unit tests, not integration tests) and the other folder is called integration-test, which only host integration test codes as the name implies.

This is a clean separation and why do we do that? Because we would not want the integration test codes to be part of the build life cycle of the core project modules every time when we need to compile and deploy to the app servers; but, when the need arise for integration tests to be executed, it could be invoked independently. Even though it is separated, the project codes’ dependency for the integration test is not broken as we can define that in the pom.xml file. I’ll leave the discussion of the contents of the pom.xml files to the next part of the series.

Creating The Directories Through Maven archetype:generate Command

The Maven’s archetype:generate command will pre-generate the directory modules, sub-modules and their respective pom.xml files. This will save you time and reduce much error against manual creation. Of course, this is not fool proof as the pom.xml files will have to be edited later to include dependencies and other plugins that are necessary.

To use Maven’s archetype:generate command for creating the project structure above, follow the below steps. Before you start, just make sure that the maven’s mvn command is in the path. Use the command prompt or terminal to carry out the below steps.

Creating the “DummyDemoJavaEE5” project root directory

  1. Since the demo project name is DummyDemoJavaEE5, log onto the terminal and type “mvn archetype:generate“. This command will list all of the archetypes available in Maven and from version 3 onwards, it has more than 600 archetypes to choose from.

    What you need to do now is to filter the archetype for root directory, to do this, just type: “org.codehaus.mojo.archetypes:pom-root” at the prompt, it shall filter only one archetype which is org.codehaus.mojo.archetypes:pom-root. It will return something like this:

    1: remote -> org.codehaus.mojo.archetypes:pom-root (Root project archetype for creating multi module projects)

    type “1” to to proceed.

  2. Next, it will ask you to choose the version of the archetype, just accept, the default, which will always refer to the latest version.
  3. Next, it will ask you to enter the groupId. The groupId is a unique name that identifies your project across all projects that all modules within this project should share as common. I’m going to use “com.developerscrappad” here as an example, you may use your company’s package name such as com.mycompany, etc. as the groupId. Once you’ve decided on this, it has to be the same across the any modules that you want to have in this project.
  4. After keying in the groupId, it will then ask you for the artifactId. The artifactId is the name of the project/module, if not, it is commonly use as the name of the jar file, the war file or the ear file. Since we are creating the root directory for a new project, just enter the name of the project “DummyDemoJavaEE5” as the artifactId.
  5. Next, it will ask for version number, follow by the package name defaulted to the groupId as you have entered, just accept them by default and the root directory structure will be created. Once done, you should be able to see the “DummyDemoJavaEE5” directory and within it, it will have a pom.xml file.

The archetype that you’ve used just now is to create the root pom (Project Object Model). The root pom is always used to encapsulate any modules within it and make it look as a whole. A root pom can consists of other root pom(s) and other modules within the directory.

Creating the “project” directory

Now that you know how to use the archetype:generate command, we still need to create the rest of the directories and modules. Next, we need to create the project directory, which is where you put all of the module codes in it. Please change your working directory into DummyDemoJavaEE5 ( <path>/DummyDemoJavaEE5/ ) and do the same like what you did to create the root project directory DummyDemoJavaEE5. Do use the same archetype as you did and follow the below parameters:

  • archetype: org.codehaus.mojo.archetypes:pom-root
  • groupId: com.developerscrappad
  • artifactId: project
  • Version & package: accept the default values

Once done, you should be able to see a generated pom.xml within the project directory.

Creating the “DummyDemo-ejb” module directory for EJBs and other back-end codes

Next, change the working directory into project directory ( <path>/DummyDemoJavaEE5/project/ ). Now, we’ll make a module specifically for your EJBs. This module is specifically used to place your entity classes, session beans, message-driven beans and other back-end related codes. To achieve this, we’ll have to use another archetype call org.codehaus.mojo.archetypes:ejb-jee5 instead of pom-root (yes, you can use this for Java EE 6). Follow the below:

  1. Once you are in the <path>/DummyDemoJavaEE5/project/ directory, type “mvn archetype:generate” and type the filter “org.codehaus.mojo.archetypes:ejb-jee5“:
    1: remote -> org.codehaus.mojo.archetypes:ejb-jee5 (-)

    Just type “1”, the number of the selection.

  2. For the rest of the parameters, just follow the below:
    • groupId: com.developerscrappad
    • artifactId: DummyDemo-ejb
    • Version & package: accept the default values

Once done, you should be able to see the DummuDemo-ejb directory ( <path>/DummyDemoJavaEE5/project/DummyDemo-ejb/ ) and within it, the pom.xml file will be created as well. You may have multiple EJB modules using the same way to generate them if you decide to introduce separation of business process instead of lumping all EJBs into one module in your future project.

Creating the “DummyDemo-api” module directory for commonly used classes that pack as a jar/library

Sometimes, you may have some commonly used classes through out the project such as utility classes, helpers, tools or parsers that you want to put them into a jar file so that other modules could use it. Just follow the below:

  1. In the working directory of project ( <path>/DummyDemoJavaEE5/project/ ) perform the “mvn archetype:generate” command.
  2. When ask to filter the archetype, type: “org.apache.maven.archetypes:maven-archetype-quickstart“, you should get something like:
    1: remote -> org.apache.maven.archetypes:maven-archetype-quickstart (An archetype which contains a sample Maven project.)

    just select it.

  3. For the rest of the parameters, just key in the below:
    • groupId: com.developerscrappad
    • artifactId: DummyDemo-api
    • Version & package: accept the default values

Once done, the module directory DummyDemo-api will be created with the pom.xml file inside of it. This is the place where you put your commonly used codes.

Creating the “DummyDemo-web” module directory for JSFs, JSPs, MVCs and other web presentation related files

The DummyDemo-web is the web application module for the project. To create this, please make sure that the working directory is still on project ( <path>/DummyDemoJavaEE5/project/ ). We need to use the org.codehaus.mojo.archetypes:webapp-jee5 archetype. Just create this with the archetype:generate command, filter the archetype and you should see something like:

1: remote -> org.codehaus.mojo.archetypes:webapp-jee5 (-)

just create the module with like what you’ve done in the previous steps with the below details:

  • archetype: org.codehaus.mojo.archetypes:webapp-jee5
  • groupId: com.developerscrappad
  • artifactId: DummyDemo-web
  • Version & package: accept the default values

Once the module was created, the pom.xml file will be generated and the rest of the module directory structure specifically for JEE webapp, that includes the WEB-INF directory, the sample web.xml and a sample index.jsp file.

Creating the “DummyDemo-appclient” module directory for Enterprise Application Client

Not many enterprise application will need an Application Client, but if you need it in your project, these are the steps to create the Enterprise Application Client module. Here, let’s call it DummyDemo-appclient. Do this in the project ( <path>/DummyDemoJavaEE5/project/ ) working directory, we need to use the archetype call “org.codehaus.mojo.archetypes:appclient-jee5“. Just use the archetype:generate command the same way with the details below:

  • archetype: org.codehaus.mojo.archetypes:appclient-jee5
  • groupId: com.developerscrappad
  • artifactId: DummyDemo-appclient
  • Version & package: accept the default values

Once completed, not only that the pom.xml file will be generated, but this module includes a sample file as the main class for the Enterprise Application Client.

Creating the “DummyDemo-ear” module for packing the EAR file

Now that we have the rest of the Java EE core modules, it is time to create the DummyDemo-ear module solely for packaging the EAR file and it is also in this module that we will define the deployment instructions in the pom.xml file. I’ll leave the discussion in the later part of the series, because different app server will require different configuration.

Anyway, to create the DummyDemo-ear module, we need to use the org.codehaus.mojo.archetypes:ear-jee5 archetype. In the working directory of project ( <path>/DummyDemoJavaEE5/project/ ), just use the “mvn archetype:generate” command with the below details:

  • archetype: org.codehaus.mojo.archetypes:ear-jee5
  • groupId: com.developerscrappad
  • artifactId: DummyDemo-ear
  • Version & package: accept the default values

There is nothing much to explore inside the DummyDemo-ear module directory for now after creating. But nevertheless, this module is important for deployment later on.

Creating the “integration-test” module for, well…integration tests

Lastly, we’ll now create the integration-test module, which is solely for any integration tests classes. You may place your unit tests files in the previously created modules, but as time passes, I find that having a separate module solely for integration tests will be much better as tests could be run independently without having to induce skip flags to maven and will not run prematurely before the the EAR is being deployed to the application server.

Creating the integration-test module is easy. Just change the working directory out from the project directory and back to the DummyDemoJavaEE5 root folder ( <path>/DummyDemoJavaEE5/ ), use the “org.apache.maven.archetypes:maven-archetype-quickstart” archetype as you execute the “mvn archetype:generate” command. As for the rest of the parameters, the details are below:

  • archetype: org.apache.maven.archetypes:maven-archetype-quickstart
  • groupId: com.developerscrappad
  • artifactId: integration-test
  • Version & package: accept the default values

Once complete, you have a separate integration-test module solely for your integration test classes. In fact, you may use the same approach to create a functional test module to run Selenium related tests if you wish for your future projects.

To Be Continued…

If you have followed through the above steps, you should be able to produce all of the module layout of the project, plus the module for integration-test. In my opinion, using Maven’s archetype:generate command to generate the project and module layout is very much faster than by doing it manually. It generates the pom.xml file, although it is not complete, still it is much faster and less error than crafting it by your own.

We are far from finish. I will leave the discussion of what contents to be included in the pom.xml file in the next part of the series. As for the next part, I’ll be writing about where to put the codes and what are the necessary plugins and dependency that is to be included in the pom.xml files. So, stay tuned.

Proceed To Part 2:

Building and Deploying Java EE EAR with Maven to Java EE Application Server (Part 2) – Where to put your source codes and pom.xml (EJB, MDB, Web & Enterprise Application Client)

Related Articles:

Max Lam
About the Author

Born and currently resides in Malaysia, a seasoned Java developer whom had held positions as Senior Developer, Consultant and Technical Architect in various enterprise software development companies.

Related Posts

(adsbygoogle = window.adsbygoogle || []).push({}); So far, we’ve covered Maven deployment of...

We’ve discussed the Deployment to Glassfish 3.x in Part 3 of the series. In this article, we’ll do...

In Part 1 and Part 2 of this series, we have discussed about the directory layout and the Java EE...