Auto Deploy Spring Gradle Application as Tomcat ROOT in Production Environment

In previous post, we discussed about Spring Boot project using AngularJS. I hope you have been familiar with Spring Boot and AngularJS architecture of that project hosted on Github.

Now the next step is to make the app production ready for deploying on Tomcat 8. Please note that this tutorial is Tomcat 8 specific and not tested on older version of tomcat.

With “Production Ready” goal, I target following requirements:

  1. Making your application as ROOT application, so that when you access http://localhost:8080, it will show your app.
  2. When you need to upload a new build (war), you just have to execute build command, gradle build, in your code base. That’s it. Tomcat should automatically pick the war file and deploy it without restarting.

Creating war

The first thing is building war and for that you need to specify following in build.gradle:


----------
----------

apply plugin: 'war'

war{
 baseName = 'boot-demo'
 version = '0.1.0'
}

----------

Configuring Tomcat

Configuring tomcat is easy and just 2 step process:

  1. Add following ROOT.xml file in your tomcat’s conf>Catalina>localhost directory
    <Context 
      docBase="<Path to your war>" 
      path="" 
      reloadable="true" 
    />
    

    Note that in the case of github demo spring project discussed in previous tutorial, the war file will be created in build>lib folder. So you just need to specify that war location. For e.g. my code base is in D:/git/boot-demo then docBase would be D:/git/boot-demo/build/lib/boot-demo-0.1.0.war.

    Setting build folder’s lib path on docBase have advantage. Whenever you want to upload the build, you just need to pull all the changes from git repository and execute gradle build. This will create a new war under build>lib and tomcat will pick it.

  2. Now for enabling tomcat to pick the war from docBase and deploy, you need to set deployXML to true in Host configuration. For that open server.xml from conf folder of tomcat and add deployXML="true" to Host tag. Your Host tag will look as follow:
    <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true" deployXML="true">
           
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log" suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
    
    </Host>
    

    Following is written on tomcat security considerations:

    In a hosted environment where web applications may not be trusted, set the deployXML attribute to false to ignore any context.xml packaged with the web application that may try to assign increased privileges to the web application. Note that if the security manager is enabled that the deployXML attribute will default to false.

    So by default deployXML is set to false. Which you need to set to true. If you have your own hosted environment then there should not be any security concerns.

That’s it. With this much configurations, your app will be at root of the tomcat and accessible at http://localhost:8080 and it will be auto deployed whenever you create new war with gradle build

Spring Boot with AngularJS using Gradle – with Spring Security and Auditing

 

Why Spring Boot

Gone are the days when you need to do lot of configurations in xml files for Spring project. Spring Boot favors convention over configuration, which gives you edge over other frameworks, considering the less time in get you up and start developing project.

Now one question came to my mind, if we talk about convention over configuration, then why not use Grails which is also running on JVM. I looked into Grails 3 , which is having angular profile built in. So it will just setup most of the things for you and it is very good. But I personally feels that due to smaller developer community, you will have less support in case if you are stuck. On other hand, Spring has large community and large scale project have been built on top of Spring. So Spring is proven. Otherwise Grails is also a good choice and I am sure you can scale the project when it grows.

I personally decided  to go ahead with Spring Boot and in this guide we will create a Single Page Application (SPA) in Spring Boot using Angular JS.

What you will need

What features this project will be having

  • Single Page Application (SPA) using Angular UI Router.
  • Client resources (CSS and JS) dependency management using this gradle plugin.
  • Asset Pipeline for compressing asset files and for asset chaining. This helps for module wise developement using Angular.

Update – 26th May 2016

Added following feature to the project. Check Github Project for details.

How to build  this Spring boot project with Angular using Gradle

