Learn Spring with Shamik

Spring Tutorial


After getting so many requests from my viewers and Students I am planning to Write Tutorials on Spring only for you.



And the good new is that I have published my Spring Tutorials with A4Academis which is an Academic site published quality Tutorials on various topics like C, C++, Java, Angular JS.



To read my Spring Tutorials please click the link below



About the Tutorials:

There are many Spring tutorials you can find on the web,  why you should read this tutorial?

When I am planning to write a Tutorials for Spring, I researched and found that most of the tutorials just covered the topics with just a few lines with basic examples and provide important Spring classes names in Tabular format, With not much details. Examples are unrealistic which is not

So , I thought it would be great if we write tutorial which try to teach you the core Spring with proper justification and example not only that I also try to point out the concepts which you need to know in very details as those are frequently used in IT world, SO after reading this tutorial you have a fair bit of idea and start using Spring in your Project !!!!


In the case of any clarification/queries drop a note on A4Academics or my personal blog.



Still,  If you want to learn more about Spring, Advance Spring I offer Tuition please contact me on
Shamik Mitra
9830471739(M)
mitrashamik@gmail.com



Happy reading!!!!!












Spring: Be careful when using PropertyPlaceholderConfigurer

A word on PropertyPlaceholderConfigurer

A few days back one of my juniors came to me and said that when he test his modules separately in JUnit that worked perfectly but when the modules were deployed in Server as a unit, Server fails to start.


So I checked his code and fortunately identified the problem.
in this Article, I will discuss  that problem.

Let me describe the problem in detail.
Problem Statement:

The application he works on has three layers.

1.Dao layers
2.Service layers.
3.Middleware(Spring MVC).


Which is very standard architecture, and each layer built on top of spring so maintains separate Spring context files.

Each layer maintains its own property file.

Say for  Dao layers database connection related properties are maintained in  db.properties.
In Service layer, web service URL or other service parameters are maintained in service.properties file.

To load these properties files in application it uses PropertyPlaceholderConfigurer in each SpringContext file (Dao, Service, Middleware).




Sample example

db.properties
db.url=abc@localhost:1028/BillSchema
db.user=admin
db.password=tiger


and the entry for PropertyPlaceholderConfigurer in Spring_DB_Context.xml

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
               <value>classpath:db.properties</value>
             </list>
       </property>
      </bean>



Same for Services

Service.properties

bil.user=admin.
bill.passwd=abcd

and the entry for PropertyPlaceholderConfigurer in Spring_Service_Context.xml
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
               <value>classpath:service.properties</value>
             </list>
       </property>
 </bean>


In middleware, Spring context Spring_Middleware_Context.xml   imports  Spring_DB_Context.xml and Spring_Service_Context.xml


Now when he runs each modules Junit test it can resolve the properties files and works fine, but the problem kicks in when middleware application combine other two modules as jar and import context files into Spring_middleware  context and try to deploy in Server.

It Shows an error message {db.url} can’t resolve, and server fails to start.


So, His question is why it is happening?
In Junit, it runs but when we clubbed two modules as a jar and try to deploy it on server why such error message, as we have provided the PropertyPlaceholderConfigurer in each context and both properties files are present in classpath.


Actual Problem:

Upon viewing the error message one thing is clear that somehow those properties are not resolved by PropertyPlaceholderConfigurer.

Now deep dive to Spring context to understand why it is not resolved?

There are three separate Spring context files

Spring_DB_Context.xml
Spring_Service_Context.xml
Spring_Middleware_Context.xml


Spring_DB_Context.xml,Spring_Service_Context.xml joins the big context Spring_Middleware_Context.xml while deploying, via import statement in Spring_Middleware_Context.xml.

And each context has it’s own PropertyPlaceholderConfigurer and a property file. Now, if the Service context is loaded first by classloader then it’s PropertyPlaceholderConfigurer is loaded and it properties files so this PropertyPlaceholderConfigurer can resolve the beans under Service context but won’t able to resolve the properties of DB_Context as Service PropertyPlaceholderConfigurer does not knows about that db.properties  file. So server says {db.url } can’t resolved.

