My Review of Sanjay Patel’s Spring Course

Spring is the most popular Java framework for building web and enterprise applications. There are plenty of official documentation, books, and Training Courses available for Spring framework on web.

I got an opportunity to review Sanjay Patel‘s Spring Course Material which is divided into 3 modules.

The total course is divided into 3 modules covering various aspects of web application development using Spring/SpringBoot framework.

  1. Module I : Spring Framework 4 And Dependency Injection For Beginners
  2. Module II : Spring Framework for the Real World
  3. Module III : Spring Framework REST API Development

Module I: Spring Framework 4 and Dependency Injection For Beginners

This module covers the basics of Spring Dependency Injection mechanism using Annotations and JavaConfig based approach using SpringBoot.

The material is structured in such a way that the readers can follow the course and practice in a step by step manner.

The following topics are covered in this Module:

  • Quick and brief introduction to Dependency Injection using Spring
  • Loading and binding properties from properties files
  • Using environment profiles
  • Brief introduction about using @Conditional
  • Sending Email

There are plenty of Spring core feature are there which can’t be covered in a single book or video.But I think it would be great to cover the most commonly used features Scopes, like LifeCycle methods @PostConstruct and @PreDestroy etc.

Overall, this module will be good for people who already have some basic knowledge on Spring. But for complete beginners it may be overwhelming to understand all these Spring concepts along with SpringBoot.

Module II: Spring Framework for the Real World

This module covers the most of the aspects of web application development. The explanation is straight forward and to the point.

This module explains the concepts by implementing various use-cases of typical User Management such as SignIn, SignUp, Forgot Password, Reset Password etc.

This module covers:

  • Implementing Controllers, Request Parameters binding
  • Performing Validations, Customizing Error Messages
  • Creating custom validation constraints
  • Exception Handling
  • Brief introduction to Spring Data JPA and Transaction Handling
  • Implementing Security using Spring Security
    • Configuring Spring Security
    • Form based Login, Remember Me, Password Encryption
    • Spring Security JSP Tag libraries
  • A quick introduction to Asynchronous processing using @Async
  • Scheduling tasks using @Scheduled

This module gives hands-on experience on using many of the Spring web application development tasks. This module also contains creating many commonly used utilities such as getting I18N messages, getting login user details etc which comes very handy.

