Maven Multi-Module Structure for Enterprise Java Projects (Best Practices)

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 and it’s effectiveness.

It’s worth investing some time on application structure for big projects (especially Java EE). If not, it’s cannot be changed at the end.

It’s important to understand the application structure and the underlying build tools when you start working on a project.

Maven might be wise choice because it’s helps you build a better project quickly and effectively.


Maven helps in the following areas :

  • Making the build process easy
  • Providing a uniform build system
  • Providing quality project information
  • Providing guidelines for best practices development
  • Allowing transparent migration to new features

Best practices (maven’s) for development

  • Keeping your test source code in a separate, but parallel source tree
  • Using test case naming conventions to locate and execute tests
  • Have test cases setup their environment and don’t rely on customizing the build for test preparation.

Maven is designed to be flexible, but only to an extent. So, using maven in your project means, you need to reorganize your project (if not in good shape) and adhere to the maven’s conventions.

Random Quote :

“It is good to break conventions in your life and in your coding, but never with Maven.”


 Organizing Style

There are number of ways you can organize your project’s sub-modules.

  • Single Bulk Module
  • Module by Class Type
  • Module by Functionality Area

1) All the modules can be grouped together as a single bulk project. But it’s not recommended anyway.

2) Module by class type : Project can be splitted into sub-projects/modules. And each module are used to group together all classes that comprise, but are not limited to, a layer in the project’s architecture. For example, a module could contain all classes that make up the project’s service or persistence layers or a module could contain all the model class (i.e., jpa or entity beans).

3) Modules by functionality area : Project’s sub-modules are organized by functional area (component based) i.e, vertical slice of the application including model beans, service layer, repositories etc..

Example for ‘Module by class type’:

  • app-model
  • app-utils
  • app-repository
  • app-services
  • app-web
  • app-ear

Example for ‘Module by functionality’:

  • app-utils
  • app-user
  • app-audit
  • app-auth
  • app-integration
  • app-web
  • app-ear

It’s always necessary for each module to have it’s own unit tests.

Pros and Cons of Class Type :

+ Pretty maintainable in that you always known where to find stuff
+ Build order is very straight forward
Circular dependencies
Classes with totally different responsibilities are all mixed up together making it difficult to re-use functionality in other projects

Pros and Cons of Functionality Type :

+ Modules are highly decoupled
+ It’s far simpler to re-use a functional area of code in other projects
Build order might be complex because of its dependencies

You may have noticed that both of them are not 100% perfect.

Also there are few modules which are repeated in both these types in the project. Because it’s always wise to keep the necessary things together i.e., creating a separate database module allows you to change your project’s database implementation fairly easily, which may make testing easier in some circumstances and likewise, having a separate web module allows you to re-skin your code easily.

At the end of the day, it really depends on the need of the project and it’s existing structure. And you can also mix-match both these types, if helps to solve your problem effectively.

Generating and Compiling Java Classes using Java Compiler API

Steps :

  • Construct JavaFileObject from any source (i.e, here, from sourceCode String) and make it to iterable object
  • Get the Java System Compiler
  • Create a compiler task using Compiler.getTask(), (if required create the task with diagnostic collection to get compilation errors)
  • Execute the Compiler Task (compile it).

Source Code :

import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Locale;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class CompileDynamicClasses {

static String sourceCode = "class DynamicClass{" + "public static void main (String args[]){"
+ "System.out.println (\"Hello, Dynamic Class!\");" + "}" + "}";

public static void main(String[] args) {

// Construct a JavaFileObject from source code
SimpleJavaFileObject fileObject = new DynamicJavaSourceCodeObject("DynamicClass",
sourceCode);

Continue reading "Generating and Compiling Java Classes using Java Compiler API"

Mobile App Development with J2ME & EclipseME Plugin

To develop mobile app, you basically need the J2ME enabled IDE. I preffer Eclipse IDE which is even better then NetBeans IDE.

EclipseME is an Eclipse plugin that can be used to simplify the development of J2ME MIDlets using eclipse.

You need to install EclipseME plugin in your Eclipse IDE :

Open the Eclipse IDE and go to Help –> Install New Software, Enter the following URL in the ‘Work with’ text box

http://eclipseme.org/updates & click ‘Add’ button.

This will prompt an window to add repository & give some name like ‘EclipseME Updates’ & then press ‘ok’.

Download the Wireless Toolkit(WTK) from

http://www.oracle.com/technetwork/java/download-135801.html

To install the WTK,

chmod +x sun_java_wireless_toolkit-2.5.2_01-linuxi486.bin.sh

./sun_java_wireless_toolkit-2.5.2_01-linuxi486.bin.sh

Choose the JDK Path like /usr/java/bin & Installation Path like /opt/apps/WTK

Then run the ktoolbar (/opt/apps/WTK/bin/ktoolbar)

Open the eclipse & click new project –> J2ME MIDlet Suite

Go to Preferences –> J2ME –> Device Management

Import the devices from the Installation Path & Apply the changes.

In Project Explorer & click the src package from HelloWorld Project & right click it to add a java class.

Add the following code into it.

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

public class HelloWorld extends MIDlet

implements CommandListener {

private Form mMainForm;

public HelloWorld() {

mMainForm = new Form("HelloWorld");

mMainForm.append(new StringItem(null, "Hello, World!"));

mMainForm.addCommand(new Command("Exit", Command.EXIT, 0));

mMainForm.setCommandListener(this);

}

public void startApp() {

Display.getDisplay(this).setCurrent(mMainForm);

}

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}

public void commandAction(Command c, Displayable s) {

notifyDestroyed();

}

}

Then go to run configuration & select the J2ME & add the configuration you want and run it.

You can this via the Wireless toolkit,

The output is displayed in the Device Emulator.