Same is true for service layer if classloader load Db Context first the {service.url} can’t be resolved.


Solution

The solution is just a tweak in PropertyPlaceholderConfigurer in each context. Just add the following line

<property name="ignoreUnresolvablePlaceholders" value="true"/>


So, Updated context files

Service context

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
               <value>classpath:service.properties</value>
             </list>
       </property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
 </bean>


DB context

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
               <value>classpath:dbproperties</value>
             </list>
       </property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
 </bean>


By doing this we tell Spring to ignore the unresolved properties or put it in another word
By default, Spring throws an exception if it can’t resolve a property that is fail-fast in nature.
But here we will explicitly say to Spring don’t throw the exception but go on with unresolved properties defer the action so when other PropertyPlaceholderConfigurer(Db Context)  will be loaded it will resolve the other part.

NB: Please note that for each context you have to mention
<property name="ignoreUnresolvablePlaceholders" value="true"/>, unless if one context does not provide aforesaid tag it will fails there immediately as by default Spring is fail-fast.

My juniors case  was very similar like this although he provides <property name="ignoreUnresolvablePlaceholders" value="true"/> in every modules still it fails.

Then I search for transitive dependencies on its module and found that one of the modules does not define <property name="ignoreUnresolvablePlaceholders" value=" true"/> tag in its context so it fails there, we update the same and recompile it then all problem just gone like magic.


TIP: Always use <property name="ignoreUnresolvablePlaceholders" value="true"/>, with PropertyPlaceholderConfigurer  as you never know when and how other modules use your modules and they may have their own  PropertyPlaceholderConfigurer as well, So you can break their code unknowingly  and give them an opportunity to scratch their head.

An Interview Question on Spring Singleton

Spring Singleton


While taking interview on Spring core, Often I ask a question

What do you mean by Spring Singleton scope?

Most of the time I got an answer like Spring singleton scope manages only one object in the container.

Then after getting this answer I will ask the next question,

Please tell me what will be the output of the following program



Spring.xml file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
   
    <bean id="scopeTest" class="com.example.scope.Scope" scope="singleton">
    <property name="name" value="Shamik Mitra"/>    
    </bean>    
    <bean id="scopeTestDuplicate" class="com.example.scope.Scope" scope="singleton">
          <property name="name" value="Samir Mitra"/>    
    </bean>
</beans>


Scope.java

package com.example.scope;
public class Scope {
   private String name;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   @Override
   public String toString() {
      return "Scope [name=" + name + "]";
   }

}

Main class

package com.example.scope;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {

   public static void main(String[] args) {
      ApplicationContext ctx = new ClassPathXmlApplicationContext(
              "configFiles/Scope.xml");

      Scope scope = (Scope) ctx.getBean("scopeTest");
      Scope scopeDuplicate = (Scope) ctx.getBean("scopeTestDuplicate");      
      System.out.println(scope==scopeDuplicate);
      System.out.println(scope  + "::"+ scopeDuplicate);
     

   }

}


Here I create two beans of Scope class and make spring scope as singleton now checking the references.


Now Interviewee got confused, and I will get three types of answer

This code will not compile throw error at runtime, as you can not define two spring beans of the same class with scope singleton in XML. (Very rare).
References check will return true, as container maintains one object so both bean definition will return the same object so memory location would be same.(Often)
They said References check will return false and Spring singleton is not worked as they have told earlier.(few)



The third answer is the correct answer, Spring singleton is not worked as Java Singleton.

If we see the output of the program we will understand that it will return two different instances, So in a  container, there may be more than one object in spite of the scope is the singleton.




Output:

Reference Check ::false
Scope [name=Shamik Mitra]::Scope [name=Samir Mitra]


