Monday, November 4, 2013

Spring JMX - Expose POJOs as MBeans

Spring JMX allows you to easily expose POJOs as JMX MBeans. Even it allows the MBeans to deploy on application server which has MBean server running or can be run standalone. We can use jconsole to run the services provided by the MBean.
The configuration required to expose the POJO as Mbean is as follows. Here, MyBean is a POJO with at-least one public method.
<bean id="myMBean" class="com.test.MyBean"  />

<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
   <property name="beans">
       <map>
          <entry key="bean:name=MyMBeanName" value-ref="myMBean" />
       </map>
   </property>
</bean>
MBeanExporter exposes the map of "beans" as MBeans. Here we exposed myMBean as "MyMMBeanName". This name will be shown in the jconsole. By default, all the public methods inside the POJO will be exposed as operations.
If the Spring JMX is not running under an application server, then we need a starter. Definition is as follows:
<!-- If not running on a server which has MBean server running, you must start here -->
<bean id="factory" class="org.springframework.jmx.support.MBeanServerFactoryBean" />
With the above configuration, The MBean can be accessed locally. The MBean can be exposed either using JMXJMP or RMI.
To expose using JMXJMP as follows. The default service URL to access is : service:jmx:jmxmp://localhost:9875
<bean class="org.springframework.jmx.support.ConnectorServerFactoryBean" />
To expose using RMI as follows.
<bean class="org.springframework.jmx.support.ConnectorServerFactoryBean"
    depends-on="rmiRegistry">
    <property name="objectName" value="connector:name=rmi" />
    <property name="serviceUrl"
        value="service:jmx:rmi://localhost/jndi/rmi://localhost:10099/myconnector" />
</bean>

<bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
    <property name="port" value="10099" />
</bean>
The complete configuration of exposing POJO using Spring JMX (With Remote access with RMI) without running an application server is as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util-3.0.xsd">

    <bean id="myMBean" class="com.test.MyBean"  />

    <bean class="org.springframework.jmx.export.MBeanExporter"
       lazy-init="false">
       <property name="beans">
           <map>
           <entry key="bean:name=MyMBeanName" value-ref="myMBean" />
           </map>
        </property>
    </bean>

    <!-- If not running on a server which has MBean server running, you must start here -->
    <bean id="factory" class="org.springframework.jmx.support.MBeanServerFactoryBean" />

    <bean class="org.springframework.jmx.support.ConnectorServerFactoryBean"
        depends-on="rmiRegistry">
        <property name="objectName" value="connector:name=rmi" />
            <property name="serviceUrl"
               value="service:jmx:rmi://localhost/jndi/rmi://localhost:10099/myconnector" />
    </bean>

    <bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
        <property name="port" value="10099" />
    </bean>

</beans>
The POJO MyBean.java is :
package com.test;

public class MyBean {
    public void start()
    {
        System.out.println("Started");
    }
 
    public void stop()
    {
        System.out.println("Stopped");
    }
}
The Application program to start is :
package com.test.application;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Application {
   public static void main(String...args)
   {
       ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
       context.getBean("factory");
   }
}
When we run this program, it start the MBean. Connect to this using jconsole. The MBean with name "MyMBeanName" visible under MBeans Tab.

Happy Learning!!!!

Saturday, October 26, 2013

Getting started with Spring Batch 2.0

Spring batch 2.0 simpilified and improvised the batching framework. We have so many frameworks for MVC, Web, JDBC etc but batching frameworks are very rare. Spring batch is a lightweight and robust batch framework to process these big data sets. Spring offer Tasklet oriented and Chunk Oriented processing. In this post, we will see Simple Tasklet oriented processing.

Key Concepts:
  • Job - Job is a sequence of steps, each has an exit status. Execution of the next step depends on the exit status of previous step.
  • JobRepository - An interface which contains the meta data and corresponding entities of the Job. 
  • JobLauncer - Which launches a job by exposing the method to run.
  • Tasklet - An interface, can be instance of job which exposes a method called execute and returns the execution status. A tasklet will execute repeatedly until it returns FINSIHED.
Step to define (A simple job):
  • Define one job repository
  • Define one job launcher using the job repository.
  • Define Job(s) under the job launcher. Multiple jobs can be defined under one job launcher.
  • Create steps under the job. We can add multiple steps under the job with relations. By default, job launcher executes the job based on the steps defined. We can create dependency between each step. Literally, each step is a java class (Either Tasklet - a simple task or a combination of reader, writer and executiors for chunk oriented processing).
The below example shows how to define a job with single task (or step) using Tasklet.
spring-job.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans="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 http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd">

  <beans:bean id="transactionManager"
    class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
  
  <beans:bean id="jobRepository"
    class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
    <beans:property name="transactionManager" ref="transactionManager" />
  </beans:bean>

  <beans:bean id="jobLauncher"
    class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
      <beans:property name="jobRepository" ref="jobRepository" />
  </beans:bean>

  <job id="sampleJob" job-repository="jobRepository">
    <step id="step1">
       <tasklet ref="sampleTasklet" />
    </step>
  </job>

  <beans:bean name="sampleTasklet" class="com.test.springbatch.SampleTasklet" />
</beans:beans>
The SampleTasklet class should be a type of Tasklet, which provides one execute. The execute method returns RepeatStatus to know the status of the task. The tasks executes multiple times if it returns CONTINUABLE otherwise stops after execution.
package com.test.springbatch;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

public class SampleTasklet implements Tasklet
{
    public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception
    {
        System.out.println("Do Something; ");
        // Return RepeatStatus.CONTINUABLE if something goes wrong so that it
        // repeats; Otherwise Return FINISHED to complete
        return RepeatStatus.FINISHED;
    }
}

How to run the job:
Spring provides you with CommandLineJobRunner which runs the job using the two parameters. One the spring context file and the other is the batch name.
CommandLineJobRunner.main(new String[] { "spring-batch.xml", "sampleJob" });
In the next post, we will see "Chunk Oriented processing with Spring Batch"
Happy Learning !!!!

Saturday, September 7, 2013

Spring Data - JPA

A lot of effort is required for configuration and using JPA. Spring Data JPA has reduced that to a major extent. Takes little effort to configure and easy to use. Let's look at this with an example.
The spring data dependency and hibernate dependencies using maven are as follows. (Note: All other spring core, bean, context dependencies are required along with the below dependencies)
        <!-- Spring Data JPA -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.0.2.RELEASE</version>
        </dependency>
        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