We can also use JSP with SpringBoot jar type packaging as described in Spring Boot With JSPs in Executable Jars(

Module III: Spring Framework REST API Development

This module covers building REST API using SpringBoot. This module contains excellent material covering most of the aspects required for building a good REST API.

This module covers:

  • Creating REST Endpoints using @RestController
  • Exception handling via @ControllerAdvice
  • Environment specific properties using Profiles
  • Using @ConfigurationProperties to bind properties
  • How to catch constraint violation exceptions
  • How to use reCAPTCHA
  • Securing REST API
    • Customizing Spring Security to support REST API
    • Switching User
    • Handling CSRF and CORS

This module filled with lot of interesting material required to build a Secured REST API.

However, I feel like there are few important things which are not covered:                        

  • No mention of Serializing JPA entities
  • Dealing with bi-directional JPA Entity relation serialization issues
  • Token based Security

Throughout the course author explain the concepts in clear and to the point manner. Also, the course is backed by an application SpringLemon which contains all the code used in this course.

Overall this course looks very to me and I strongly recommend this course if you are looking for a fast paced Spring course.

Retrying Method Execution using Spring AOP

One of my blog follower sends an email asking me to show an example of “RealWorld Usage of Spring AOP”. He mentioned that in most of the examples the usage of Spring AOP is demonstrated for logging method entry/exit or Transaction management or Security checks. He wanted to know how Spring AOP is being used in “Real Project for Real Problems”.

So I would like to show how I have used Spring AOP for one of my project to handle a real problem.

We won’t face some kind of problems in development phases and only come to know during Load Testing or in production environments only.
For example:

  • Remote WebService invocation failures due to network latency issues
  • Database query failures because of Lock exceptions

In most of the cases just retrying the same operation is sufficient to solve these kind of failures.
Let us see how we can use Spring AOP to automatically retry the method execution if any exception occurs.

We can use Spring AOP @Around advice to create a proxy for those objects whose methods needs to be retried and implement the retry logic in Aspect.

Before jumping on to implementing these Spring Advice and Aspect, first let us write a simple utility to execute a “Task” which automatically retry for N times ignoring the given set of Exceptions.

public interface Task<T> {
	T execute();
import java.util.HashSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TaskExecutionUtil 
	private static Logger logger = LoggerFactory.getLogger(TaskExecutionUtil.class);

	public static <T> T execute(Task<T> task, 
								int noOfRetryAttempts, 
								long sleepInterval, 
								Class<? extends Throwable>... ignoreExceptions) 
		if (noOfRetryAttempts < 1) {
			noOfRetryAttempts = 1;
		Set<Class<? extends Throwable>> ignoreExceptionsSet = new HashSet<Class<? extends Throwable>>();
		if (ignoreExceptions != null && ignoreExceptions.length > 0) {
			for (Class<? extends Throwable> ignoreException : ignoreExceptions) {
		logger.debug("noOfRetryAttempts = "+noOfRetryAttempts);
		logger.debug("ignoreExceptionsSet = "+ignoreExceptionsSet);
		T result = null;
		for (int retryCount = 1; retryCount <= noOfRetryAttempts; retryCount++) {
			logger.debug("Executing the task. Attemp#"+retryCount);
			try {
				result = task.execute();
			} catch (RuntimeException t) {
				Throwable e = t.getCause();
				logger.error(" Caught Exception class"+e.getClass());
				for (Class<? extends Throwable> ignoreExceptionClazz : ignoreExceptionsSet) {
					logger.error(" Comparing with Ignorable Exception : "+ignoreExceptionClazz.getName());
					if (!ignoreExceptionClazz.isAssignableFrom(e.getClass())) {
						logger.error("Encountered exception which is not ignorable: "+e.getClass());
						logger.error("Throwing exception to the caller");
						throw t;
				logger.error("Failed at Retry attempt :" + retryCount + " of : " + noOfRetryAttempts);
				if (retryCount >= noOfRetryAttempts) {
					logger.error("Maximum retrial attempts exceeded.");
					logger.error("Throwing exception to the caller");
					throw t;
				try {
				} catch (InterruptedException e1) {
					//Intentionally left blank
		return result;


I hope this method is self explanatory. It is taking a Task and retries noOfRetryAttempts times in case method task.execute() throws any Exception and ignoreExceptions indicates what type of exceptions to be ignored while retrying.

Now let us create a Retry annotation as follows:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public  @interface Retry {
	public int retryAttempts() default 3;
	public long sleepInterval() default 1000L; //milliseconds
	Class<? extends Throwable>[] ignoreExceptions() default { RuntimeException.class };

We will use this @Retry annotation to demarcate which methods needs to be retried.

Now let us implement the Aspect which applies to the method with @Retry annotation.

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

public class MethodRetryHandlerAspect {
	private static Logger logger = LoggerFactory.getLogger(MethodRetryHandlerAspect.class);
	public Object audit(ProceedingJoinPoint pjp) 
		Object result = null;
		result = retryableExecute(pjp);
	    return result;
	protected Object retryableExecute(final ProceedingJoinPoint pjp)
		MethodSignature signature = (MethodSignature) pjp.getSignature();
		Method method = signature.getMethod();
		logger.debug("-----Retry Aspect---------");
		logger.debug("Method: "+signature.toString());

		Retry retry = method.getDeclaredAnnotation(Retry.class);
		int retryAttempts = retry.retryAttempts();
		long sleepInterval = retry.sleepInterval();
		Class<? extends Throwable>[] ignoreExceptions = retry.ignoreExceptions();
		Task<Object> task = new Task<Object>() {
			public Object execute() {
				try {
					return pjp.proceed();
				} catch (Throwable e) {
					throw new RuntimeException(e);
		return TaskExecutionUtil.execute(task, retryAttempts, sleepInterval, ignoreExceptions);

That’s it. We just need some test cases to actually test it.

First create configuration class as follows:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

public class AppConfig {


And couple of dummy Service beans.

import org.springframework.stereotype.Service;

public class ServiceA {
	private int counter = 1;
	public void method1() {
	@Retry(retryAttempts=5, ignoreExceptions={NullPointerException.class})
	public void method2() {
		System.err.println("----method2 begin----");
		if(counter != 3){
			throw new NullPointerException();
		System.err.println("----method2 end----");		
import org.springframework.stereotype.Service;

public class ServiceB {
	@Retry(retryAttempts = 2, ignoreExceptions={IOException.class})
	public void method3() {
		if(1 == 1){
			throw new ArrayIndexOutOfBoundsException();
	public void method4() {

Finally write a simple Junit test to invoke these methods.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

public class RetryTest 
	@Autowired ServiceA svcA;
	@Autowired ServiceB svcB;
	public void testA()
	public void testB()
	public void testC()
	public void testD()

Yeah, I know I could have written these test methods a bit better, but I hope you got the idea.

Run the JUnit tests and observe the log statement to verify whether the method retry is happening in case of Exception or not.

Case#1: When invoking ServiceA.method1() is invoked MethodRetryHandlerAspect won’t be applied at all.

Case#2: When invoking ServiceA.method2() is invoked, we are maintaining a counter and throwing NullPointerException for 2 times. But we have marked that method to ignore NullPointerExceptions. So it will continue to retry for 5 times. But 3rd time method will be executed normally and exits the method normally.

Case#3: When invoking ServiceB.method3() is invoked, we are throwing ArrayIndexOutOfBoundsException but that method is marked to ignore only IOException only.
So this method execution won’t be retried and throws the Exception immediately.

Case#4: When invoking ServiceB.method4() is invoked, everything is fine so it should exit in the first attempt itself normally.

I hope this example demonstrate a good enough real world usage of Spring AOP 🙂

Selecting The Technology Stack for JCart

Selecting the right technology stack is very crucial and plays an important role in project success. Many of the architects (unknowingly??!!) try to make complex designs by trying to use all kinds of latest and greatest stuff. On the other hand some architects try to be in their comfort zone by limiting their technology stack to the technologies with which they are comfortable. Both approaches are dangerous. One should understand the business needs and pick the technologies that are necessary for project.

Java Platform: We will be using Java 8 for JCart so that we can leverage the good features introduced in Java8 like Streams, DateTime API etc.

Frameworks: This is where people go religious about their favourite frameworks. We should consider various factors while choosing the tech stack for any project.

  • Needs of the project requirements
  • Maturity and stability of the technologies
  • Team skills
  • Community/Commercial support

For JCart project we need:

  • Request-Response oriented MVC web framework for ShoppingCart site. I prefer stateless architecture for public facing web apps.
  • Component oriented MVC web framework for Administration site. I prefer UI Component Oriented framework for internal applications like Administration web apps.
  • Security framework supporting Role Based Access Control (RBAC)
  • A high-level Data Persistence framework
  • Other miscellaneous features like Emailing, Scheduling etc

In Java land, JavaEE and Spring are the most popular tech stacks for building applications. Both are very mature and have wonderful community support.

Spring provides:

  • Request-Response oriented SpringMVC web framework
  • Spring doesn’t provide any Component Oriented MVC framework. But we can integrate Spring with JSF or Vaadin which are Component Oriented Web MVC Frameworks
  • SpringSecurity provides RBAC security
  • Spring Data projects provides a very nice abstraction over various Data Access Technologies
  • Spring provides support for Emailing and Quartz Scheduler integrations as well.

JavaEE provides:

  • As of JavaEE7 there is no Request-Response Oriented framework provided by JavaEE. But in upcoming JavaEE8 version a new MVC framework will be released as JSR 371 . The reference implementation for MVC 1.0 is Ozark. You can find more details on it at
  • Component Oriented Web MVC framework JSF
  • IMHO, Security features provided by JavaEE 7 are not sufficient for many of the applications. But the good news is in the upcoming JavaEE8, JSR 375: Java EE Security API will be released.
  • JPA ORM framework which you can use with any of the popular implementations like Hibernate, EclipseLink etc. In addition to that you can use Apache DeltaSpike  modules to make things more easier.
  • JavaEE also provides support for Emailing and Scheduling features.

Coming to the Team skills, we are more hands-on with Spring technologies than pure JavaEE stack. We can work with both JavaEE and Spring, but we are more productive with Spring. If our team members are more hands-on with JavaEE we would have chosen JavaEE.

So, we are going to use Spring and some of its portfolio projects like Spring Security, Spring Data, Spring Boot etc.

Note: As I mentioned, a Component Oriented framework would be more suitable for JCart Administration web app, we will be using SpringMVC with Thymeleaf only. This is a compromise we are making considering the team skills and scope of the project.

Secret: Let me tell you a little secret. Come close. The reason I mentioned above for not using any Component Oriented Frameworks is not true. The actual reason is, after completing this application using Spring stack, I am planning to build the same app using pure JavaEE stack (CDI, EJB, JPA, JSF etc). There I am planning to use JSF/PrimeFaces for Administration web app. So we will be hands-on with both Thymeleaf and JSF/PrimeFaces 🙂

What are the tools we will be using?

  • Version Control System: We will be using Git VCS and host our code on Github.
  • Build Tool: I know Gradle is so hot these days but I am happy with Maven. We will be using Maven for our application.
  • IDE: As we are using Maven which is IDE agnostic we can use any of our favourite IDE. But our application is heavily depends on Spring technologies we will be using STS. Those of you Intellij IDEA fan boys can happily use Intellij IDEA 🙂
  • Server: Tomcat as embedded server.
  • Database: MySQL. But ideally we should be able to use our application with other databases like Postgres.
  • Tools: Jenkins for CI, SonarQube for code quality checking.
  • Production: While deploying our application in production we may want to use Apache or Ngnix as our load balancer and use monitoring tools like Zabbix. As I am not an expert in this area we will come back and spend some time to take a deep look at the options and pick the tools.

What about MicroServices, Docker and Cloud stuff?

As I said earlier, we are choosing the technologies based on our project needs. We are not Netflix, we are not LinkedIn and we are not building the NextAwesomeTechProductOnEarch. Our project needs are simple, our team size is small and we are not going to deploy our application on 128 containers on Cloud, so we are not going to use any fancy container technologies like Docker/Kubertness. If at all we got scalability problems where we may need to deploy our application on hundreds of servers, that’s a good to have problem.

Remember: Adding new software/framework/library to a project is easy..Removing is lot harder than you thing. So be careful while adding another software/framework/library.

Developing a simple e-commerce application from scratch to production using SpringBoot

We can find plenty of information on any technical topic, be it Java, .NET, Python or any frameworks like Spring, Hibernate, CDI, JSF etc. You can find hundreds of well written blogs on many of these topics. For example, you can find lot of tutorials on how to use SpringBoot or how to use various mappings in JPA/Hibernate or how to do form validations in JSF etc. Also, there are plenty of books published by well established publishers on most of the technologies.

But once the “Junior Developer” stage is crossed, many developers would like to learn more about how to design an application, how to modularize the code, what security aspects should be considered, what measures we should take while deploying into production and how to handle the production issues etc.

We can find articles on these topics in bits and pieces but not in an organized manner. So, I thought of starting a series of articles covering “How to develop an application from scratch to production?“. What I am going to do is I will start developing an application (neither a simple HelloWorld app nor a NextGenerationAwesome product, but a decent size application) and write a series of articles explaining how we can develop the application in a step by step manner.

Why I am writing these article series?

To help junior developers:
Every week I receive at least couple of emails from software developers with 1 to 3 years of experiencing for a suggestion.

Those emails goes like this:

I joined in XYZ company as a fresher and I have been there for the last 2+ years. They put me in a maintenance project where I mostly work on defect fixes and I never really worked on anything from scratch. Now I am not at all confident about my technical skills as I have not implemented anything on my own apart from fixing defects here and there. Here we don’t see any new projects in near future. So I want to move to a different company, but I am having a very hard time in clearing the interviews.

So, could you please advise me how to learn Java the way people use it in real projects, not basic HelloWorld kind of samples? Could you suggest any books, blogs? Should I learn Spring, Hibernate to get a Job?

I feel very sad to see the people in this kind of situation because I know how painful it is. But also simply blaming the company for not giving an opportunity to build something from scratch won’t help. Teaching you latest and greatest technologies may not be your organizations top priority.

Some people told they even joined some training institutes to learn Java while working as Java developers!!. But again they are disappointed because they got basic HelloWorld kind of training only, not the way projects are developed in organizations.

So, I thought of helping them by writing a series of articles explaining how the project development from scratch looks like.

Material for my trainings
I do give trainings on Core Java, Spring and JavaEE. I hope the projects that will be developed for this series may also be helpful for my Java trainings as well.

I want to learn more
Teaching is the best way to learn.

What we are going to do?

We will develop an e-commerce application using Java technologies. We will start from the very beginning of Requirements Gathering and go through all the phases of Analysis, Design, Implementation and Deployment in a step by step manner.


Table of contents:

  1. Introducing the application JCart
    • High Level Requirements
    • Overview of System Architecture
  2. Requirements Analysis
  3. Selecting The Technology Stack
    • Platform, Frameworks
    • Application Server, Database
    • IDE, Build Tool, Version Control System (VCS)
    • Continuous Integration, Code Quality Checking
  4. Release Planning
    • Plan Iterations & UseCases
    • Estimations & Release Schedules
  5. Setting up the Development Environment
  6. Building Administration/ShoppingCart WebApps
    • Iteration – 1
    • Iteration – 2
    • Iteration – 3
    • Iteration – 4
    • Iteration – 5
    • Iteration – 6
    • Iteration – 7
    • Iteration – 8
  7. Deploying to Production
    • Clustering and Load balancing
    • Setting up Monitoring Tools


For this whole exercise we will build a ShoppingCart application “JCart” using SpringBoot, SpringMVC, Thymeleaf, JPA(Hibernate). I too have this habit of prefixing with J for everything I built with Java :-).

If everything goes as planned and once we finish this application, then probably I will try to implement the same application using JavaEE stack (CDI, EJB, JPA, JSF etc).

Stay tuned 🙂

A Developers Perspective on Spring vs JavaEE

In Java community Spring vs JavaEE is a never ending debate. In such debates people form two groups consisting of evangelists, architects and hard core fans of one platform and debate endlessly. Those who participate in the debates may be architects who are responsible for platform selection. But what would developers think about this Spring vs JavaEE debate?

I am a Java developer who uses both Spring and JavaEE and I am not part of Spring or JavaEE fan club. Here I would like to share my own thoughts on this epic Spring vs JavaEE debate.

1. Business(sometimes political) Aspects
In many organizations technology selection may not completely depends on developers choice. More specifically if you are working in so called giant enterprise organizations there are high chances that there is an Architecture Team who will decide what platform/language/framework/libraries to use in the projects.

In addition to that, large enterprises also considers the following aspects while choosing the technology platform:

  • Maturity of the platform/language/framework/libraries
  • Commercial support
  • Licensing cost etc etc

As a developer I can hardly influence the decision making process for any of the above aspects, especially when I am a developer in offshore development center. So I don’t worry too much about these things.

2. If you are really good at Spring/JavaEE then learning the other one shouldn’t be difficult
I am always surprised when someone says I am JavaEE expert but I can’t understand Spring or vice-versa. Both JavaEE and Spring work on the same core APIs (Servlet, JPA, JMS, BeanValidation etc), the difference is who is gluing the things together, Spring or AppServer.

Even though there are some different APIs for things like dependency injection (Spring DI, CDI), REST (JAX-RS, SpringMVC) etc they look and behave pretty similar to each other.

May be someone can say CDI is more typesafe than Spring DI. Doesn’t Spring and CDI behaves similarly when:

  • Injection using @Autowired or @Inject works fine if there is only one Spring/CDI Bean
  • Injection fails when there are more than one Spring or CDI bean implementations by throwing errors saying “Found more than one eligible beans that can be inject”
  • Use @Produces or @Bean annotated method to provide custom made objects as bean providers

As long as they are behaving similarly I don’t care whether they are implemented in more typesafe manner or used String based mappings in their internal implementations.

How can one be expert in Spring and can’t understand JavaEE and vice-versa?? How much time it can take for a Spring expert to learn JavaEE??!!

3. Which is more “Average Joe developer” friendly
I think by now many people should have realized that success of a technology may not be completely depends on its merits, but also based on developers adoption. The most important thing to realize is “Not every software developer is a rock star developer. There are more average joe developers than passionate, tech ninjas”. So in order to people adapt any framework it should be “Average Joe Developer” friendly.

I think Spring is doing pretty good job at it by providing more tools like SpringBoot, User Guides etc. Spring Security, Spring Integration, Spring XD, Spring Social addresses the modern business needs very well. Also think about various templates provided by Spring which makes easy to do things without worrying about boilerplate coding.

JavaEE is also doing very well by introducing JBossForge, Wildfly Swarm etc to quickly get started. I came across few JavaEE based frameworks like Picketlink which addresses Security requirements, but I felt it is much more complex than it should be.

The point I am trying to convey is “You can do pretty much everything in JavaEE that you can do with Spring”. The difference is which is giving more out-of-the-box to average joe developer.

4. Lame arguments without context
Whenever Spring vs JavaEE debate arises people form two groups and debate endlessly.  Unfortunately the debates focus on some useless or outdated points.

XML heavy: 
JavaEE fans first start saying Spring is XML heavy and I hate XML blah blah blah. If you are still using Spring older than version 2.5 and assuming it is still same XML based then my friend you should wake up and head to

EJBs are bad (or) JSF is bad
Spring fans jump on to bashing EJB and JSF as if they are same as EJB 2.x or JSF 1.x. If they really look at EJB 3.x and JSF 2.x then they wouldn’t argue on this at all. Don’t judge EJB 3.x with your 6 years back EJB2.x experience.

Heavy weight or light weight
My interpretation of this ‘weight’ thing is based on runtime foot print. To my knowledge, when you deploy your managed beans into JavaEE container then container will proxy it and inject all enterprise services (Transactions, Security etc) and in case of Spring it will be done by Spring AOP.
I don’t have any metrics to say which is more heavy weight Container Proxy or SpringAOP Proxy, but I guess there may not be significant difference.

Some people consider the size of war file as its ‘weight’. In that case compare (JavaEE AppServer + war) size with (SpringApp with 126 jars) and see which is light weight 🙂

JavaEE is standards based
Come on guys!!!!

Vendor lock-in
I think choosing a platform which doesn’t make you stick with one particular vendor is good. But going with an option purely based on the ability to move to a different implementation is not correct. How many times in an year you switch from one server to another? Choosing a platform which doesn’t lock you with a vendor is a ‘nice to have’ but it should not be major factor to choose your platform.

We don’t need external libraries
This is called “Arguing for the sake of arguing”. Show me any real application without having any dependencies. If you say I will develop my own logging library, I will write my own HTTP client, I will develop my own common-utilities then you need to look for a little bit more lazy architect/developers who doesn’t have “Re-invent all the wheels” sickness.

5. Don’t look at the crowd and say “You are all idiots because you are using X, you should migrate to Y”.
This is a common pattern that I observe on many community sites, especially on Reddit. Just post anything related to JavaEE vs Spring thing and there will be two groups who bash the other group like anything because other group are not using their favorite platform.

Think for a minute. If Spring is not any good why so many people use it and love it. If JavaEE is not good why so many people switch from Spring to JavaEE. There is so many good things in each platform. Respect others for choosing whatever option they choose. If possible ask them the reasons why they went with one over the other and learn if you miss anything.

Just saying “You all are idiots for not using my favorite option” doesn’t make them use your favorite technology. In fact it triggers the thought to come up with list of points why your favorite platform sucks.

If you really want them to switch to your favorite platform then show the reasons with code examples. Show them how easy it is to develop applications using your favorite platform with sample applications. Write more articles on commonly facing issues and how to resolve them. Get the “Average Joe Developer” on-board onto your favorite platform.

As an enthusiastic Java developer I read the Spring vs JavaEE discussions hoping there might be few things which I don’t know such as “in which areas one is better than the other”. But I find 70% of discussions goes on lame arguments which is not very interesting to me.

I wish Spring and JavaEE camps to fight more and more and made their platform superior than the other. End of the day, no matter who win the debate ultimately developers will have more powerful platforms.