So again Question is What do you mean by Spring Singleton Scope?

According to Spring documentation

When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.
To put it another way, when you define a bean definition and it is scoped as a singleton, then the Spring IoC container will create exactly one instance of the object defined by that bean definition. This single instance will be stored in a cache of such singleton beans, and all subsequent requests and references for that named bean will result in the cached object being returned.


So it is clear that for a given id Spring container maintains only one shared instance in singleton cache.

In my example, I use two different ids (scopeTest, ScopeTestDuplicate) so Spring container creates two instances of the same class and bound it with respective ids and stores it in singleton cache.

You can think Spring Container manage Key-value pair where Key is the id or name of the bean and value is bean itself , so for a given key, it maintains singleton. So if we use that key as a reference of other beans the same bean will be injected to other beans.





In a one words , Spring guarantees exactly one shared bean instance for the given Id per IoC container unlike Java Singleton where Singleton hard codes the scope of an object such that one and only one instance of a particular class will ever be created per ClassLoader.

Picture taken from Spring docs

Spring @Transactional & Exception

Spring Transactional Annotation & Exception


What is Transaction?

The transaction is unit work which will success or fails as the unit. So suppose we are dealing with two accounts for transfer money from one to another.  Now if Money from one account is already debited but while it is credited to an another account there was Exception so the ideal scenario would be debited action should rollback. Otherwise, it would be an Inconsistent state.

So if we use Transaction in our business logic we can ensure, logic under the Transaction work as a unit it will be rollback if anything found wrong.

In one word.

Either Unit of work Succeeds completely or failure completely no intermediate state.


Now the question comes How we can handle Transaction.

There are two ways to Handle it

BMT: Bean managed Transaction.
CMT: Container Managed Transaction.



BMT: If we need a finer control over business logic or want to introduce savepoints this type of technique should be adopted where bean provider has a responsibility to start, commit, rollback the transaction.

CMT: If we want to delegate the responsibility to container we use it. Sometimes we called it Declarative Transaction.


We all know in Spring using @Transactional annotation we can adopt Declarative transaction technique.

In this article, I will not show how to configure it but tell about the precaution you want to take while using @Transactional annotation.

Study the pseudo code.
@Transactional
pbublic void transferMoney(Account to,Account from,int amount) throws Exception{
        debiFromAccount(to,amount)
        creditFromAccount(from,amount);
       
    }
   
    public debiFromAccount(Account to,int amount){
        //do staff and debited money from data base
    }
   
    public creditFromAccount(Account from,int amount)throws Exception{
        //do straff
        throw new EXception("Error during credit");
    }



Now do a dry run
If Account to initial balance is 1000
Account from is 500
Transfer amount : 100


After error occurred in creditFromAccount(Account from,int amount) what will be the output you expected?

To : 1000
From : 500

Afterall I use @Transactional so in case of Exception it should be rolled back automatically right.

But unfortunately it left a inconsistent state

Output is like

To : 900
From : 500


So obviously you will ask me Why, what is going on here?

Let me clear you, @Transactional only rollback transaction only for the unchecked exception but for checked Exception and it’s subclass it commits data. So although an Exception raised here but as it is a Checked Exception, Spring simply ignores it and commit the data to the database so the system goes inconsistent.

Spring documentation says that,



While the EJB default behavior is for the EJB container to automatically roll back the transaction on a system exception (usually a runtime exception), EJB CMT does not roll back the transaction automatically on an application exception (that is, a checked exception other than java.rmi.RemoteException). While the Spring default behavior for declarative transaction management follows EJB convention (roll back is automatic only on unchecked exceptions), it is often useful to customize this.

So pay attention to the last line “it is often useful to customize this”

So how can we customize it?

It is very simple just use following with @Transactional

@Transactional(rollbackFor = Exception.class)
So if you throw an Exception or Subclass of Exception always use the above with @Transactional annotation to tell Spring to rollback transaction in case for Checked Exception occur.