Create a persistence xml file in META-INF file.
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <!--Persistence Unit for Mysql database-->
    <persistence-unit name="testMysql" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>com.test.entity.Employee</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
            <property name="hibernate.show_sql" value="true"/>
        </properties>
    </persistence-unit>
</persistence>
Now, need to configure Spring Data - JPA using the persistent unit "testMysql"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--Following data source for Mysql-->
    <bean id="mysqltestDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.testurl}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--Following entity manager for Mysql database-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="mysqltestDataSource"/>
        <property name="persistenceUnitName" value="testMysql"/>
    </bean>

    <!--Transaction manager for both H2 and Mysql-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    
    <jpa:repositories transaction-manager-ref="transactionManager" 
        entity-manager-factory-ref="entityManagerFactory" base-package="com.test.dao">
    </jpa:repositories>
    
</beans>
Explanation of above spring configuration Create one datasource.

  • Create one driver manager datasource named "mysqltestDataSource", by loading jdbc.properties file from the classpath using line <context:property-placeholder location="classpath:jdbc.properties"/>
  • Create entity manager factory using the datasource created and persistent unit created in persistent.xml
  • Inject entity manager factory into transaction manager. 
  • Finally configure both transaction manager and entity manager factory to set of repositories in a package (defined using base-package)
Now, create repository, an interface which extends JpaRepository inside package (defined in base-package). The typed arguments required are one entity and other is Id. In this case, entity is Employee and Id of the Employee is Long.
package com.test.dao;

import org.springframework.data.jpa.repository.JpaRepository;

import com.test.entity.Employee;

public interface EmployeeDAO extends JpaRepository<Employee, Long>
{
}
The entity is as follows
package com.test.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "EMP")
@Entity
public class Employee
{
    private int id;
    private String name;
    private int age;
    @Id
    @Column(name = "id", unique = true, nullable = false)
    public int getId()
    {
        return id;
    }
    public void setId(int id)
    {
        this.id = id;
    }
    @Column(name = "name")
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    @Column(name = "age")
    public int getAge()
    {
        return age;
    }
    public void setAge(int age)
    {
        this.age = age;
    }
}
That's it on the configuration part. By using the repository, we can do all types of database operations for that entity. There are numberous in-built methods are provided by JpaRepository interface. Sample code for that will be
        EmployeeDAO dao = (EmployeeDAO)context.getBean("employeeDAO");
        List list = dao.findAll();
        for(Employee e : list)
        {
            //Do Something
        }

Sunday, August 18, 2013

Java New IO 2.0

The New IO is one of the features introduced in Java7. A new package java.nio has been added as part of this feature. Even though the usage wise it's same as java.io, most of the issues in java.io has been addressed. We will see the features introduced in New IO (NIO)
Path
The package java.nio.file consists of classes and interfaces Path, Paths, FileSystem, FileSystems and others. Each of represent's the file path or file system as is.
java.nio.file.Path works exactly same as java.io.File with additional features.
Path path = Paths.get("C:\\temp\\sample.txt");
System.out.println("Name Count : "+path.getNameCount());
System.out.println("Parent     : "+path.getParent());
System.out.println("Root       : "+path.getRoot());
The output will be
Name Count : 2
Parent     : C:\temp
Root       : C:\
Files
Path can also be used for deleting. There are two delete methods. One delete method can throw NoSuchFileException if the file doesn't exist.
Files.delete(path);
Where as other deletes the file if exists.
Files.deleteIfExists(path);
There are copy, move, create (Both for directories and files) with options. There are mthods to create symbolic links, temporary directories as well.
WatchService
This is the service which we can get the file change notifications like delete, update, create, change etc. WatchService API makes to receive notifications on a file or directory.
   Path path = Paths.get("C:\\Temp");
   WatchService service = path.getFileSystem().newWatchService();
   path.register(service, StandardWatchEventKinds.ENTRY_CREATE,
            StandardWatchEventKinds.ENTRY_DELETE,
            StandardWatchEventKinds.ENTRY_MODIFY);
   WatchKey watckKey = service.take();
   List<watchevent>&gt; events = watckKey.pollEvents();
   for(WatchEvent event : events)
   {
       System.out.println("Event : "+event.kind().name()+"; Context : "+event.context());
   }
The steps for creating a WatchService are
  • Create WatchService instance using path
  • Register required events (Create, delete and modify are available) on the path
  • Get the watch key and poll for the events. (For continuously watching the events, put it in infinite loop).
Happy Learning!!!

Thursday, August 15, 2013

What's in .Class file - Contd.

This is continuation of post. Now, we will see bit in detail with an example
package com.test;
public class Employee
{
     .....
     public void setEmpid(int empid)
     {
          this.empid = empid;
     }
     ....    
     public double getSalary()
     {
          return salary;
     }
     public void setSalary(double salary)
     {
          this.salary = salary;
     }
}
For example, take the above block's byte code one by one
public void setEmpid(int);
  Code:
   0:   aload_0
   1:   iload_1
   2:   putfield        #2; //Field empid:I
   5:   return
