Introduction
In the last days I’ve been working on a Java project template. After reading some inspiring articles, I’ve decided to mix up some of the concepts explained on them with other nice features which they don’t cover, and adding some improvements.
The basics
The idea is to present how to structure a Java multi-module project using maven. So, the project is divided into the following parts:
- main: It contains the main files to build the application, the “Parent” pom
- persistence: The module with the data access components
- common: The inter-module common parts will go here. E.g.- Parsers, Utility classes, etc
- business: Models the business logic of our application
- web: Where the views and the webapp structure will be modeled
Moreover, the project code will be configured with as much annotations as possible, for two reasons, avoid to locate the configuration files in deeply hidden places, and to take advantage of the compliance of Spring and Hibernate with the JSR-330 and JSR-317, respectively.
Multi-module with Maven
The project uses the multi-module feature provided by Maven. It is defined in a “Parent” pom file which is located into the main project, and as we’ll see later it has to be located into the root directory (where all the projects are located). The parent looks like:
<?xml version="1.0" encoding="UTF-8"?> <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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging> <groupId>com.mm.jtemplate</groupId> <artifactId>jtemplate</artifactId> <version>0.1-SNAPSHOT</version> <modules> <module>jtemplate-main</module> <module>jtemplate-common</module> <module>jtemplate-persist</module> <module>jtemplate-module</module> <module>jtemplate-web</module> </modules> <properties> <spring.version>4.0.0.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <!-- Spring 3 dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- Log4j library --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.8.7</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <server>tomcat</server> <path>/jtemplate</path> </configuration> </plugin> </plugins> <finalName>jtemplate</finalName> </build> </project>
The file is structured in two blocks, the first one is used to identify the modules. The second block refers to the dependencies and the needed configuration stuff to construct the project.
How-to build
There is only one required step to be done before building the project with maven normally, copy the “Parent” pom from the main project to the root directory:
cp ./main-module/parentPom.xml ./pom.xml
After this step is done, the project can be build normally with the common maven command:
mvn clean install
And, after a few seconds everything has to be build and on fire!
The components
Entity
package com.mm.model.domain; import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.Id; @javax.persistence.Entity(name="Entity") public class Entity { @Id @GeneratedValue @Column(name="id") private int id; @Column(name="attribute") private String attribute; public Entity(){} public Entity(int id, String attribute) { super(); this.id = id; this.attribute = attribute; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAttribute() { return attribute; } public void setAttribute(String attribute) { this.attribute = attribute; } }
EntityDAO
package com.mm.model.dao.impl; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import com.mm.model.dao.IEntityDAO; import com.mm.model.domain.Entity; @Named public class EntityDAO implements IEntityDAO { @Inject private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void addEntity(Entity entity) { Session session = getSessionFactory().getCurrentSession(); Transaction trans = session.beginTransaction(); session.save(entity); trans.commit(); } public void deleteEntity(Entity entity) { Session session = getSessionFactory().getCurrentSession(); Transaction trans = session.beginTransaction(); session.delete(entity); trans.commit(); } public void updateEntity(Entity entity) { Session session = getSessionFactory().getCurrentSession(); Transaction trans = session.beginTransaction(); session.update(entity); trans.commit(); } public Entity getEntity(int id) { Session session = getSessionFactory().getCurrentSession(); Transaction trans = session.beginTransaction(); List<?> list = session .createQuery("from Entity where id=?").setParameter(0, id) .list(); trans.commit(); return (Entity) list.get(0); } public List<Entity> getEntities() { Session session = getSessionFactory().getCurrentSession(); Transaction trans = session.beginTransaction(); @SuppressWarnings("unchecked") List<Entity> list = (List<Entity>) session.createQuery("from Entity").list(); trans.commit(); return list; } }
EntityService
package com.mm.module.one.impl; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import org.springframework.transaction.annotation.Transactional; import com.mm.model.dao.IEntityDAO; import com.mm.model.domain.Entity; import com.mm.module.one.IEntityService; @Named @Transactional(readOnly = true) public class EntityService implements IEntityService { @Inject IEntityDAO entityDAO; @Transactional(readOnly = false) public void addEntity(Entity entity) { getEntityDAO().addEntity(entity); } @Transactional(readOnly = false) public void deleteEntity(Entity entity) { getEntityDAO().deleteEntity(entity); } @Transactional(readOnly = false) public void updateEntity(Entity entity) { getEntityDAO().updateEntity(entity); } public Entity getEntityById(int id) { return getEntityDAO().getEntity(id); } public List<Entity> getEntitys() { return getEntityDAO().getEntities(); } public IEntityDAO getEntityDAO() { return entityDAO; } public void setEntityDAO(IEntityDAO entityDAO) { this.entityDAO = entityDAO; } }
EntityBBean
package com.mm.web.bbean; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import javax.inject.Inject; import javax.inject.Named; import org.springframework.context.annotation.Scope; import org.springframework.dao.DataAccessException; import com.mm.model.domain.Entity; import com.mm.module.one.IEntityService; @Named("entityBBean") @Scope("session") public class EntityBBean implements Serializable { private static final long serialVersionUID = 1L; @Inject private IEntityService entityService; private int id; private String attribute; private List<Entity> entityList; public void addEntity() { try { Entity entity = new Entity(); entity.setId(getId()); entity.setAttribute(getAttribute()); getEntityService().addEntity(entity); FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Added!", "Message: ")); } catch (DataAccessException e) { e.printStackTrace(); FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "D'oh!", "Message: ")); } } public void reset() { this.setId(0); this.setAttribute(""); } public List<Entity> getEntityList() { entityList = new ArrayList<Entity>(); entityList.addAll(getEntityService().getEntitys()); return entityList; } public IEntityService getEntityService() { return entityService; } public void setEntityService(IEntityService entityService) { this.entityService = entityService; } public void setEntityList(List<Entity> entityList) { this.entityList = entityList; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAttribute() { return attribute; } public void setAttribute(String attribute) { this.attribute = attribute; } }
index.xhtml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"> <h:head> <title>Welcome to JTemplate</title> </h:head> <h:body> <p:messages></p:messages> <h:form> <table> <tr> <td><h:outputLabel for="id" value="Id : " /></td> <td><p:inputText id="id" value="#{entityBBean.id}" disabled="true"> <f:converter converterId="javax.faces.Integer" /> <p:ajax event="blur" update="idMsg" /> </p:inputText> <p:message id="idMsg" for="id" display="icon" /></td> </tr> <tr> <td><h:outputLabel for="attribute" value="Attribute : " /></td> <td><p:inputText id="attribute" value="#{entityBBean.attribute}"> <f:validateLength minimum="5" /> <p:ajax event="blur" update="attributeMsg" /> </p:inputText> <p:message id="attributeMsg" for="attribute" display="icon" /></td> </tr> <tr> <td><p:commandButton id="addUser" value="Add" actionListener="#{entityBBean.addEntity}" ajax="false" /></td> <td><p:commandButton id="reset" value="Reset" actionListener="#{entityBBean.reset}" ajax="false" /></td> </tr> </table> Elements: <p:dataTable id="entities" var="entity" value="#{entityBBean.entityList}" style="width: 10%"> <p:column> <f:facet name="header"> <h:outputText value="ID" /> </f:facet> <h:outputText value="#{entity.id}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="Name" /> </f:facet> <h:outputText value="#{entity.attribute}" /> </p:column> </p:dataTable> </h:form> </h:body> </html>
Where is the code?
Feel free to fork the code from https://github.com/miquelmillan/jtemplate
References
– http://www.javacodegeeks.com/2012/04/jsf-2-primefaces-3-spring-3-hibernate-4.html
– http://www.mkyong.com/maven/how-to-create-a-web-application-project-with-maven/
– http://www.mkyong.com/maven/how-to-deploy-maven-based-war-file-to-tomcat/
– http://books.sonatype.com/mvnex-book/reference/multimodule.html