If you are familiar with Spring Boot and Angular, then you can skip this and start exploring the project downloading from Github. Otherwise you can go through following steps:

  1. Once you downloaded STS, add following vm arguments in STS.ini file and start STS
    -vm
    C:/Program Files/Java/jdk1.8.0_77/bin/javaw.exe

    Noe that, I have used mine jdk installation. You should use the path of your jdk 1.8 installation directory.

  2. Now add gradle plugin to STS. For this go to dashboard tab > IDE EXTENSION > Search for Gradle and follow the instructions to install gradle.
  3. With gradle you can also install groovy support, as gradle developed on groovy. Though it is not required.
  4. Once installed gradle, click on File > new > Project > Gradle (STS ) Project. Add the details as shown in following screenshots.
    1.png
    2.png
  5. Now go to https://spring.io/guides/gs/spring-boot/  and copy build.gradle file and replace it with your build.gradle.
  6. change the baseName as boot-demo in your build.gradle
  7. Delete org.gradle package from main/java, test/java and resources. It is not required.
  8. Now create package structure for project as follow:
    • com.boot //For application class
    • com.boot.config //For configuration class
    • com.boot.controller
    • com.boot.model
    • com.boot.repository
    • com.boot.service
  9. Now we will do following modification related to dependencies in build.gradle:
    • Remove jetty and include tomcat
    • Add Spring Data JPA dependency
    • Add MySql dependency
    • Add Flyway dependency for handling database creation/migration
    • Add asset-pipeline dependencies and plugin for managing module wise development using angular (Chaining and compressing of assets).
    • Add plugin to manage javascript and css dependencies. And specify required dependencies like jQuery, angular, materializecss etc.

    With above changes, build.gradle will look as follow:

    buildscript {
        repositories {
            mavenCentral()		
            mavenLocal()
    		maven { url &quot;https://repo.grails.org/grails/core&quot; }
        }
        dependencies {
            classpath(&quot;org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE&quot;)		
    		classpath(&quot;org.codehaus.groovy:groovy:2.4.6&quot;)
    		classpath(&quot;com.bertramlabs.plugins:asset-pipeline-gradle:2.7.4&quot;)
    		classpath(&quot;gradle.plugin.com.boxfuse.client:flyway-release:4.0&quot;)			
        }
    }
    
    plugins {
        id 'com.craigburke.client-dependencies' version '1.0.0-RC2'
    }
    
    apply plugin: 'groovy'
    apply plugin: 'java'
    apply plugin: 'eclipse'
    apply plugin: 'idea'
    apply plugin: 'spring-boot'
    apply plugin: 'asset-pipeline'
    apply plugin: 'org.flywaydb.flyway'
    apply plugin: 'war'
    
    jar {
        baseName = 'boot-demo'
        version =  '0.1.0'
    }
    
    repositories {
        mavenCentral()
    	mavenLocal()
    	maven { url &quot;https://repo.grails.org/grails/core&quot; }
    	jcenter()
        maven { url &quot;http://repo.spring.io/libs-snapshot&quot; }
    }
    
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    
    configurations {
        providedRuntime
    }
    
    dependencies {    
        compile(&quot;org.springframework.boot:spring-boot-starter-web&quot;)         
    	providedRuntime(&quot;org.springframework.boot:spring-boot-starter-tomcat&quot;)
        compile(&quot;org.springframework.boot:spring-boot-starter-actuator&quot;)
        compile(&quot;org.springframework.boot:spring-boot-starter-data-jpa&quot;)
        compile(&quot;mysql:mysql-connector-java&quot;)
    	compile(&quot;org.flywaydb:flyway-core:4.0&quot;)
    		
        compile(&quot;org.codehaus.groovy:groovy&quot;)
        testCompile(&quot;org.springframework.boot:spring-boot-starter-test&quot;)
    	compile(&quot;com.bertramlabs.plugins:asset-pipeline-spring-boot:2.7.4&quot;)
    	compile(&quot;javax.inject:javax.inject:1&quot;)
    	compile(&quot;org.springframework.boot:spring-boot-starter-security&quot;)
    	compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate4', version: '2.7.4'
    	
        testCompile(&quot;junit:junit&quot;)
    }
    
    task wrapper(type: Wrapper) {
        gradleVersion = '2.3'
    }
    
    clientDependencies {
    
    	bower {
            'jquery'('2.2.x', from:'dist') { 
                include 'jquery.js'
    			include 'jquery.min.js'
            }
    		'materialize'('0.97.x', from:'dist', into:'materialize'){
    			include &quot;**&quot;
    		}		
    		
        }
    	
    	npm {
    		'angular'('1.5.x', into: 'angular') {
    			include 'angular.js' 
    			include 'angular.min.js'
    		}
    		'angular-resource'('1.5.x', into: 'angular') {
    			include 'angular-resource.js'
    			include 'angular-resource.min.js'
    		}
    		'angular-mocks'('1.5.x', into: 'angular') {
    			include 'angular-mocks.js'
    			include 'angular-mocks.min.js'
    		}		
    		'angular-ui-router'('0.2.18', into: 'angular'){
    			include 'angular-ui-router.js'
    			include 'angular-ui-router.min.js'
    		}
    		'angular-animate'('1.5.x', into: 'angular') {
    			include 'angular-animate.js'
    			include 'angular-animate.min.js'
    		}
    		'angular-cookies'('1.5.x', into: 'angular') {
    			include 'angular-cookies.js'
    			include 'angular-cookies.min.js'
    		}
            
    	}
    
    	
    }
    
    assets {
      minifyJs = true
      minifyCss = true    
    }
    
    flyway {
        driver = 'com.mysql.jdbc.Driver'
        url = 'jdbc:mysql://localhost:3306/demo'
        user = 'root'
        password = 'root'    
    }
    
  10. Now we will add properties file from which spring boot will read various configurations. You can also add environment specific property files, application-test.properties specific to test environment and application-prod.properties specific to production environment.
    logging.level.org.springframework.web=DEBUG
    
    server.port=8080
    
    spring.datasource.url=jdbc:mysql://localhost:3306/demo
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
    spring.datasource.max-active=10
    spring.datasource.max-idle=8
    spring.datasource.max-wait=10000
    spring.datasource.min-evictable-idle-time-millis=1000
    spring.datasource.min-idle=8
    spring.datasource.time-between-eviction-runs-millis=1
    
    flyway.baseline-on-migrate=true
    spring.jpa.hibernate.ddl-auto=false
    
    datasource.flyway.url=jdbc:mysql://localhost:3306/demo
    datasource.flyway.username=root
    datasource.flyway.password=root
    datasource.flyway.driver-class-name=com.mysql.jdbc.Driver
    
  11. Now we need to provide datasource for JPA. For that we will add one configuration class named PersistenceConfiguration.java as follow:
    package com.boot.config;
    
    import javax.sql.DataSource;
    
    import org.springframework.boot.autoconfigure.flyway.FlywayDataSource;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    
    @Configuration
    public class PersistenceConfiguration {
    
    	@Bean
    	@ConfigurationProperties(prefix=&amp;amp;amp;amp;amp;amp;quot;spring.datasource&amp;amp;amp;amp;amp;amp;quot;)
    	@Primary
    	public DataSource dataSource() {
    		return DataSourceBuilder.create().build();
    	}
    
    	@Bean
    	@ConfigurationProperties(prefix=&amp;amp;amp;amp;amp;amp;quot;datasource.flyway&amp;amp;amp;amp;amp;amp;quot;)
    	@FlywayDataSource
    	public DataSource flywayDataSource() {
    		return DataSourceBuilder.create().build();
    	}
    
    }
    
    
  12. Add V1__create_db.sql script under resources/db/migration. When you run the project, Flyway will use this file to create tables defined in this script. For this demo, we only created on table, User:
    CREATE TABLE USER(
      ID INT NOT NULL AUTO_INCREMENT,
      FIRSTNAME VARCHAR(40) NOT NULL,
      LASTNAME VARCHAR(40),
      EMAIL VARCHAR(100) NOT NULL,
      MOBILE_NO VARCHAR(20) NOT NULL,
      PRIMARY KEY (ID)
    );
    
  13. With asset-pipeline, default location of assets is src/assets. So create assets folder under src and inside assets create following folders
      • javascripts
      • stylesheets
      • images

    Note that clientInstall command will be installing dependencies unser assets/vendor.

  14. Now we will create gradle wrapper, so in case someone from team is not having gradle installed then also they can run gradle command. Assuming you have installed gradle in your machine, to create wrapper run following command:
            gradle wrapper

    Not that if you have downloaded this project from Github, then it will already have gradle wrapper.

  15. Now let’s download CSS and JS dependencies. For that run following command:
         gradlew clientInstall

    With this command, it will download all the specified dependecies (of build,gradle) and install in inside our assets folder.

  16. With this, our architecture is ready and now we can start adding angular modules, create controllers in java, create views etc. I have created bootdemo folder inside src/assets/javascripts. We will follow the approach of creating separate folder for each module in our application.
    └── src
        └── assets
            └── javascripts
                └── bootdemo
                    └── user
                        └── controllers
                        └── services
                        └── directives
                        └── templates //all html template files goes here
                        └── bootdemo.user.js //main js file of module.
                        └── routes.js //configuring routes for this module    
    

    Our templates (referenced by ui router)  will fall under src/assets/javascripts/bootdemo/user/templates. We have used DomainServiceFactory.js for CRUD api calls. This file is same as the one comes in Grails Angular profile project.

For more details you can download the project from Github and explore it. If you have any query/issue please reach out to me at ghariaonline@gmail.com.

Customizing Materialize css – changing default theme with Sass

In this article we will discuss how effectively you can use Sass to manage/change multiple themes in your website/cms. I have used materializecss which is very cool and based on Google material design concept.

Sass stands for Syntactically Awesome Stylesheets. It is a style sheet language using which you can program your style sheet by using variables, inheritance, nesting etc. Sass takes these .scss files as input and ganerate actual .css file for you, which is nothing but output of interpreted .scss files.

First of we will setup Sass and then will look into materializecss how we can change the default template design. There are two ways you can use Sass in your project.

  1. Install Sass command line tool and then generate .css file and use that file in your project
  2. Find out maven dependency that actually compiles the .scss files.

In this article we will discuss about first option. The reason is most of the time changing the template of website is mostly rare in real life, like once or twice in a year. And using command line it won’t take more then 5-10 mins.

Here we will discuss for windows platform. You can visit http://sass-lang.com/install where they have details for other platform as well.

Steps to install Sass on windows:

    1. Download latest version of Ruby Installer from http://rubyinstaller.org/downloads/ and install it.
    2. Now add the bin directory of ruby in path. For e.g if Ruby’s home directory is C:\Ruby22-x64\ the add C:\Ruby22-x64\bin to path variable.
    3. Now restart the command prompt and run following command.     gem install sass
    4. If you get any error the try following:     sudo gem install sass.
    5. Sass will be installed in bin directory of Ruby. If  you ave already added bin directory of Ruby in path variable then it will be accessible from any location. You can double check sass installation with following command:     sass -v

Now download materialize css source (Sass version) from http://materializecss.com/getting-started.html. This will contain source .scss files. Now we can modify these files and generate customize materialize css for us. Extract the downloaded source. The extracted source will have folder named sass. In this folder you will find materialize.scss file. This is our source file, from which we generate actual materialize css. To do this again open the command prompt and go to this location of  materialize.scss file. Once in that location, run the following command:

            sass materialize.scss materialize.css

This will create materialize.css which we will use in our project. Note that this is default css provided and we haven’t customized it yet.

For demo purpose I have created simple static web application which you can download from link provided at end this tutorial. Copy the above sass interpreted materialize.css file in css folder of the web application. In this app you will find simple web page, index.html as follow:

<!DOCTYPE html>
<html>
<head>
<meta name="layout" />
<title>Welcome to Materializecss - Sass way</title>

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="css/materialize.css">
<style type="text/css">
body {
	display: flex;
	min-height: 100vh;
	flex-direction: column;
}

main {
	flex: 1 0 auto;
}
</style>

</head>

<body>

	<header>

		<nav>
			<div class="nav-wrapper">
				<a href="#" class="brand-logo">Logo</a>
				<ul id="nav-mobile" class="right hide-on-med-and-down">
					<li><a href="sass.html">Sass</a></li>
					<li><a href="badges.html">Components</a></li>
					<li><a href="collapsible.html">JavaScript</a></li>
				</ul>
			</div>
		</nav>

	</header>

	<main class="grey lighten-4">
	<div class="container">
		<h2>Sign Up</h2>
		<div class="row">

			<form class="col s12">
				<div class="row">
					<div class="input-field col s6">
						<input placeholder="Placeholder" id="first_name" type="text" class="validate"> <label for="first_name">First Name</label>
					</div>
					<div class="input-field col s6">
						<input id="last_name" type="text" class="validate"> <label for="last_name">Last Name</label>
					</div>
				</div>
				<div class="row">
					<div class="input-field col s12">
						<input disabled value="I am not editable" id="disabled" type="text" class="validate"> <label for="disabled">Disabled</label>
					</div>
				</div>
				<div class="row">
					<div class="input-field col s12">
						<input id="password" type="password" class="validate"> <label for="password">Password</label>
					</div>
				</div>
				<div class="row">
					<div class="input-field col s12">
						<input id="email" type="email" class="validate"> <label for="email">Email</label>
					</div>
				</div>
				<div class="row">
				<div class="input-field col s12">
					<button class="btn waves-effect waves-light" type="submit" name="action">
						Submit <i class="material-icons right">send</i>
					</button>
					</div>
				</div>
			</form>

		</div>
		<div class="fixed-action-btn" style="bottom: 125px; right: 150 px;">
			<a class="btn-floating btn-large waves-effect waves-light"><i class="material-icons">add</i></a>
		</div>
	</div>
	</main>
	<footer class="page-footer">
		<div class="container">
			<div class="row">
				<div class="col l4 s12"></div>
			</div>
		</div>

		<div class="footer-copyright">
			<div class="container">
				© 2015-2016 GhariaOnline, All rights reserved. <a class="grey-text text-lighten-4 right"
					href="https://github.com/Dogfalo/materialize/blob/master/LICENSE">Terms and Condition</a>
			</div>
		</div>
	</footer>

</body>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="js/materialize.min.js"></script>

</html>

With the default materialize css, the look will be as follow:

template1.PNG

Now let’s modify the default materialize css. To do this go to the downloaded materialize-src source folder . In this go to the sass>components folder. Here you will find that module vise they have separated the source code in different file. From these files open _variables.scss file. You will find the first Colors section as follow:

/*** Colors ***/
$primary-color: color("materialize-red", "lighten-2") !default;
$primary-color-light: lighten($primary-color, 15%) !default;
$primary-color-dark: darken($primary-color, 15%) !default;
 
$secondary-color: color("teal", "lighten-1") !default;
$success-color: color("green", "base") !default;
$error-color: color("red", "base") !default;
$link-color: color("light-blue", "darken-1") !default;
----
---

Here we will be modifying primary color and secondary color with deep purple theme. To do this comment $primary-color and $secondary-color. And add deep purple shade (#673AB7) as primary color and pink accent shade (#F50057) as secondary color.

The modified Colors section of _variables.scss will be as follow:

 /*** Colors ***/
/*** $primary-color: color("materialize-red", "lighten-2") !default; ***/
$primary-color: color("deep-purple", "lighten-1") !default;
$primary-color-light: lighten($primary-color, 15%) !default;
$primary-color-dark: darken($primary-color, 15%) !default;

/*** $secondary-color: color("teal", "lighten-1") !default; ***/
$secondary-color: color("pink", "accent-3") !default;
$success-color: color("green", "base") !default;
$error-color: color("red", "base") !default;
$link-color: color("light-blue", "darken-1") !default;
-----
---

Now generate a new customized materialize.css from sass command line with same command earlier you used.

            sass materialize.scss materialize.css

Now copy and paste this new materialize.css in css folder of web application. And refresh index.html in browser. The new look will be as follow:

template2.PNG

Isn’t this cool ! We did not change any code of our web application and we changed the whole theme. This will be useful in following scenarios:

  1. You have web application as a product and you are selling to different clients. Now each client has own choice of themes/colors. In this case you can easily change the look in just few tweaks.
  2. After some time, you got request of changing theme of your application in new release.

In such scenarios, it will save lot of time.

Few tips for choosing the color pallet:

  1. Use http://www.sankk.in/material-mixer/ tool to choose the combination:pallet.PNG
  2. Once you choose the combination, search for the class of color code in materialize.css. For e.g my primary color code is #7E57C2. Now I will open _color.scss and find that color code. For #7E57C2, I found deep-purple with lighten-1. So my color function would be color(“deep-purple”, “lighten-1”) in _variables.scss file.
  3. Here we have just focused on _variables.css for changing the theme, but you can achieve more customization by editing other components like _tabs.scss for tabs, _sideNav.scss for side navigation menu etc.

You can download the sample web application from this link following link and play with it.

Spring MVC and Spring Data JPA with EclipseLink, Sitemesh, RESTful Web Service – Annotation based Configuration

This article is about creating a web application which has Spring MVC, Spring Data JPA, EclipseLink as JPA solution, Sitemesh decorator pattern, RESTful Web Service. And this all configuration are JavaConfig Annotation based. There is no XML configuration for Spring. Since Spring 3, Java Configuration features are part on Spring framework but it is less explored.

You can download/pull the whole project from this github repository. In this article we will discuss about important configurations.

Since all the configuration are java based, they are devided in differentjava files. We will cover important configuration.

WebInitializer.java

This calss implements WebApplicationInitializer interface. This interface needs to be implemented in Servlet 3.0+ environments in order to configure the ServletContext programmatically as opposed to the traditional  web.xml based approach. So your web.xml will not have any servlet declaration.


public class WebInitializer implements WebApplicationInitializer{

	private static org.apache.log4j.Logger log = Logger.getLogger(WebInitializer.class);

	public void onStartup(ServletContext servletContext) throws ServletException {

		// TODO Auto-generated method stub
		log.debug(&quot;WebApplicationInitializer started...&quot;);
		AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

		 // Manage the lifecycle of the root application context
	    servletContext.addListener(new ContextLoaderListener(rootContext));
	    servletContext.setInitParameter(&quot;contextConfigLocation&quot;, &quot;&lt;NONE&gt;&quot;);

	    rootContext.register(DBConfig.class);
	    rootContext.register(WebConfig.class);	    

		rootContext.setServletContext(servletContext);

		log.debug(&quot;Starting Dispatcher Servlet.....&quot;);
		ServletRegistration.Dynamic servlet = servletContext.addServlet(&quot;dispatcher&quot;, new DispatcherServlet(rootContext));
		servlet.setLoadOnStartup(1);
		servlet.addMapping(&quot;/&quot;);
		servlet.setMultipartConfig(new MultipartConfigElement(&quot;/img&quot;, 1024*1024*5, 1024*1024*5*5, 1024*1024));
		log.debug(&quot;Started Dispatcher Servlet.....&quot;);

		registerSitemeshFilter(servletContext);

	}

	private void registerSitemeshFilter(ServletContext servletContext){
		log.debug(&quot;Registering sitemesh filter....&quot;);
		FilterRegistration.Dynamic registration = servletContext.addFilter(&quot;sitemesh&quot;, new SitemeshConfig());
		registration.addMappingForUrlPatterns(null, true, &quot;/*&quot;);
		log.debug(&quot;Sitemesh filter Registered....&quot;);
	}

}

Using this class ServletContext will be started and all the servlet (DispatcherServlet in this case) and all the filters (Sitemesh filter in this case) will be loaded

DBConfig.Java

Following is DBConfig.java which contains mainly database related configuration and bean initialization.

@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@EnableJpaRepositories(basePackages={&quot;com.yoursite.repository&quot;}, entityManagerFactoryRef = &quot;em&quot;)
@EnableLoadTimeWeaving
public class DBConfig {

	@Value(&quot;${jdbc.driverClassName}&quot;)
	private String driverClassName;

	@Value(&quot;${jdbc.url}&quot;)
	private String url;

	@Value(&quot;${jdbc.username}&quot;)
	private String username;

	@Value(&quot;${jdbc.password}&quot;)
	private String password;

	@Value(&quot;${eclipselink.persistenceUnitName}&quot;)
	private String persistenceUnitName;

	private static org.apache.log4j.Logger log = Logger.getLogger(DBConfig.class);

	@Bean()
	public DataSource getDataSource() {
		BoneCPDataSource ds = new BoneCPDataSource();
		log.debug(&quot;Driver Name : &quot; + driverClassName);
		try {
			Class.forName(driverClassName);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		log.debug(&quot;DB Url : &quot; + url);
		ds.setDriverClass(driverClassName);
		ds.setJdbcUrl(url);
		ds.setUsername(username);
		ds.setPassword(password);
		ds.setMaxConnectionsPerPartition(5);
		ds.setMinConnectionsPerPartition(2);
		ds.setAcquireIncrement(2);
		return ds;
	}

	@Bean(name = &quot;em&quot;)
	public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
		LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
		em.setDataSource(getDataSource());
		em.setJpaDialect(jpaDialect());
		em.setPackagesToScan(&quot;com.yoursite.model&quot;);
		em.setPersistenceUnitName(persistenceUnitName);
		DatabasePlatform dp = new MySQLPlatform();
		em.setJpaVendorAdapter(getEclipseLinkJpaVendorAdapter());

		//following code will be used for static weaving. Uncomment when creating war.
		/*Map &lt;String, String&gt; propMap = new HashMap&lt;String, String&gt;();
		propMap.put(&quot;eclipselink.weaving&quot;, &quot;static&quot;);
		em.setJpaPropertyMap(propMap);*/

		em.setLoadTimeWeaver(loadTimeWeaver()); //comment this when using static weaving. Mostly in development environment inside eclipse
		return em;
	}

	@Bean
	public EclipseLinkJpaVendorAdapter getEclipseLinkJpaVendorAdapter() {
		EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter();
		vendorAdapter.setDatabasePlatform(&quot;org.eclipse.persistence.platform.database.MySQLPlatform&quot;);
		vendorAdapter.setGenerateDdl(false);
		vendorAdapter.setShowSql(true);
		return vendorAdapter;
	}

	@Bean()
	public LoadTimeWeaver loadTimeWeaver() {
	    return new org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver();
	}

	@Bean
	public PlatformTransactionManager transactionManager() {
		JpaTransactionManager transactionManager = new JpaTransactionManager();
		transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
		return transactionManager;
	}

	@Bean
	public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
		return new PersistenceExceptionTranslationPostProcessor();
	}

	@Bean
	public JpaDialect jpaDialect() {
		return new EclipseLinkJpaDialect();
	}
}

@Configuration indicates that a class declares one or more @Bean methods and will be processed by the Spring container to generate bean definitions . @EnableJpaRepositories will enable Spring Data Jpa and you need to place all your repository interfaces under mentioned basePackages. @EnableLoadTimeWeaving is related to weaving of POJO. You can find out more about weaving at this link. For configuring weaving refer point no 6 below in “Steps to run/deploy project”

Also note that @Value annotation will fetch values from application.properties file. So modify database properties as per your database.

WebConfig.java

This java class contains configuration related to web application.

@EnableWebMvc
@Configuration
// Specifies which packages to scan
@ComponentScan(&quot;com.yoursite&quot;)
@PropertySource(value = &quot;classpath:application.properties&quot;)
// Enables Spring's annotation-driven transaction management capability, similar to the support found in Spring's &lt;tx:*&gt; XML namespace
@EnableTransactionManagement(proxyTargetClass=true)
public class WebConfig extends WebMvcConfigurerAdapter{

	@Bean
	public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
		return new PropertySourcesPlaceholderConfigurer();
	}

	@Bean
	public UrlBasedViewResolver setupViewResolver() {
		UrlBasedViewResolver resolver = new UrlBasedViewResolver();
		System.out.println(&quot;UrlBasedViewResolver........&quot;);
		resolver.setPrefix(&quot;/WEB-INF/views/&quot;);
		resolver.setSuffix(&quot;.jsp&quot;);
		resolver.setViewClass(JstlView.class);
		return resolver;
	}

	@Bean
	MultipartResolver multipartResolver() {
		MultipartResolver resolver = new CommonsMultipartResolver();
		return resolver;
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		System.out.println(&quot;In Resouce Handler&quot;);
	    registry.addResourceHandler(&quot;/resources/**&quot;).addResourceLocations(&quot;/resources/defaultTheme/&quot;);
	}

}


@EnableWebMvc enables Spring MVC, equivalent to <mvc:annotation-driven />. @ComponentScan specify component scanning directives/packages, equivalent to <context:component-scan>. @PropertySource specifies the property file. @EnableTransactionManagement enables Spring’s annotation-driven transaction management capability, similar to the support found in Spring’s <tx:*> XML namespace.

In this class, we have specified UrlBasedViewResolver, which will allow direct resolution of symbolic view names (Strings in Controller) to URLs. This means all your JSPs should be created under /WEB-INF/views and it will be processed by JSTL. When you return a string from Controller method, it will be mapped with respective JSP. We have also added MultipartResolver bean for file upload.

SitemeshConfig.java

This class will configure sitemesh.

public class SitemeshConfig extends ConfigurableSiteMeshFilter {

	private static org.apache.log4j.Logger log = Logger.getLogger(SitemeshConfig.class);

	@Override
	protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
		builder.addDecoratorPath(&quot;/*&quot;, &quot;/WEB-INF/decorators/genericdecorator.jsp&quot;);
		builder.addTagRuleBundle(new Sm2TagRuleBundle());
		log.debug(&quot;Sitemesh Configuration done!&quot;);
	}
}

Here we have specified decorator to be used. Decorator jsp is the one which will be applied to all pages in application. Header, footer, navigation, css, scripts etc which is common to all the pages are part of this. This is like template. Refer genericdecorator.jsp of the project for reference.

GreetingController.java

This is REST Controller. Spring provides easy  RESTful web services. @RestController will do all the job for you. Using Jackson integration,  Rest Controller’s method will parse POJO to JSON and return to client. You can integrate any other JSON framework with spring.

@RestController
public class GreetingController {

	private final PersonService personService;

	@Autowired
	private PersonDataRepository personDataRepository;

	@Autowired
	public GreetingController(PersonService personService) {
		this.personService = personService;
	}

	/*
	 * Returns JSON represents of Person object
	 */
	@RequestMapping(&quot;/greeting/{userId}&quot;)
	public Person greeting(@PathVariable Long personId) {
		return personDataRepository.getOne(personId);
	}
}

Required tools/technologies

  1. Eclipse IDE with Maven
  2. Tomcat 7 or greater
  3. MySql 5.0 or above

Steps to run/deploy project

  1. Download project from github.
  2. Execute yoursite.sql in your MySql database.
  3. In eclipse, choose file > Import > Existing Maven Project.
  4. Select the location of pom file of the project you downloaded and click on finish.
  5. Right Click on Project > Maven > Update Project. This will update the structure of project if needed.
  6. For development environment, you need to set up load time weaving of POJOs. For this you need to specify weaver jar using javaagent to your tomcat server. Here we are using  Spring Instrument for load time weaving. You can download latest jar from this link. Now open launch configuration of your tomcat server from eclipse (Double click on your tomcat in Servers tab & click on Open launch configuration). Now click on Arguments tab and append following line to VM arguments.

    -javaagent:<Path to Spring Instrument jar you downloaded>

    For e.g. I downloaded spring-instrument-4.2.3.RELEASE.jar and placed in D drive. Then javaagent argument will be as follow:

    -javaagent:D:\spring-instrument-4.2.3.RELEASE.jar

    In development environment you should use load time weaving. But when you are preparing war file you should use static weaving. So when creating war comment @EnableLoadTimeWeaving and make changes in entityManagerFactoryBean()  method of DBConfig.java as mentioned in comments of method.

  7. In application.properties, change jdbc.url, jdbc.username, jdbc.password & eclipselink.persistenceUnitName as per your database settings. Also make the same changes in persistence.xml
  8. Add project to tomcat and start the tomcat.
  9. The project has Person domain class, controller, service & repository. To access on browser, go to http://localhost:8085/yoursite/person?startIndex=0&limit=10. This will open list of person, which initially will be blank. Click on “Add” button to add a new person. Once added it will be listed there. You can edit it.landingaddperson
  10. You can access one sample REST endpoint at http://localhost:8080/yoursite/greeting/<personId>. Replace “personId” with the added person id.

If you want to develop a web application using this project and want to rename it, then change artifactId, groupId, fileName etc in pom.xml. Also if you want to upgrade spring and other dependencies version, then simply change the properties in pom.xml

If found any difficulty, please contact me on ghariaonline@gmail.com.  Share your feedabck. Happy Coding