The code is pretty readable. load means loading a value. Each load is prefixed by a character ( 'i' means integer, 'd' means decimal and 'a' means an object. putfield means setting a value to other variable. Each function will have a return statement at the end. If the function has a void return type, then simple return otherwise return will be prefixed by a character. For example getSalary() method as below
public double getSalary();
  Code:
   0:   aload_0
   1:   getfield        #4; //Field salary:D
   4:   dreturn
Each and every line in the java byte code is called opcode as we discussed has a special meaning. We can find the list of all opcodes in the JVM Spec or on Wiki. Apart from the load, put, get, return, new (That we saw). There are method invocations which you will find more common. These start with invoke prefix
  • invokespecial: Used to call the instance private as well as public method (including initializations)
  • invokevirtual : Used to call a method based on the class of the object. 
  • invokestatic : Invokes a static method. 
  • so on....
Will post some more details in the next posts.

Sunday, July 28, 2013

Spring OXM

OXM is Spring's Object/XML Mapping support which helps in conversion of Object to XML(Marshalling) and XML to Object(Unmarshalling). For this, spring has two interfaces Marshaller and Unmarshaller defined in spring-oxm under the package org.springframework.oxm.Marshaller . These can be defined as normal beans like other spring beans.
Marshaller and Unmarshaller has one method each for the actions as below.
public interface Marshaller {
    /**
     * Marshals the object graph with the given root into the provided Result.
     */
    void marshal(Object graph, Result result) throws XmlMappingException, IOException;
}
public interface Unmarshaller {
    /**
     * Unmarshals the given provided Source into an object graph.
     */
    Object unmarshal(Source source) throws XmlMappingException, IOException;
}
Implementation:
There are different marshaller instances in spring-oxm. We will go through CastorMashaller because it's easy to implement and configure.
<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="converter" class="com.test.spring.oxm.converter.Converter">
  <property name="marshaller" ref="castorMarshaller" />
  <property name="unmarshaller" ref="castorMarshaller" />
 </bean>
 
 <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller">
  <property name="mappingLocation" value="classpath:mapping.xml" />
 </bean>
</beans>
CastorMarshaller is the marshaller and it requires one optional property "mappingLocation" which defines the mapping of class to xml. Sample mapping.xml file is
<?xml version="1.0" encoding="UTF-8"?>
<mapping>
 <class name="com.test.spring.oxm.entity.Employee">
  <map-to xml="employee" />
  <field name="empid" type="integer">
   <bind-xml name="id" node="element" />
  </field>
  <field name="name" type="string">
   <bind-xml name="ename" node="element" />
  </field>
   <field name="dob" type="date" >
   <bind-xml name="dob" node="element"  />
  </field>
   <field name="salary" type="double">
   <bind-xml name="salary" node="element" />
  </field>
 </class>
</mapping>
Points to be noted
  • property "mappingLocation" is optional. We can create CastorMarshaller without mappingLocation but it takes default values while binding
  • Each class tag defines the Object which to be marshalled/unmarshalled with set of field tags. Each corresponds to XML and object mapping.
  • type on the field indicates the type of the node and is mapped to Java Type.
  • map-to and bind-xml tags defines the elements and attributes in the xml. 
  • node attribute in bind-xml defines whether the field should be attribute or element

Code for bean "converter" is as below. Converter internally calls the marshall and unmarshall methods of CastorMarshaller.
package com.test.spring.oxm.converter;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;

public class Converter
{
    private Marshaller marshaller;
    private Unmarshaller unmarshaller;

    public Marshaller getMarshaller()
    {
        return marshaller;
    }

    public void setMarshaller(Marshaller marshaller)
    {
        this.marshaller = marshaller;
    }

    public Unmarshaller getUnmarshaller()
    {
        return unmarshaller;
    }

    public void setUnmarshaller(Unmarshaller unmarshaller)
    {
        this.unmarshaller = unmarshaller;
    }
    
    public String convertToXml(Object obj,String filepath)
    {
        String finalString = new String();
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(filepath);
            getMarshaller().marshal(obj, new StreamResult(fos));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally {
            if(fos != null)
            {
                try
                {
                    fos.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        return finalString;
    }
    
    public Object convertToObject(String filepath)
    {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(filepath);
            return getUnmarshaller().unmarshal(new StreamSource(fis));
        } 
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally {
            if(fis != null)
            {
                try
                {
                    fis.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
The object which to marshalled or unmarshalled is
package com.test.spring.oxm.entity;

import java.util.Date;

public class Employee
{
    private int empid;
    private String name;
    private Date dob;
    private Double salary;

    public int getEmpid()
    {
        return empid;
    }
    public void setEmpid(int empid)
    {
        this.empid = empid;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public Date getDob()
    {
        return dob;
    }
    public void setDob(Date dob)
    {
        this.dob = dob;
    }
    public Double getSalary()
    {
        return salary;
    }
    public void setSalary(Double salary)
    {
        this.salary = salary;
    }
}
Finally, the main program is
package com.test.spring.oxm;

import java.util.Date;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.spring.oxm.converter.Converter;
import com.test.spring.oxm.entity.Employee;

public class Application
{
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        Converter converter = (Converter)context.getBean("converter");
        Employee emp = new Employee();
        
        emp.setDob(new Date());
        emp.setEmpid(1234);
        emp.setName("Employee Name");
        emp.setSalary(2500.122);
       
        converter.convertToXml(emp,"cust.xml");
        
        Employee emp2 = (Employee)converter.convertToObject("cust.xml");
        System.out.println("Empid : "+emp2.getEmpid());
        System.out.println("Name  : "+emp2.getName());
        System.out.println("Salary: "+emp2.getSalary());
        System.out.println("DOB   : "+emp2.getDob());
    }
}
The xml file generated out of it is :
<?xml version="1.0" encoding="UTF-8"?>
<employee>
 <id>1234</id>
 <ename>Employee Name</ename>
 <dob>2013-07-28T21:17:29.331+05:30</dob>
 <salary>2500.122</salary>
</employee>

Friday, July 26, 2013

What's in .Class File

I never looked what's inside .class file except knowing that .class file consists of compiled byte code of Java Program. I was looking at quite a few articles, specifications, posts etc to get to know about byte class exact contents.
We already know what compiler does, what is a byte code, how byte code is executed by jre. Below is the brief definition.
Byte code: Java compiler (javac) generates the byte code for each Java file compiled. Byte-code is a sequence of mnemonics. Each of them will be translated by java run time environment to execute.
There are many mnemonics byte code consists of. Let's take a look at some of them with some examples which are very frequent.
Example 1:
package com.test;
public class Main
{
     public static void main(String...args)
     {
          System.out.println("Hello World");
     }
}
After compiling the Main.java, the generated class file looks like as below when you open in any hexa-decimal supported editor.




















To view the byte code in ASCII, we can use javap command.
Example: javap <class-name> displays the Class with methods in it where as -c option shows the each line of code inside the methods.












There are some basic points in the above lines of byte-code. As we know, each and every class we write, will be a sub-class of java.lang.Object ( as we can see extends java.lang.Object even we don't have that in .java file) and a default constructor is added with no parameters.
javap prints more detailed information
-s : the internal signature
-l : the line numbers and local variables used inside each function
And to print all the information, just give -verbose. Sample output looks like this

Interesting fact is, even though the java file is so simple with very few statements, compiler generated very large set of statements with tables, signatures, etc. We will see the details of few instructions in the next posts.

Thursday, July 25, 2013

Hibernate Caching - Second Level Cache

First Level Cache of hibernate (Detailed in the last post) is more specific to Session. Second Level Cache is another level where the cache is maintained in different regions across the sessions. The second level cache is divided into four regions: entity, collection, query, and timestamp.
Entity and Collection regions cache data from entities and their relations. 
The Query cache caches the result set of the database against the query. 
The Timestamp cache keeps track of last updated time of each table.
There will be on timestamp cache enabled for each query cache. The following properties to be set to enable the second level caching
hibernate.cache.use_second_level_cache = true|false
hibernate.cache.use_query_cache = true|false
hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.EhCacheRegionFactory
Since Hibernate4, the factory "org.hibernate.cache.ehcache.EhCacheRegionFactory" to be used instead of "net.sf.ehcache.hibernate.EhCacheRegionFactory"
In addition to above lines, the objects to be specified with the cache strategy. The line to be specified in the hibernate hbm file in <class> tag is
<cache usage="read-write|nonstrict-read-write|read-only" />
If to be specified in Annotations on the Entity Class, use
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
How it Works

  • When we fetch an object using hibernate, it searches the object in first level cache. If found, it returns the object
  • If the object not found in first level cache, checks the second level cache. If found, stores the object in first level cache returns
  • If the entity is not found both the levels, a database query is fired and stores in both the levels and returns.
  • The second level cache validates all of its entities, if any modifications are done through hibernate APIs. But, it never know if the database object is modified by any other resource unless "timeToLiveSeconds" duration has passed 

Notes:
To view the statistics of Entity fetches, second level cache hits, etc. We need to configure explicitly as.
hibernate.generate_statistics=true|false
and using "sessionFactory.getStatistics()" which retunrs an object of Statistics type. 

Hibernate Caching - First Level Cache

Caching is one of the basic feature provided by ORM frameworks. Caching make the application to run faster by reducing number of queries to the database. Hibernate provides two levels of cache for this.
  1. First Level Cache: First level cache is associated with each session. This cache is by default and you cannot switch off this. As we can create sessions on demand, there will be first level cache associated with each session.
  2. Second Level Cache: Second level cache is associated with Session Factory. Basically, there is only one second level cache as only one Session Factory is maintained by application.
When a session is closed, the first level cache associated with it will be cleared. When a session factory is cleared, full second level cache associated with it will be lost.

Example for First level cache:

   SessionFactory sessionFactory = (SessionFactory) context.getBean("sessionFactory");
   Session session = sessionFactory.openSession();
        
   Employee emp = null;
   emp = (Employee) session.load(Employee.class, new Integer(1));
   System.out.println("Employee Name : "+emp.getName());
        
   emp = (Employee) session.load(Employee.class, new Integer(1));
   System.out.println("Employee Name : "+emp.getName());
        
   Session newSession = sessionFactory.openSession();
   emp = (Employee) newSession.load(Employee.class, new Integer(1));
   System.out.println("Employee Name : "+emp.getName());
        
   session.evict(emp);
   emp = (Employee) session.load(Employee.class, new Integer(1));
   System.out.println("Employee Name : "+emp.getName());
        
   newSession.clear();
   emp = (Employee) newSession.load(Employee.class, new Integer(1));
   System.out.println("Employee Name : "+emp.getName());
The log for the above program will be :
Hibernate: select employee0_.id as id0_0_, employee0_.age as age0_0_, employee0_.name as name0_0_ from EMP employee0_ where employee0_.id=?
Employee Name : name
Employee Name : name
Hibernate: select employee0_.id as id0_0_, employee0_.age as age0_0_, employee0_.name as name0_0_ from EMP employee0_ where employee0_.id=?
Employee Name : name
Hibernate: select employee0_.id as id0_0_, employee0_.age as age0_0_, employee0_.name as name0_0_ from EMP employee0_ where employee0_.id=?
Employee Name : name
Hibernate: select employee0_.id as id0_0_, employee0_.age as age0_0_, employee0_.name as name0_0_ from EMP employee0_ where employee0_.id=?
Employee Name : name

Explanation:
First time when load method called, the object is fetched by firing a query to database. When the second time loaded, no query was fired as the object is cached in first level cache.
Even though the object is cached by session "session", the new session "newSession" is fetched the object by firing a new query.
To clear the cache from the session, evict() or clear() method can be used. Once it's cleared, the session tries to get the object from the database. The last two queries of hibernate in the log explains that.

Notes:

  • First level cache is only associated to Session. Each session will have it's own first level cache.
  • There is no extra configuration required for first level cache. No way to switch off configuration.
  • Cache will be cleared by closing the session, by using clear() method.
  • Individual object can be removed from the cache by using evict method.

Monday, June 24, 2013

MDB Using Jboss 7

Jboss 7 architecture is completely changed compared to the previous versions. Due to this, there is a change in configuration of queues, connection factories, security etc. Here, we are not going to see how we create MDB, rather we will look at how to configure to work in Jboss7 and how to create a standalone client to send a message to Queue on Jboss7.
Jboss7 has been fully modulated, we treat each and every component of jboss7 as separate module. This has to be done in standalone.xml file. By default, we get different versions of standalone files like standalone, standalone-full etc. I prefer to use standalone.xml and add modules as required.
To enable messaging we need to add the following lines to standalone file
  • In <extensions> tag, add
<extension module="org.jboss.as.messaging"/>
  • Add sub-system in <profile>
<subsystem xmlns="urn:jboss:domain:messaging:1.1">
    <hornetq-server>
        <persistence-enabled>true</persistence-enabled>
        <journal-file-size>102400</journal-file-size>
        <journal-min-files>2</journal-min-files>

        <connectors>
            <netty-connector name="netty" socket-binding="messaging"/>
            <netty-connector name="netty-throughput" socket-binding="messaging-throughput">
                <param key="batch-delay" value="50"/>
            </netty-connector>
            <in-vm-connector name="in-vm" server-id="0"/>
        </connectors>

        <acceptors>
            <netty-acceptor name="netty" socket-binding="messaging"/>
            <netty-acceptor name="netty-throughput" socket-binding="messaging-throughput">
                <param key="batch-delay" value="50"/>
                <param key="direct-deliver" value="false"/>
            </netty-acceptor>
            <in-vm-acceptor name="in-vm" server-id="0"/>
        </acceptors>

        <security-settings>
            <security-setting match="#">
                <permission type="send" roles="guest"/>
                <permission type="consume" roles="guest"/>
                <permission type="createNonDurableQueue" roles="guest"/>
                <permission type="deleteNonDurableQueue" roles="guest"/>
            </security-setting>
        </security-settings>

        <address-settings>
            <address-setting match="#">
                <dead-letter-address>jms.queue.DLQ</dead-letter-address>
                <expiry-address>jms.queue.ExpiryQueue</expiry-address>
                <redelivery-delay>0</redelivery-delay>
                <max-size-bytes>10485760</max-size-bytes>
                <address-full-policy>BLOCK</address-full-policy>
                <message-counter-history-day-limit>10</message-counter-history-day-limit>
            </address-setting>
        </address-settings>

        <jms-connection-factories>
            <connection-factory name="InVmConnectionFactory">
                <connectors>
                    <connector-ref connector-name="in-vm"/>
                </connectors>
                <entries>
                    <entry name="java:/ConnectionFactory"/>
                </entries>
            </connection-factory>
            <connection-factory name="RemoteConnectionFactory">
                <connectors>
                    <connector-ref connector-name="netty"/>
                </connectors>
                <entries>
                    <entry name="RemoteConnectionFactory"/>
                    <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                </entries>
            </connection-factory>
            <pooled-connection-factory name="hornetq-ra">
                <transaction mode="xa"/>
                <connectors>
                    <connector-ref connector-name="in-vm"/>
                </connectors>
                <entries>
                    <entry name="java:/JmsXA"/>
                </entries>
            </pooled-connection-factory>
        </jms-connection-factories>

        <jms-destinations>
            <jms-queue name="MyQueue">
                <entry name="queue/MyQueue"/>
                <entry name="java:jboss/exported/jms/queue/MyQueue"/>
            </jms-queue>
        </jms-destinations>
    </hornetq-server>
</subsystem>
  • This creates a queue named MyQueue. Now i can deploy a MDB listening to the queue "MyQueue". Listener class is as follows.
@MessageDriven(activationConfig = {
  @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
  @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/MyQueue") }, mappedName = "MyQueue")
public class QueueListener implements MessageListener {

 private static final Logger logger = Logger.getLogger(QueueListener.class);

 /**
  * @see MessageListener#onMessage(Message)
  */
 public void onMessage(Message message) {
  logger.debug("Inside onMessage");
  try {
   if (message instanceof TextMessage) {

    TextMessage msg = (TextMessage) message;
    logger.info("Message : " + msg.getText());
   }
  } catch (Exception e) {
   logger.error("Exception while processing the message ", e);
  }

 }
}
  • After deploying, start the Jboss7, you will find log saying QueueListener is listening using hornetq-ra resource adapter. Now, it's time to send a message to the Queue. Here is the client which can send the message to the Queue.
public class MDBClient {
 public static void main(String... strings) {
  try {
   final Properties props = new Properties();
   props.put(Context.INITIAL_CONTEXT_FACTORY,     "org.jboss.naming.remote.client.InitialContextFactory");
   props.put(Context.PROVIDER_URL, "remote://localhost:4447");
   props.put(Context.SECURITY_PRINCIPAL, "sample");
   props.put(Context.SECURITY_CREDENTIALS, "sample123");

   InitialContext context = new InitialContext(props);
   QueueConnectionFactory factory = (QueueConnectionFactory) context     .lookup("jms/RemoteConnectionFactory");
   Queue queue = (Queue) context.lookup("jms/queue/MyQueue");
   QueueConnection cnn = factory.createQueueConnection("sample",     "sample123");
   QueueSession session = cnn.createQueueSession(false,     QueueSession.AUTO_ACKNOWLEDGE);
   QueueSender sender = session.createSender(queue);
   TextMessage message = session.createTextMessage();
   message.setText("Text Message");
   sender.send(message);
   context.close();
   cnn.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
  • Run the above code, which sends the message to Jms Queue "MyQueue". Add jboss-client.jar ($JBOSS_HOME/bin/client/jboss-client.jar) to classpath to get it running.
Points to remember
  1. Remote JNDI : A new entry added for RemoteConnectionFactory (java:jboss/exported/jms/RemoteConnectionFactory) to expose it so that it can be called looked up from remote. Same is the case for the queue (java:jboss/exported/jms/queue/MyQueue)
  2. Security: Credentials to be passed to the Context and While creating connection to connect to Queue. The credentials must be of user who belongs to group (guest). User can be setup by using adduser script in $JBOSS_HOME/bin.
  3. Off the Secutiry: We can off the security by adding <security-enabled>false</security-enabled> to the hornetq-server element
  4. Jboss-Client: jboss-client.jar which is added to Standalone client classpath.

Sunday, May 19, 2013

JAXB XML Adapter

JAXB provides XMLAdapter to change the format of default JAXB types. For example, formatting decimal places in Decimal or BigDecimal, Date formatting etc.
How to do it?
First look at the following plain vanilla example of JAXB
package com.test;

import java.math.BigDecimal;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.datatype.XMLGregorianCalendar;

@XmlRootElement
public class Loan {
	private String name;
	private Long amount;
	private XMLGregorianCalendar startDate;
	private BigDecimal interestRate;
	public String getName() {
		return name;
	}
	@XmlElement
	public void setName(String name) {
		this.name = name;
	}
	public BigDecimal getInterestRate() {
		return interestRate;
	}
	@XmlElement
	public void setInterestRate(BigDecimal interestRate) {
		this.interestRate = interestRate;
	}
	public XMLGregorianCalendar getStartDate() {
		return startDate;
	}
	@XmlElement
	public void setStartDate(XMLGregorianCalendar startDate) {
		this.startDate = startDate;
	}
	public Long getAmount() {
		return amount;
	}
	@XmlElement
	public void setAmount(Long amount) {
		this.amount = amount;
	}	
}
If we marshall the Loan object, the output is similar to
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<loan>
    <amount>200000</amount>
    <interestRate>15.6</interestRate>
    <name>Name</name>
    <startDate>2013-05-19T16:02:51.080+05:30</startDate>
</loan>
Now, format the XMLGregorianCalendar to YYYY-MM-DD in XML. For this, we need to add a new XMLAdapter which can convert(marshall) from Calendar format to String format.
package com.test;

import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.datatype.XMLGregorianCalendar;

public class CalendarAdaptor extends XmlAdapter<String, XMLGregorianCalendar> {

	@Override
	public String marshal(XMLGregorianCalendar v) throws Exception {
		return v.getYear()+"-"+v.getMonth()+"-"+v.getDay();
	}

	@Override
	public XMLGregorianCalendar unmarshal(String v) throws Exception {
		return null;
	}
}
and Add the Adapter to the property where we would like to change. So the Loan.java file will be changed at the setStartDate method to following
        @XmlJavaTypeAdapter(CalendarAdaptor.class)
	public void setStartDate(XMLGregorianCalendar startDate) {
		this.startDate = startDate;
	}
When we marshall the same Loan object now, with the above change, the xml string will be
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<loan>
    <amount>200000</amount>
    <interestRate>15.6</interestRate>
    <name>Name</name>
    <startDate>2013-5-19</startDate>
</loan>
But the thing is, we need to change each property for the class definitions to affect this change. Instead of changing the classes, we can provide this adapter change at the package level by defining a class called package-info.java without changing the individual class properties. By doing this, all the XMLGregorianCalendar attributes in the package will follow the format defined by the Adapter. package-info.java
@XmlJavaTypeAdapter(value=CalendarAdaptor.class, type=XMLGregorianCalendar.class)
package com.test;

import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

Sunday, March 17, 2013

Timer Service Using EJB 3.1

In the last post, we saw how to have scheduled processing using JBoss. The scheduling was very specific to JBoss. Let's look at how can we schedule using EJB 3.1. J2EE providers provided us with the EJB timers as alternative to threads for the timed notifications. We can schedule them like crontab in UNIX by specifying the day, hours, minutes, seconds to the service get invoked by the container.
The following example demonstrates how to use the EJB Timer service. I have created a very simple EJB application with one Stateless bean service which is being invoked by the Timer Service of the EJB.
  • Create a class with a call back method. Annotate the method with "Schedule" to make the method being called by the TimerService of EJB.
package com.test.ejb.timer;

import javax.ejb.EJB;
import javax.ejb.Schedule;
import javax.ejb.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.test.ejb.stateless.SimpleStatelessService;

@Singleton
public class SimpleTimer {
 
     private static final Logger LOG = LoggerFactory.getLogger(SimpleTimer.class);
     
     @EJB
     SimpleStatelessService service;
     
     @Schedule(hour="*", minute="*", second="10")
     public void startTimer() {
          LOG.info("Timer started... Invoking the bean");
          service.invokeBeanMethod();
     }    
}
The attributes inside the Schedule annotation are as follows
AttributeDescriptionValue
secondOne or more seconds within a minute0 to 59, default is 0
minuteOne or more minutes within an hour0 to 59, default is 0
hourOne or more hours within a day0 to 23, default is 0
dayOfWeekOne or more days within a week0 to 7 (Sunday to Sunday) default is * (Everyday). Even Mon, Tue etc are allowed
dayOfMonthOne or more days within a month1 to 31. Default is *. (Negative values are accepted, -5 means 5th day from end of the month)
monthOne or more months within a year1 to 12. Default is *. Names of the months are also allowed like Jan, Feb etc
yearA particular calendar yearA four digit year. Default is *
  • I have created a simple stateless bean named "SimpleStatelessSerive" to be invoked by the TimerService from the callback method startTimer().
package com.test.ejb.stateless;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Session Bean implementation class SimpleStatelessService
 */
@Stateless
@LocalBean
public class SimpleStatelessService {
     private static final Logger LOG = LoggerFactory.getLogger(SimpleStatelessService.class);
    /**
     * Default constructor. 
     */
    public SimpleStatelessService() {
        LOG.info("Service Created....");
    }
    public void invokeBeanMethod()
    {
         LOG.info("Inside invokeBean method");
    }
}
  • Deploy the EJB application onto Application server. I deployed it on Jboss6. The timer service started and invoking the callback method for every 10th second of the each minute as specified in the Schedule annotation.
Glimpse of the server log is
14:28:10,010 INFO  [com.test.ejb.timer.SimpleTimer] Timer started... Invoking the bean
14:28:10,011 INFO  [com.test.ejb.stateless.SimpleStatelessService] Service Created....
14:28:10,011 INFO  [com.test.ejb.stateless.SimpleStatelessService] Inside invokeBean method
14:29:10,009 INFO  [com.test.ejb.timer.SimpleTimer] Timer started... Invoking the bean
14:29:10,010 INFO  [com.test.ejb.stateless.SimpleStatelessService] Service Created....
14:29:10,010 INFO  [com.test.ejb.stateless.SimpleStatelessService] Inside invokeBean method

We can configure multiple callback methods for scheduling and each callback can be scheduled for multiple times. Have a look at the following sample code with two callback methods configured for Scheduling.
package com.test.ejb.timer;

import javax.ejb.EJB;
import javax.ejb.Schedule;
import javax.ejb.Schedules;
import javax.ejb.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.test.ejb.stateless.SimpleStatelessService;

@Singleton
public class SimpleTimer {
     private static final Logger LOG = LoggerFactory.getLogger(SimpleTimer.class);  
     @EJB
     SimpleStatelessService service;
     
     @Schedules( {
          @Schedule(hour="*", minute="*", second="10"),
          @Schedule(hour="*", minute="*", second="13")
     })
     public void startTimer() {
          LOG.info("Timer started... Invoking the bean");
          service.invokeBean();
     }
     
     @Schedule(minute="3")
     public void antoherTimer() {
          LOG.info("Another Timer started.. Invoking the bean");
          service.invokeBean();
     }
}
There are two schedulers configured now.
  1. The startTimer() method is being configured for two scheduled times. One is every 10th second of the minute and the other is every 13th second of the minute. 
  2. The anotherTimer() which is being called every 3rd minute of the hour.

Saturday, March 16, 2013

Scheduling in JBoss

We will look at how to schedule a process in JBoss like crontab in UNIX. This can be done in JBoss by using Schedulers. Schedulers provides a simple callback method by implementing the Schedulable interface in custom Java class. It is very easy to use this for scheduling even though we have many options like crontab in UNIX, Timers, etc because of it's easy implementation.

Lets see how to create a Scheduler in JBoss in 2 simple steps

1. Create a simple XML file for the configuration of the Scheduler. The attributes allowed in the configuration xml and their descriptions are

o    InitialStartDate : Date when the initial call is scheduled. It can be either:
o    NOW: date will be the current time plus 1 seconds
o    A number representing the milliseconds since 1/1/1970
o    Date as String able to be parsed by SimpleDateFormat 
o    InitialRepetitions : The number of times the scheduler will invoke the target's callback. If -1 then the callback will be repeated until the server is stopped.
o    StartAtStartup : A flag that determines if the Scheduler will start when it receives its startService life cycle notification. If true the Scheduler starts on its startup. If false, an explicit startScheduleoperation must be invoked on the Scheduler to begin.
o    SchedulePeriod : The interval between scheduled calls in milliseconds. This value must be bigger than 0.
o    SchedulableClass : The implementation class of  the org.jboss.varia.scheduler.Schedulable interface.
o    SchedulableArguments : A comma separated list of arguments passed to implementation class(Only primitives and String types are supported).
o    SchedulableArgumentTypes : The list of argument types passed in the above attribute.
o    SchedulableMBean : Specifies the fully qualified JMX ObjectName name of the schedulable MBean to be called. When using SchedulableMBean the SchedulableMBeanMethod must also be specified.
o    SchedulableMBeanMethod : Specifies the operation name to be called on the schedulable MBean.

<?xml version="1.0" encoding="UTF-8"?>
<server>
    <mbean code="org.jboss.varia.scheduler.Scheduler" name=":service=My-Scheduler">
        <attribute name="StartAtStartup">true</attribute>
        <attribute name="SchedulableClass">com.test.scheduler.MyScheduler</attribute>
        <attribute name="SchedulableArguments">MyScheduler</attribute>
        <attribute name="SchedulableArgumentTypes">java.lang.String</attribute>
        <attribute name="InitialStartDate">0</attribute>
        <attribute name="SchedulePeriod">5000</attribute>
        <attribute name="InitialRepetitions">-1</attribute>
    </mbean>
</server>

2. Create a class and implement Schedulable Interface. We need to implement only one method perform which takes two parameters. One is Date type, the actual date when it is being called and the other is number of times the scheduler invokes the callback method(The parameter of attribute InitialRepetitions)
package com.test.scheduler;

import java.util.Date;

import org.jboss.varia.scheduler.Schedulable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyScheduler implements Schedulable {
     
     private static final Logger LOG = LoggerFactory.getLogger(MyScheduler.class);
     private String name;
     
     public MyScheduler(String name) {
          this.name = name;
     }

     @Override
     public void perform(Date arg0, long arg1) {
          LOG.info("Started "+name);
          LOG.info("Date "+arg0+" Time "+arg1);
     }

}

That's it. Its time to deploy and run it. Deploy the class into Jboss via jar or ear project. Put the xml file in jboss deploy directory and start JBoss Server.
Once started, you will be able to see the following Log in the JBoss server log. The Scheduler calls the callback function once in every 5 seconds as defined in configuration XML.
22:21:05,066 INFO  [MyScheduler] Started MyScheduler
22:21:05,066 INFO  [MyScheduler] Date Sat Mar 16 22:21:05 IST 2013 Time -1
22:21:10,067 INFO  [MyScheduler] Started MyScheduler
22:21:10,067 INFO  [MyScheduler] Date Sat Mar 16 22:21:10 IST 2013 Time -1
22:21:15,068 INFO  [MyScheduler] Started MyScheduler
22:21:15,068 INFO  [MyScheduler] Date Sat Mar 16 22:21:15 IST 2013 Time -1

The timer will be running, until you stop the Jboss

Tuesday, March 5, 2013

Dependency Injection and Spring

When it comes to Spring, it always said that Dependency Injection is the major feature of Spring. In the last post i gave an example on how to use spring with a very basic example.

Let's see what's dependency injection is?

In Object oriented world, each and every application is collection of objects working together. In order to work together, there might me some relation (dependency in general sense) between the objects.

For example, i take an application of polymorphism in Java.

package com.test.appl;
public interface Shape 
{ 
     public abstract void draw();
}
package com.test.appl;
public class Rectangle implements Shape 
{
   @Override
   public void draw() 
   {
       System.out.println("Drawing Rectangle");
   }
}
package com.test.appl;

public class Triangle implements Shape 
{
   @Override
   public void draw() 
   {
       System.out.println("Drawing Triangle");
   }
}
It's a very old story. Let me repeat it again. Triangle and Rectangle are types of Shape. The methods of types will be called based on the object assigned to reference of Shape Class.

package com.test.appl;

public class Main 
{ 
   public static void main(String...strings)
   {
       Shape traingle = new Triangle();
       traingle.draw();
  
       Shape rectangle = new Rectangle();
       rectangle.draw();
   }
}

But there is dependency between the objects creation and assigning it to Shape references, and we do call at the same time when it was created. In short, they are tightly coupled.

We can slightly remove the dependency between Parent and its types, by creating an helper class, say ShapeHelper as defined below.

package com.test.appl;

public class ShapeHelper 
{ 
    private Shape shape;
 
    public ShapeHelper(Shape shape)
    {
        this.shape = shape;
    }
 
    public void doDraw()
    {
        shape.draw();
    }
}

ShapeHelper is the class which accepts an object of type Shape (can be Triangle or Rectangle in the current scenario . A method doDraw() is added which internally calls the draw method of Shape type. So, if we assign shape to an object of Rectangle , it calls the draw method of Rectangle(basic of runtime polymorphism). 

package com.test.appl;

public class MainWithHelper {
 
    public static void main(String...strings)
    {
        ShapeHelper sHelper = new ShapeHelper(new Triangle());
        sHelper.doDraw();
        Triangle t = new Triangle();
        sHelper = new ShapeHelper(t);
        sHelper.doDraw();
        sHelper = new ShapeHelper(new Rectangle());
        sHelper.doDraw();
    }
}

From the above example, the dependency in assigning of the objects to Shape has been removed with the help of an Helper Class. The shape is said to be injected into the ShapeHelper class.

This way of removing the dependency between the objects by injecting is called Dependency Injection (in other words. but not exactly)

Spring does this for us, with a simple xml configuration. Instantiation of objects and injecting the dependencies will be done by Spring configuration xml file(In short spring context file).

Let's write the same example in Spring with spring-context file as spring context file
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
    <bean class="com.test.appl.Triangle" id="triangle" ></bean>
    <bean class="com.test.appl.Rectangle" id="rectangle"></bean>
  
    <bean class="com.test.appl.ShapeHelper" id="helper1">
        <property name="shape" ref="triangle">
    </property></bean>
  
</beans>
I have created two different beans (one for triangle and one for rectangle). and one bean for Helper class. I injected the triangle bean into ShapeHelper. In the same way, we can inject rectangle bean.

Now, the question is how do we access them. See the below code on how to access. We need to create the ApplicationContext and then get the bean to call it's methods

package com.test.spring.appl;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.appl.ShapeHelper;

public class DIApplication 
{
    public static void main(String...strings)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        ShapeHelper helper = (ShapeHelper)context.getBean("helper1");
        helper.doDraw();
    }
}

The the helper will call the draw() of triangle as the injected object is triangle  To call the draw method to Rectangle, we can change the xml file rather than the actual code. That is another advantage of Spring.

Sunday, March 3, 2013

Getting started with Spring

There are only three simple steps to do it. Let's see a simple example on how to start with Spring.

1. Create a bean class, beans are nothing but simple POJOs.

package com.myexamples.spring;
class Student
{
      private String name;
      public String getName()
      {
           return name;
      }
      public void setName(String name)
      {
           this.name = name;
      }
}

2. Create bean configuration file - spring-context.xml
<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-2.5.xsd">
 
 <bean id="studentBean" class="com.myexamples.spring.Student">
  <property name="name" value="John" />
 </bean>
</beans>
In spring-context.xml, we have defined one bean which is a plain pojo and passing an argument to it named "name"

3. Create the Application, which invokes the Bean
class MainClass
{
      public static void main(String...args)
      {
           ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
    Student std = (Student)context.getBean("studentBean");
    System.out.println(std.getName());
      }
}
MainClass is the actual application, which access the bean using ApplicationContext.

Steps to access the bean from Application Context

  1. Get an Instance of ApplicationContext, there are many types to get it. Here am using XmlApplicationContext.
  2. Get the bean from the context using getBean method. The beans created by Spring are by default singleton. So if an instance of studentBean exists then created otherwise returns the same instance again. While creating the instance, spring initializes with the properties mentioned in the context xml file (spring-context.xml in this case)
  3. Now if you print, getName(), it will print "John" on the console

Saturday, February 23, 2013

Spring Introduction

Introduction
Spring is a light-weight open source framework. Its initially written by Rod Johnson. Spring enables you to develop applications using POJOs. This got a laryered structure, so that you can choose to use any part of it as an isolation.
Spring Includes
  1. An IOC Light weight Container
  2. AOP Functionality
  3. Abstraction Layer for JDBC/Transaction management
  4. Web Integration Layer
  5. MVC Web Application Framework
Spring Modules
The following are the modules in Spring Architecture
spring-modules

Each of the Components can stand on its own or can be implemented jointly one or more jointly. The functionality of each component is as follows:
  1. Core: This is the basic component in the framework. It has the features of IoC and Dependency Injection. It provides a basic Container called BeanFactory. 
  2. AOP: It introdues aspect oriented programming feature in the Spring framework. Spring-AOP addresses the cross-cutting functionality. 
  3. DAO: This package supports both programmatic and declarative approaches to manage transactions. These can be used to add transaction capability not only for classes implementing special interfaces, but for all ordinary POJOs (plain old Java objects).
  4. ORM: The ORM package provides integration layers for popular object-relational mapping APIs such as JPA, JDO, Hibernate, and iBatis. Using the ORM package you can use these frameworks in combination with all the other features Spring offers, such as the simple declarative transaction management feature.
  5. Enterprise Integration: This package provides an integration layer for popular enterprise services including several remoting technologies, EJB, JMS, JMX, e-mail, and scheduling.
  6. Web Framework Integration: Spring’s Web package provides integration layer for popular web frameworks such as WebWork, Struts, JSF etc. It also provides features such as multipart file-upload functionality, initialization of the IoC container using servlet listeners and a web-oriented application context.



Templating with CI

Let’s see how to templating with CI.
  • Create Template : Create a file template.php in application/views with the below content.
<?php
$this->load->view(‘header’);
$this->load->view($content);
$this->load->view(‘footer’);
?>
  • Changing default Controller : By default, the controller will be welcome. If you want, you can change the configuration in application/config/routes.php file. Change the default_controller to your custom one (Note: Dont include extension).
  • Create Controller : Create the controller(If you have changed the default controller or exisitng one). Change the index function with the following .
$data['content']=’login’;
$this->load->view(‘template’,$data);
  • Create View : Create header.php, login.php and footer.php in application/views.
By default, the Login page will be opened in place of content. index is the default function called in the controller. As we mentioned the above lines of code in default contoller’s default function. So, when we open the page. we will login page with header and footer.
  • Example : the contents of the three files are as follows
header.php
<html>
<body>
This is header part
Footer.php
This is footer part
</body>
</html>
login.php
<?=form_open(‘welcome/login’); ?>
Login Name<br />
<?=form_input(‘username’,”,’class=text’)?><br />
Password<br />
<?=form_password(‘password’,”,’class=text’)?><br />
<input type=”submit” name=”login” value=”Login” class=”button” />
<?=form_close(); ?>
The first line in login.php says, when the form is submitted, the action goes to login function in welcome controller. Notation is controller/function_name. If we dont specify the function, by default index function will be called.
In the function login, do the login validation and re-direct based on the validation. For example
welcome.php
public function login() {
$user_name = $this->input->post(‘username’);
 $user_pass = $this->input->post(‘password’);
if($user_name == $user_pass ) {
$data['content'] = ‘home’;
}
else  {
$data['content']=’login’;
}
$this->load->view(‘template’,$data);
}
For login authentication, we can use models as well. Create the file in application/model and call in the controller.
User.php in application/model
$user = new User();
$user->username = $user_name;
$user->password = $user_pass;
$status = $user->login();
Instead of if condition in login function, use the status variable to redirect to the respective page. So, based on the login, it will redirect to login or home page.