Saturday, November 28, 2015

Java 8 - Streams (Part - I)

Stream represents a sequence of elements which can calculate or compute on-demand. Stream is an interface like an Iterator but it can do parallel processing. In other words, we can say Stream is a lazy collection where the values are computed on-demand.

How to Create

Streams are defined in java.util.stream package. Stream can be obtained using various options but a simple way is to get Stream is from Collection Interface. A default method defined as stream in Collection Interface to get it from the respective collection built. This is one of the best example to explain why the default methods are introduced in Java 8. See my previous post for more details on default methods. Collection Interface has two default methods for streams
  • stream(): Returns a stream associated with the collection for processing
  • parallelStream(): Same as stream method but returns for parallel processing. 
Stream here is the generic type. There are few streams defined for the primitive types as IntStream, DoubleStream, LongStream etc.

How to Use

As mentioned earlier - Streams are like Iterators or more than Iterators. Streams can be used to find an element, get first element, sort the elements etc. Apart from using streams on Collections, they can be used to operate on Paths, files, range of numbers etc. We will see few of them with examples

Streaming Files

BufferedReader class has got a new method lines() to return the lines in that file as Stream. See below
        try (FileReader fr = new FileReader("/tmp/sample.txt");
                BufferedReader br = new BufferedReader(fr))
        {
            br.lines().forEach(System.out::println);
        }
The above code returns the Stream which represents the sequence of lines in the file /tmp/sample.txt and, prints them. To add to it, Stream has got a method forEach to iterate over it. The Files class has also has a method lines() to read the Path as stream.
        try (Stream<String> st = Files.lines(Paths.get("/tmp/sample.txt")))
        {
            st.forEach(System.out::println);
        }

Streaming Patterns

Pattern can also return a Stream object with the matched values. Lets see that
        Pattern p = Pattern.compile("-");
        p.splitAsStream("5-13-93").forEach(System.out::println);
This will split the pattern 5-13-93 into three integers (5,13 and 93) and prints them.

Streaming Range

Stream interface has method to find range of primitive types (Int, Double or Long) as a Stream itself. We can use the respective Stream Interface (IntStream, DoubleStream and LongStream) to get the range associated with it. See - for example
IntStream.range(10, 20).forEach(System.out::println);

Stream Functions

Stream provides various methods to operate on Collections. We will discuss few of them here with examples. Most of the methods of Stream interface take lambda expression as argument (i.e. a method name - See Lambda Expressions for more details).

of:

This is a static method defined in Stream Interface to create a generic Stream. The method exists in other specific Streams like Double, Long etc to create its own type.
Stream<String> stream = Stream.of("Veeresh", "Blog", "Stream")

forEach:

The function will iterate through the Stream. All the above example has got forEach with prints to console

sort:

This method sorts the Stream elements associated with it in natural order (i.e. ascending order). See here
Stream.of("Veeresh", "Blog", "Stream").sorted().forEach(System.out::println);
The above code prints the sorted names. sort() is a very lazy function, means it doesn't effect until you call any other method after/before sort. In the above example - When the sort method was executed nothing changed on the Stream. Once the foreach method was called - the sorting was done.

Apart from these - stream has few other methods which are more powerful and useful which reduces developer effort, Increases readability and reduces LOC. We will discuss those in the next post. For now - this is it.

Happy Learning!!!!

Sunday, October 11, 2015

Default Methods in Java

Default Method is one of the features of Java 8. Default Method is
  • A method - which has a keyword default before it
  • Has to be defined only in Interface
  • Must be implementation. 
  • Can be overridden in Implemented Classes but has to be defined without default keyword.
  • An Interface can have multiple default methods
Default method may break the contract of an Interface because technically interface should consists of all abstract methods and no implementations. The main reason behind the concept of default method is to add steam method to collections (especially to interface) without breaking the implementation classes.

Example

  • As mentioned earlier, default method is a method with implementation in an Interface
public interface AInterface 
{
    public default void print()
    {
        System.out.println("Default Method in Interface A");
    }
}
  • If a class implements it, then it may or may not override the default method along with it's own methods.
public class AImplementation implements AInterface
{
    public void otherMethod()
    {
        System.out.println("New Method Defined in AImplementation");
    }
}
  • Calling a default is same as like other methods as below
AImplementation a = new AImplementation();
a.print();
a.otherMethod();
  • As multiple interfaces can be implemented by one class, but there is a probability of same default method with the same name, defined in both interfaces. Let's say another interface with a default method print like below
public interface BInterface
{
    default void print()
    {
        System.out.println("Default Method in Interface B"); 
    }
}
  • Now, if a class implements both AInterface and BInterface, which has same default method print, then compiler throws an error saying "Duplicate default methods named print with the parameters () and () are inherited from the types BInterface and AInterface". So, print method has to be overridden in the implemented Class like below
public class CImplementation implements AInterface, BInterface
{
    @Override
    public void print()
    {
        System.out.println("Default Method in Interface A");
    }
}

More details on the default methods and its use in Java will be explained in the next post.

Happy Learning!!!!

Sunday, September 27, 2015

Apache Camel-JPA

Camel JPA allows to route the Entities as Messages to read and write using Java Persistence Architecture (JPA). Let's quickly look at the configuration required to make Camel to route the messages (in fact entities) using camel-jpa.

Dependency

Add the following dependency along with camel-core to enable Camel JPA
<dependency>
	<groupId>org.apache.camel</groupId>
	<artifactId>camel-jpa</artifactId>
	<version>2.15.3</version>
</dependency> 

Component

Create JPA component using the class org.apache.camel.component.jpa.JpaComponent and inject Entity Manager Factory (and Transaction Manager if required)
<bean id="jpa" class="org.apache.camel.component.jpa.JpaComponent">
	<property name="entityManagerFactory" ref="entityManagerFactory" />
	<property name="transactionManager" ref="transactionManager" />
</bean>

EndPoint

Format of the JPA Endpoint URI to be defined as (Component, Entity Class and Options)
jpa://<fully-classified-entity-class-name?option1=value1&option2=value2.."

Few Notable Parameters 

  • entityType: Default value is Class Name of the entity. The option will override the entity class name.
  • consumeDelete: The table row will be deleted after processing. In order to avoid deleting - set it to false. 
  • consumer.query: Custom query to consume the data from the table. 
  • consumer.namedQuery: Custom named query to consume the data from the table.
  • consumer.nativeQuery: Custom native query to consume the data form the table.
  • consumer.delay: Polling interval in milli-seconds between two polls.

Reading from Endpoint

Selection

By default, JPA will read all the rows in the table. To read specific set of rows in the table - use consumer.query (, consumer.nativeQuery or consumer.namedQuery) to set the selection. 

Preserve Rows

After the row is read from the table, the endpoint deletes the processed row. In order to avoid deleting the row, set the parameter consumeDelete to false. 
If we set this parameter - there is a possibility of reading the same row again because the row still exists on the table. In order to avoid the same row to be picked again - we can update the row by creating a method (in the entity and changing the specific value) by annotating it with @Consumed. 

Sending to Endpoint

Send entity by entity to an endpoint, it writes row by row into the table. We can use aggregator to write a list of entities into the endpoint. In this case, we need to set an extra parameter : entityType as java.util.List to make all the rows persisted to the table. 

Example

Let's read rows from a table and write into the same table by changing few parameters.

Table

mysql> desc camel_test;
+---------+----------+------+-----+---------+-------+
| Field   | Type     | Null | Key | Default | Extra |
+---------+----------+------+-----+---------+-------+
| seq_no  | int(11)  | NO   |     | NULL    |       |
| status  | char(4)  | NO   |     | NULL    |       |
| column1 | char(20) | YES  |     | NULL    |       |
| column2 | char(40) | YES  |     | NULL    |       |
| column3 | int(11)  | YES  |     | NULL    |       |
| column4 | datetime | YES  |     | NULL    |       |
+---------+----------+------+-----+---------+-------+

Configuration

We will see the example using Hibernate and Spring JPA with MYSQL

persitance.xml

<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>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
            <property name="hibernate.show_sql" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

Datasource and Entity manager

<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" />

<bean id="entityManagerFactory"
	class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	<property name="dataSource" ref="mysqltestDataSource" />
	<property name="persistenceUnitName" value="testMysql" />
</bean>

Camel JPA

<bean id="jpa" class="org.apache.camel.component.jpa.JpaComponent">
	<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

Entity Class

package com.test.entity;
//Imports here.. 
@Entity
@Table(name = "camel_test")
@NamedQuery(name = "selectQuery", query = "select m from CamelTest m where m.status = 'P'")
public class CamelTest
{
    @Id
    @Column(name="seq_no")
    private Integer seq;
    
    @Column(name="status")
    private String status;
    
    @Column(name="column1")
    private String column1;
    
    @Column(name="column2")
    private String column2;
    
    @Column(name="column3")
    private Integer column3;
    
    @Column(name="column4")
    private Date column4;

    //Getters and Setters here
    
    @Consumed
    public void afterConsume()
    {
        setStatus("D");
    }
}

Points to be noted

  • The class is a JPA entity with one Named Query which will be used by JPA endpoint to read the data from the Table.
    • It reads the data from table whose status is 'P'
  • Only one extra method added which annotated with @Consumed (This will be executed after the entity is processed.
    •  After Camel JPA processing the record, the entity is changing the status to 'D' to avoid it from further reading

Finally Camel Route

<camel:camelContext id="camelContext">
	<camel:route>
		<camel:from uri="jpa://com.test.entity.CamelTest?consumer.namedQuery=selectQuery&amp;consumer.delay=10000&amp;consumeDelete=false" />
		<camel:to uri="direct:sample" />
	</camel:route>
</camel:camelContext>

Points to be noted

  • jpa is the JPA Component of Camel JPA
  • com.test.entity.CamelTest is the entity class created corresponding to camel_test table (as above)
  • Three options are set
    • consumeDelete to false to make the entity preserved after processing
    • consumer.dealy is set to 10 seconds to poll the table for every 10 seconds
    • consumer.namedQuery is set to read a specific set of rows (see NamedQuery annotation on the Entity). 
The above route just reads the rows from the table using the named query (selectQuery) with a polling delay of 10 secs, maps the entities, executes the @Consumed method (which modifies the status column from P to D so that the next poll will not pick the same row)  in the entity class after processing and finally sends the processed message to direct:sample (one by one)

Read in a batch

To read the rows in a batch, use aggregator

Aggreagor

package com.test.camel.aggregator;
//Imports
public class SampleAggregator implements AggregationStrategy
{
    @SuppressWarnings("unchecked")
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange)
    {
        List<CamelTest> list = null;
        if(oldExchange == null || oldExchange.getIn() == null)
        {
            list = new ArrayList<CamelTest>();
            list.add(newExchange.getIn().getBody(CamelTest.class));
        }
        else
        {
            list = oldExchange.getIn().getBody(List.class);
            list.add(newExchange.getIn().getBody(CamelTest.class));
        }
        newExchange.getIn().setBody(list);
        return newExchange;
    }
}

Modified Route as below with Aggregator

<camel:route>
	<camel:from uri="jpa://com.test.entity.CamelTest?consumer.namedQuery=selectQuery&amp;consumer.delay=10000" />
	<camel:aggregate strategyRef="aggregateStrategy" completionInterval="2000" completionSize="20" >
		<camel:correlationExpression>
			<camel:constant>true</camel:constant>	
		</camel:correlationExpression>
		<camel:to uri="direct:sample" />
	</camel:aggregate>
</camel:route>

Write to Table in Batch

Modify the same route to write a duplicate entry into the table by changing the Sequence Number. See the processor below

Processor

package com.test.camel.processor;
//Imports
public class SampleProcessor implements Processor
{
    public void process(Exchange exchange) throws Exception
    {
        //Processing goes here. Set the output to same as input. (Dummy Processing) 
        List<CamelTest> list = exchange.getIn().getBody(List.class);
        
        for(CamelTest t : list)
        {
            t.setSeq(t.getSeq() + 1000); 
        }
        exchange.getOut().setBody(list);     
    }
}

  • Processor - processor is used here to change the primary key of the entities to write it back (Other we get primary key violation error) - this is just for the example purpose - added 1000 for each sequence number.

Modified Route

<camel:route>
	<camel:from uri="jpa://com.test.entity.CamelTest?consumer.namedQuery=selectQuery&amp;consumer.delay=10000" />
	<camel:aggregate strategyRef="aggregateStrategy" completionInterval="2000" completionSize="20" >
		<camel:correlationExpression>
			<camel:constant>true</camel:constant>	
		</camel:correlationExpression>
		<camel:process ref="processor" />	
		<camel:to uri="jpa://com.test.entity.CamelTest?entityType=java.util.List" />
	</camel:aggregate>
</camel:route>
  • URI on the route (camel:to) has a parameter called entityType as java.util.List to save a list of entities back to table. (See Sending to Endpoint above)
Happy Learning!!!

Sunday, September 13, 2015

Apache Camel - Simple Routing Example

This post is continuation of the previous post Apache Camel overview. In this post, we will see how to define a sample route using Apache Camel (with Spring Integration).

Dependencies

Apache Camel can work easily with Spring. The following dependencies are required to make Apache Camel to work with Spring.
  <dependency>
       <groupId>org.apache.camel</groupId>
       <artifactId>camel-core</artifactId>
       <version>2.15.3</version>
  </dependency>
  <dependency>
       <groupId>org.apache.camel</groupId>
       <artifactId>camel-spring</artifactId>
       <version>2.15.3</version>
  </dependency>
camel-core is the actual dependency and camel-spring is required for the spring integration.

Spring Configuration

To add camel to Spring Configuration, add the following

Namespace

xmlns:camel="http://camel.apache.org/schema/spring"

Schema Location

xsi:schemaLocation="http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd"

Combined Spring XML

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:camel="http://camel.apache.org/schema/spring"
    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.xsd
              http://camel.apache.org/schema/spring 
              http://camel.apache.org/schema/spring/camel-spring.xsd">

</beans>         

Camel Context and Route

Camel context is the camel runtime. In Spring, we need to define the Camel Context to define the Route. Within the context, route must be defined.
Problem Statement: Read a file from a directory, process it and copy the processed file to a destination folder.

Define the Processor

package com.test.camel.processor;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SampleProcessor implements Processor
{
    private static final Logger LOG = LoggerFactory.getLogger(SampleProcessor.class);

    public void process(Exchange exchange) throws Exception
    {
        LOG.info("Input is "+exchange.getIn().getBody());
        //Processing goes here. Set the output to same as input. (Dummy Processing) 
        exchange.setOut(exchange.getIn());
    }

}

Points to be noted:

  • Processor is a class which implements org.apache.camel.Processor. 
  • Processor implements a method which takes only one argument (Exchange) - which consists of three messages (in, out and exception) and few other properties related to the route and it's camel context.

Define the Bean

     <bean id="processor" class="com.test.camel.processor.SampleProcessor" />

Define the Route

 <camel:camelContext id="camelContext">
      <camel:route id="file-route">
            <camel:from uri="file:/tmp/input.test" />
            <camel:process ref="processor" />
            <camel:to uri="file:/tmp/output.test" />
      </camel:route>
  </camel:camelContext>

Points to be noted:

  • Route is defined inside the Spring Config (using DSL). It also be defined using RouteBuilder. (We will concentrate only on DSL).
  • Define the route inside the Camel Context 
  • A very basic route consists of From (Where to fetch from), Processor (Which processor the input) and To (Where to write the processed input). 
  • Processor is optional - if we don't want to do any processing. 
  • Here in this route (file-route), files will be read from directory /tmp/input.test, and will be written into /tmp/output.test directory after processing.
  • Camel Context and Route(s) will be automatically started once the spring application context is loaded and started. So, once spring configuration file is loaded, camel looks for the files in the input directory. 
  • Camel Context and Route(s) will be shutdown once the application context is closed.

Exception Handling

Apache Camel provides try, catch and finally (optional) blocks to be defined within a route to handle the exceptions while routing or processing. The above route can be re-defined with try-catch blocks to check for Exception 
 <camel:camelContext id="camelContext">
      <camel:route id="file-route">
            <camel:from uri="file:/tmp/input.test" />
            <camel:doTry>
                 <camel:process ref="processor" />
                 <camel:to uri="file:/tmp/output.test" />
                 <camel:doCatch>
                      <camel:exception>java.lang.Exception</camel:exception>
                      <camel:log message="Exception while processing "></camel:log>
                      <camel:to uri="file:/tmp/error.test" />
                 </camel:doCatch>
            </camel:doTry>
      </camel:route>
  </camel:camelContext>
In the above case, if an exception is occurred while routing/processing, the exception will be caught, a log will be written and the file will be moved to another directory /tmp/output.test.

Full Spring Configuration

Complete spring configuration file is as below
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:camel="http://camel.apache.org/schema/spring" 
      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.xsd
           http://camel.apache.org/schema/spring 
           http://camel.apache.org/schema/spring/camel-spring.xsd">

     <bean id="processor" class="com.test.camel.processor.SampleProcessor" />

     <camel:camelContext id="camelContext">
         <camel:route id="file-route">
              <camel:from uri="file:/tmp/input.test" />
              <camel:doTry>
                   <camel:process ref="processor" />
                   <camel:to uri="file:/tmp/output.test" />
                   <camel:doCatch>
                        <camel:exception>java.io.IOException</camel:exception>
                        <camel:log message="Exception while processing "></camel:log>
                        <camel:to uri="file:/tmp/error.test" />
                   </camel:doCatch>
              </camel:doTry>
         </camel:route>
     </camel:camelContext>
</beans>
         
In the next post, we will see more details about routing. Happy Learning!!!!

Sunday, August 30, 2015

Apache Camel and KeyWords

To be very simple, Apache Camel is an open source Java Based API which implements most of the commonly used EIPs. So, the next question is what is an EIP?. Let me briefly explain

Enterprise Integration Patterns

EIPs is a set of design patterns (65 design patterns) on how to integrate different enterprise application running on various technologies and makes them to communicate.  These patterns are explained in a book by Gregor Hohpe and Bobby Woolf. So, EIPs is a book in which, the ways to create communication between applications and integrate them are defined. Check the link for more details.

Apache Camel

Let's come back to Apache Camel. As I mentioned at the beginning, Apache Camel is an implementation of EIPs. So, we can integrate the enterprise applications using Camel. It supports almost all types of protocols (FTP, HTTP, JMS, WebService, etc,), to communicate either by itself or by leveraging it. See below an overview of Camel
Using Camel, we can define a set of route(s) within Camel Context to create the communication. The received messages can be filtered, processed, validated, aggregated, split or routed to different other systems.

Camel Context

Camel Context creates runtime for Apache Camel.

EndPoint

As the name indicates, an endpoint is the final or intermediate source/destination of the communication. The endpoint can be a physical address like FTP server or a logical address like JMS Queue, WebService etc. Apache Camel uses URI (of course, Uniform Resource Identifier) to define endpoints. Ex: queue:SAMPLE for a Queue.

Exchange

Exchange is analogous to Message in JMS Specification. But the Exchange carries three messages i.e. Incoming, Outgoing and an Exception for processing. These three are defined as in, out and fault messages. Each of theses Messages has it's own headers.

Template  

CamelTemplate is a class which reads from/writes to an EndPoint. Earlier versions of the camel has the name as CamelClient, but the convention is changed in later versions to be in sync with the other implementations (like Spring JmsTemplate). Template reads/writes Exchanges to/from EndPoint.

Component

Component is a factory class through which you can create an instance of an EndPoint. JmsComponent is the factory for creating JMS Endpoints using a method called JmsComponent.createEndpoint();

Processor

The points discussed so far are very basic to integrate at-least two applications as it is (exchange the messages as it is with no processing). In order to process the message before sending to destination application, we need processor. The processor is an interface which has only one method called void process(Exchange exchange);

Route

A route is a step by step movement of the message between the two endpoints (including exception handling). There are two ways to define a route in Apache Camel. One is using the XML file (like spring bean file). Second is by using Java DSL (Domain Specific Language).

In the next post, we will see how to use these concepts to create a route and process the message between two endpoints (within the Camel Context).

Happy Learning!!!!!

Sunday, May 24, 2015

Lambda Expression and Functional Interface

Lambda expressions are one of the major features of Java 8 (Project Lambda). With this, Java adopts a feature of Functional Programming Language. This feature already present in other languages which runs on JVM (If you familiar of Scala, you might have noticed it). Anyway, we will see what is Lambda expression; how to use it and what are the advantages to use it.

Why Lambda Expressions

Lambda expression is a block of code written in a more readable and compact way. This piece of code can be executed later stage one or more times. This means, Lambda expression allows to pass a block of code as an argument to function or to a constructor. So far, we have been using Anonymous classes to do that. I will give you couple of most common examples on this and will convert them into Lambda expression.

Example - I

We write a anonymous thread using Runnable interface like this
        Runnable r = new Runnable() {
            public void run()
            {
                System.out.println("Anonymous Runnable Example");
            }
        };
        
        Thread t = new Thread(r);
        t.start();
If we use lambda expression, then the above code can be written as
        Runnable r2 = () -> System.out.println("Lambda Runnable Example"); 
        
        Thread t2 = new Thread(r2);
        t2.start();

Example - II

To sort list of elements (or an array), we use Collections.sort of Arrays.sort using a comparator like this
        String[] names1 = new String[]{"Java", "Scala", "Lisp"};
        Arrays.sort(names1, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2)
            {
                return o1.compareTo(o2);
            }
        });
        
        for(String s : names1)
        {
            System.out.println(s);
        }
If we use lambda expression, the this code can be changed to
        String[] names2 = new String[]{"Java", "Scala", "Lisp"};
        
        Comparator<String> comparator = (s1, s2) -> { return s1.compareTo(s2);};
        Arrays.sort(names2, comparator); 
        
        for(String s : names1)
        {
            System.out.println(s);
        }
Similarly event listeners in Swing can also be written like this. Example ActionListener interface where you implement the action performed by an event.
Pretty easy, isn't it, now we will see more details on the lambda expression

Syntax

Syntax of lambda expression is also simple (as we saw in above examples).
Syntax: (arguments) -> { Code }
  • Lambda expressions takes one or more arguments separated by comma (,) 
  • Type of the arguments are optional
  • Code and Arguments are separated by the symbol (->).
  • Code is just a set of statements like we write in methods
  • The code needs to end with a return statement (if it needs to return a value). 
  • If there is only one statement in the code, then braces {} are optional 
See some more examples of Lambda expressions
Example : () -> System.out.println("Without arguments");
Example : (event) -> System.out.println("One argument without type");
Example : (String s1, String s2) -> {
            System.out.println("two arguments and return type");
            return s1.compareTo(s2);
          };

By looking at the code, examples and usage we can list the advantages of Lambda expressions as
  • It increase the readability of the code 
  • Reduces unnecessary boiler plate code
  • It also adds to the performance of the code using parallel processing. 

Functional Interface 

To incorporate the lambda expression into Java, designers introduced a new feature called Functional Interface. Functional Interface is an interface with only one method. To make it more semantic, we can add an annotation @FunctionalInterface. If we add more than one method, it will break the contract and it will no more be a functional interface, instead we can add default or static methods. Example of Functional Interfaces are
Examples
//Example 1 - Only one method
@FunctionalInterface
public interface FInterface
{
    public void method();
}

//Example 2 - with default method
@FunctionalInterface
public interface FInterface
{
    public void method();
    
    public default String printName()
    {
        return "Functional Interface";
    }
    
}
All the famous java interfaces like Runnable, Callable, Comparator etc.. are now functional interfaces. If you open the JavaDoc or code of these interfaces, you will see that these are annotated with @FunctionalInterface. See the samples below
//Comparator
@FunctionalInterface
public interface Comparator<T> {
...

//Runnable
@FunctionalInterface
public interface Runnable {
As i mentioned earlier in the post, lambdas are the most important and prominent feature of Java 8 which attracts most the developers, hope for you as well.

Thanks for reading and Happy Leaning!!!

Monday, May 18, 2015

Programming using VIM editor

There would be some cases, where we need to change source on the host machines and run them. For those instances, VIM (VI - improved) is very good editor to make use of. As we are most used to modern GUI editors, we may find it difficult to use the terminal. We can make best use of terminal using some tips and tricks. I will try to explain what i generally use.

Syntax Highlighting

We do make mistakes/typos when typing, so better to use syntax highlighting to make sure that we are typing the right command/keyword/phrase etc. Syntax highlighting is simple enough in VIM. Use the following commands to set that. Open VIM (empty or with any java/c file) and type
:syntax on
VIM detects the language automatically, but if you would like to change the language, use syn variable to set the preference (java or xml etc). See some samples below on how to use
:set syn=java
:set syn=xml
If you are using a terminal, syntax highlighting may not work for you, unless you set your term variable to ansi
:set term=ansi
You may need to add this in your .vimrc file (exists in $HOME directory. If not exists, create it) to default it for all the files opened by VIM.

Color-Schemes

Syntax highlighting will be shown with default color schemes. There are few color schemes available by vim by default, you can switch the color shown on the highlighting. use colorscheme keyword.
:colorscheme <color-scheme-name>
You can download the color schemes available on web and place in your vim colors directory. Generally it will be at $HOME/.vim/colors. You can download the color-schemes from from github, and install. Copy the downloaded files into .vim/colors (in $HOME), if not exists - create it, and copy all the colors to colors folder.
If want to default the syntax highlighting and color schemes defaulted when you open VIM, simply put all the commands into .vimrc files in your home directory.
See one sample below
set term=ansi
syntax on

colorscheme eclipse

Compile and Run

To run your program, you can use the compile or execute command prefixed with :! inside VIM editor. See sample below. Open vim and write the code and compile using
:!javac Sample.java
When you run the command, a new screen will be opened with the javac command output (Compilation errors/success of compilation). Once the compilation is successful, run the program using the following command.
:!java Sample
  • Note: Just a point to note, javac and java should be in PATH variable to be recognized. 
But it will be too cumbersome to type the same command multiple times, if any compilation errors, you have two options to make it simple and easy. 

QuickRun plugin

As VIM allows to add plugins, there is a plugin QuickRun which compiles and run a program in one go. Download the plugin at github. Follow the installation instructions (just copy the mentioned files to your vim plugins directory - $HOME/.vim/plugins). Once installed, you can run your program by the command QucikRun. Open your program and execute the command
:QuickRun
This will compile and run the program and output will be shown by splitting the screen. QuickRun supports few programming languages by default and it recognizes based on the file type (See documentation for more details).

MakePrg command

If you wouldn't like to install a plugin, or if the plugin doesn't support the programming language that you are working on, then you can use makeprg command to compile your program.
Edit .vimrc file in your $HOME directory to include the following lines (I am giving an example on how to use javac command in makeprg)
"Compiling Java Code
autocmd Filetype java set makeprg=javac\ %
set errorformat=%A%f:%l:\ %m,%-Z%p^,%-C%.%#
map <F9> :make<Return>:copen<Return>
map <F10> :cprevious<Return>
map <F11> :cnext<Return>
By doing this, you are mapping some of the control characters to default compile command (i.e. make). What we are doing in the above lines are
  • Setting the detault make program to use the command javac
  • Mapping F9 (Function-9) key to compile the java code and return to the current window without any prompt.
  • If any compilation error,
    • use F11 to see the next error message (printed in the given error-format).
    • use F10 to see the previous error message (printed in the given error-format).
How to use
Open the program using vim, write the code and compile using by pressing F9. To navigate through the errors, use F10 and F11.
Using this, you can only compile your code, it doesn't execute (Of course javac doesn't execute your java program). Use :!java command from the vim editor to execute the compiled program (as mentioned in the starting of the post), or instead use the java command on the command line (after exiting from vim editor). 

Hope this post helped you with the commands. Happy Learning!!!

Friday, April 17, 2015

Java Management Extensions - JMX

Java Management Extensions is a way to create management interface to Java applications. In brief, adding extra wrapper (MBean) to your application with a name (ObjectName) and register it on management server MBeanServer, so that it can be accessed/managed externally. JMX allows the developers to integrate the application by assigning management attributes/operations.

Instrumentation

To use JMX, we need to instrument the Java classes (or resources). The instrumented objects are called MBeans. MBeans are nothing but POJOs which adhere to JMX specifications.

MBeanServer

MBeanServer is the very core component of the JMX. MBeanServer is the JMX agent which hosts the MBeans on it and make them available for the remote applications. The MBeanServer need not to know how the MBeans are implemented and vice-versa. 

Accessing MBeans

MBeans running on MBeanServer can be accessed using Connectors, typically called as JMX Connectors, using JMX Service URL. The main intention of the connector is to provide an interface to establish communication between JMX agent and the application which is trying to access the MBean. There are various connectors available, but it always recommended use a standard RMIConnector.  

JMX Service URL

The URL is used to connect to MBean agent and locate MBeans to acess. There are two types of URLs depending on how the JMX is implemented on broker.
  • Static URL: As the name suggests, Static URL will create constant identity for MBeans irrespective of when and how broker is started, stopped etc. This uses RMI Connector.
  • Dynamic URL: Dynamic URL keeps changes for each time when the broker is started/re-started.

URL looks like

service:jmx:rmi://hostname:port/<urlpath>
The explanation goes here
  • service:jmx:rmi is constant
  • hostname:port is the name and port of the broker host where the MBean agent resides (Ideally, where the application is running)
  • urlpath is depends on where Service URL is static or dynamic
    • Static URL looks like : /jndi/rmi://hostname[:rmiPort]/jndiname
    • Dynamic URL looks like : /stub/serialnumber-with-base64encoded

Static JMX Service URL

Static URL contains the details of the RMI registry like hostname, port number and the connector name 
/jndi/rmi://hostname[:rmiPort]/connectorname 
  • hostname[:rmiPort] : RMI host and post number to locale JMX agent. By default, RMI port will be 1099 (if not specified). 
  • connectorname specifies the name which needs to be look-up in the RMI registry.
See the post, how to implement JMX MBean using Spring

Dynamic JMX Service URL

The URL consists of the serialized JMX object with Base 64 encoded value. See an example below
/stub/rO0ABdmVyLlJlpIDJyGvQkwAAAARod97VdgAEAeA==
We will see how to create JMX MBeans using dynamic URLs and how to access.

Happy Learning!!!!

Thursday, April 9, 2015

String and String Constant Pool

String and String Constant Pool

String is the most known Immutable Class in Java. Immutable means, the contents can't be changed once initialized. That's the reason, we keep hearing that to use StringBuffer for string modifications instead of String. When we modify the contents of String (see samples below) will create a new copy of String and assigns the reference. String Constant Pool is a pool of Strings maintained by JVM for storing the strings created and its references. See code below to know what happens when a string constant is created.
      String string1 = "veeresh"; 
      String string2 = "veeresh"; 
      string1.concat(string2);

Points to be noted

  • A constant veeresh will be created and reference will be assigned to string1
  • When trying to create one more constant with the same value, JVM will pick it up from String constant pool and get the reference and assigns to string2. So, string1 and string2 are referring same.
  • If we perform an operation on a string - like concat in the above code, a new string will be created with value veereshveeresh. But there is no assignment, hence we can't acess it in our program but it will present in String constant pool

More about String Constant Pool

No new string will be created only if it's a constant. If we create a string using new keyword, then a new string reference will be created. See below
        String string1 = "veeresh";
        String string2 = new String("veeresh");
        String string3 = "hi";
        String string4 = string3.concat(" "+string2);
In above code
  • On line 1, a new constant veeresh will be created in String Constant Pool and reference is assigned to string1
  • On line 2, a new Object whose value is veeresh will be created - not taken from string constant pool as we used new keyword.
  • On line 3, a new constant hi will be created in String Constant Pool and reference is assigned to string3
  • On line 4, a new constant Space (" ") will be created and then " veeresh" (Space suffixed with veeresh) created and finally "hi veeresh" will be created in String Constant Pool and assigned to string4 as reference. So, total 3 strings will be created here (Space, " veeresh" and "hi veeresh").

Why Only for String

Only String class  has Constant Pool, Other types like Integer, Char, Number etc doesn't have Constant pool even though they are Immutable. The important reason so far i got are Security and Frequency of Usage.
  • String is the most frequent used like System.out.println and arguments that we pass most of the methods and even main method accepts an array of Strings. So, JVM referes to String Constant Pool every time when a new string created in order to reduce the number of references.
  • I am not really sure what security we get but i found on web as this is one of the reasons.
I am in search of other reasons for why only String. 

To Summarize

  • Every time, when a string constant is created, JVM checks String Constant Pool whether exists. If exists, the same reference will be returned otherwise creates it
  • In order to create new string without taking from Constant Pool, use new keyword
  • Any operation on string will result in new object (or constant)
  • If we want to create strings for doing some modifications, use StringBuffer instead of String
Help me with more details if you know anything else. Happy Learning!!!

Wednesday, April 8, 2015

Debugging MQ Java Client Applications

I find it very difficult to debug the Java client application written for MQ. Most of the error messages are self explanatory but some of the error messages are difficult to diagnose and find the cause. Enable tracing would really help to identify the root of the problem. In this post, we will see how to enable tracing on Java applications.

MQ Trace

Simple MQ Trace enabling can be done by adding a JVM parameter like this
java -Dcom.ibm.mq.commonservices=trace.properties ...
Create trace.properties with the following attributes
Diagnostics.MQ=enabled
Diagnostics.Java=explorer,wmqjavaclasses,all
Diagnostics.Java.Trace.Detail=high
Diagnostics.Java.Trace.Destination.File=enabled
Diagnostics.Java.Trace.Destination.Console=disabled
Diagnostics.Java.Trace.Destination.Pathname=/tmp/trace
Diagnostics.Java.FFDC.Destination.Pathname=/tmp/FFDC
Diagnostics.Java.Errors.Destination.Filename=/tmp/errors/AMQJERR.LOG

Points to be noted

  • Add libraries of IBM JRE (From the directory $JRE_HOME/lib) to CLASSPATH
  • Create the directories /tmp/FFDC, /tmp/trace and /tmp/errors
  • Add read permission to trace.properties
  • Keep an eye on the log file size and make sure to disable logging when not required. Otherwise, it will keep filling the disk space. (Logs size will become some gigs in few hours easily)
One you start the Java Client, it will start printing the trace into the mentioned files. If you want to disable the tracing, make the Diagnostics.MQ property value to disabled so that trace will be stopped. 

JSSE Debug

In case of secure connection with MQ, if you want to enable debug for JSSE, then you can use the JVM parameter java.net.debug with different values
-Djavax.net.debug=true
This prints full trace of JSSE, this can be limited to only handshake by changing the value of the parameter to ssl:handshake
-Djavax.net.debug=ssl:handshake
This prints only the trace related to handshake, all other trace will be simply ignored.

Happy Learning!!!!

Saturday, April 4, 2015

Concurrency and Persistency using Chronicle Map

If you want a persistent, less heap and concurrent maps, then Chronicle Hash Map is the best one to use. Chronicle Map also helps in sharing the data between the JVMs. Earlier version of ChronicleMap is SharedHashMap.

Download

Add the following repository to your pom.xml with the following dependency.
<!-- Repository. Add inside repositories -->
<repository>
    <id>Snapshot Repository</id>
    <name>Snapshot Repository</name>
    <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    <snapshots>
        <enabled>true</enabled>
    </snapshots>
</repository>

<!-- Add the following dependency -->
<dependency>
  <groupId>net.openhft</groupId>
  <artifactId>chronicle-map</artifactId>
  <version>2.1.4</version>
</dependency>

Points to be noted

There are few points to be noted about a ChronicleMap.
  • It stores the data onto a file for persistency.
  • In order to implement, the object (which has to be stored) must implement Serializable/Externalizable
  • Two programs can share the same file (Used while creating the map) to share the same data across JVMs.
  • Replication can be done using Chronicle Map using TCP/IP. (not detailed in the current post).
  • No need to depend on JVM Heap Memory as the data is store Off-Heap (on a file).
  • And the last important point is, the performance of the Map is purely dependent on how the Operating System allocates the memory to the file.
If we clearly observe, all these advantages or features are because of storing a data off-heap using a file.

How to create

ChronicleMap is created using ChronicleMapBuilder. See the sample code for creating the map.
        Map<Integer,String> map = ChronicleMapBuilder.of(Integer.class,
                String.class).create();
If you want to persist the data to a file. Use like this
        File f = new File("/tmp/file.map");
        Map<Integer, String> map = ChronicleMapBuilder.of(Integer.class,
                String.class).
                createPersistedTo(f);
Here, we are creating map and persisting to a file /tmp/file.map. As its storing the data onto a file, we can limit the size of the Map by specific number of entries it can store. See below
        Map<Integer,String> map = ChronicleMapBuilder.of(Integer.class,
                String.class).
                entries(2000).
                createPersistedTo(new File("/tmp/file.map"));
There is a difference between Concurrent Map and Chronicle Map in size. It can't be re-sized once we fix the entries size as re-sizing is a costly operation on Map.

ChronicleMap Interface

There are few specials methods which are provided by ChronicleMap. See below

  • V getUsing(K key, V value); getUsing is same as get(key) but getUsing will return the value in value parameter without creating a new object whereas get will create a new object for returning the value with key.
  • V acquireUsing(K key, V value); acquireUsing is again same as getUsing but if there is no value defined with key, it will insert a new entry with key and returns the same value.

ChronicleMap can read and write the data from/to a JSON object. The following methods can be used to do so

  • void getAll(File toFile) throws IOException; To read map from the file which was created by another ChronicleMap using JSON format.
  • void putAll(File fromFile) throws IOException; To dump the entire map into a file using a JSON format.
  • void close(); As the data is stored off-heap, its recommended to close the map to release the heap data and persist the data.

All other methods are same as Map as it implements java.util.Map. Explore more on ChronicleMap

Happy Learning!!!!

Sunday, March 22, 2015

Format XML using Java

I have been looking for various options for format and pretty print XML string, I found few different options to do that with or without external dependencies. Even Java itself provided some APIs to do so. I will try to list down some of the ways to pretty print XML string but I will not explain the code because its simple, easy and more readable.

Java DOM API

No need of any external dependencies to run the below code. 
    public String formatXML(String input)
    {
        try
        {
            final InputSource src = new InputSource(new StringReader(input));
            final Node document = DocumentBuilderFactory.newInstance()
                    .newDocumentBuilder().parse(src).getDocumentElement();

            final DOMImplementationRegistry registry = DOMImplementationRegistry
                    .newInstance();
            final DOMImplementationLS impl = (DOMImplementationLS) registry
                    .getDOMImplementation("LS");
            final LSSerializer writer = impl.createLSSerializer();

            writer.getDomConfig().setParameter("format-pretty-print",
                    Boolean.TRUE);
            writer.getDomConfig().setParameter("xml-declaration", true);

            return writer.writeToString(document);
        } catch (Exception e)
        {
            e.printStackTrace();
            return input;
        }
    }

Java XML Transformer

Same as first code. This code doesn't need any external dependencies. 

    public String formatXML(String input)
    {
        try
        {
            Transformer transformer = TransformerFactory.newInstance()
                    .newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(
                    "{http://xml.apache.org/xslt}indent-amount", "3");

            StreamResult result = new StreamResult(new StringWriter());
            DOMSource source = new DOMSource(parseXml(input));
            transformer.transform(source, result);
            return result.getWriter().toString();
        } catch (Exception e)
        {
            e.printStackTrace();
            return input;
        }
    }

    private Document parseXml(String in)
    {
        try
        {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource(new StringReader(in));
            return db.parse(is);
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

Using Apache xerces impl

The below code needs an external dependency xerces-impl. Add the following dependency in maven.  
<dependency>
     <groupId>xerces</groupId>
     <artifactId>xercesImpl</artifactId>
     <version>2.8.0</version>
</dependency>
    public String formatXML(String input)
    {
        try
        {
            final Document document = parseXml(input);
            OutputFormat format = new OutputFormat(document);
            format.setLineWidth(65);
            format.setIndenting(true);
            format.setIndent(3);
            Writer out = new StringWriter();
            XMLSerializer serializer = new XMLSerializer(out, format);
            serializer.serialize(document);
            return out.toString();
        } catch (Exception e)
        {
            e.printStackTrace();
            return input;
        }
    }

    private Document parseXml(String in)
    {
        try
        {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource(new StringReader(in));
            return db.parse(is);
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

Using dom4j API

The below code needs dom4j dependency. Add the following dependency in maven.
<dependency>
     <groupId>dom4j</groupId>
     <artifactId>dom4j</artifactId>
     <version>1.6.1</version>
</dependency>
    public String formatXML(String input)
    {
        try 
        {
            Document doc = DocumentHelper.parseText(input);  
            StringWriter sw = new StringWriter();  
            OutputFormat format = OutputFormat.createPrettyPrint();  
            format.setIndent(true);
            format.setIndentSize(3); 
            XMLWriter xw = new XMLWriter(sw, format);  
            xw.write(doc);  
            
            return sw.toString();
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return input;
        }
    }
Please comment if you know any other ways to pretty print XML using Java. Happy Learning!!!!

Sunday, March 1, 2015

Logging JDBC activities using Log4JDBC

In general terms, logging is an activity of recording what's happening in run-time of the application. Sometimes, we need logging for JDBC activities. Log4jdbc is the best way to log the jdbc activities by a Java Application.

Logging Options

The options available in log4jdbc are
  • jdbc.sqlonly: Logs all the SQLs executed by Java Code.
  • jdbc.sqltiming: Logs time taken by each SQL to execute.
  • jdbc.audit: Logs all the activities of the JDBC (Except Result sets). 
  • jdbc.resultset: Includes the audit and plus Result set activities.
  • jdbc.connection: Connection details like opening and closing the database connections will be logged.
In addition to above, if we use log4j-jdbc-remix, it adds few more
  • jdbc.resultsettable: Prints the result set in format of a table with column names. 
  • We can configure this as a datasource.
Any of these can be added to log appenders as required.

Maven Dependencies

The following are the maven dependencies to be added to configure log4jdbc (I am using Apache log4j, you can use any others implementation - java.util, logback, jakarta logging etc as required ). 
  <!-- SLF4J API -->
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>1.6.4</version>
  </dependency>
 
  <!-- LOG4J -->
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-log4j12</artifactId>
   <version>1.6.4</version>
  </dependency>

  <!-- LOG4J for JDBC -->
  <dependency>
   <groupId>org.lazyluke</groupId>
   <artifactId>log4jdbc-remix</artifactId>
   <version>0.2.7</version>
  </dependency>

Log4J Configuration

Configure Log4j first and add the log4jdbc loggers to it. Sample log4j.properties file as below.
I am trying to print
  • SQLs
  • SQL Timing
  • Result Set tables
So the log4j.properties file looks like

# Root logger option
log4j.rootLogger=INFO, stdout
 
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

log4j.logger.jdbc.sqlonly=INFO
log4j.logger.jdbc.sqltiming=INFO
log4j.logger.jdbc.audit=OFF
log4j.logger.jdbc.resultset=ERROR
log4j.logger.jdbc.connection=ERROR
log4j.logger.jdbc.resultsettable=ON

Change Driver and JDBC URL

  • Change the driver from <your implementation driver> to net.sf.log4jdbc.DriverSpy 
  • Prefix the JDBC Connection URL with jdbc:log4jdbc instead of jdbc:
Example: I am using MySQL. So, I changed
  • JDBC Driver from com.mysql.jdbc.Driver to net.sf.log4jdbc.DriverSpy 
  • MySQL JDBC Connection string changed from jdbc:mysql://localhost:3306/test to jdbc:log4jdbc:mysql://localhost:3306/test
By default, log4jdbc loads all the drivers. If we want to load only the specified drivers, use the following system properties otherwise all the drivers will be loaded, and the system will pick the required driver based on the implementation.
  • -Dlog4jdbc.drivers=<driverclass>[,<driverclass>...] : To load the specific drivers
  • -Dlog4jdbc.auto.load.popular.drivers=false: To switch off loading all other drivers except mentioned by above

Log4JDBC Log

Sample Log printed with above configuration while accessing the data to/from database as below.

2015-03-01 18:07:04 INFO  Main:19 - Started
2015-03-01 18:07:05 INFO  sqlonly:236 - INSERT INTO Student VALUES(5,'Veeresham',25,'M') 
2015-03-01 18:07:05 INFO  sqltiming:357 - INSERT INTO Student VALUES(5,'Veeresham',25,'M')  {executed in 180 msec}
2015-03-01 18:07:05 INFO  sqlonly:236 - select * from Student 
2015-03-01 18:07:05 INFO  sqltiming:357 - select * from Student  {executed in 1 msec}
2015-03-01 18:07:05 INFO  resultsettable:108 - |---|----------|----|-------|
2015-03-01 18:07:05 INFO  resultsettable:108 - |id |name      |age |gender |
2015-03-01 18:07:05 INFO  resultsettable:108 - |---|----------|----|-------|
2015-03-01 18:07:05 INFO  resultsettable:108 - |1  |John      |20  |M      |
2015-03-01 18:07:05 INFO  resultsettable:108 - |2  |Lary      |28  |F      |
2015-03-01 18:07:05 INFO  resultsettable:108 - |3  |Blob      |22  |M      |
2015-03-01 18:07:05 INFO  resultsettable:108 - |5  |Veeresham |25  |M      |
2015-03-01 18:07:05 INFO  resultsettable:108 - |---|----------|----|-------|
2015-03-01 18:07:05 INFO  Main:28 - Completed

When we set SQLs to true, log will replace the placeholders with the actual arguments set to it.

Try to set and unset the parameters and see different levels of information.


Happy Learning!!!!

Saturday, February 28, 2015

Java Web-Services and Overview

What is Web-service

Web-service is a piece of software which is available on internet and accessible to client using XML (Standard Inter-operable format). 

Types of Web-services

Web-services are categorized into two types based on the type of implementation. They are "BIG" web-services and "REST"ful web-services.

"BIG" Web-services

This is also called as JAX-WS (Java API for XML Web-Services). Forget about the definition, we will see the terms which denote the BIG Web-services.
  • SOAP: An XML language which is used for communication between Client and Server. Abbreviated to Simple Object Access Protocol
  • WSDL: The operations exposed or available on the Web-service are defined using a machine-readable language called WSDL (Web-Service Definition Language). 
Going forward, we will see more about JAX-WS and example (may be in subsequent posts).

RESTful Web-services

RESTful web-services mostly integrated with HTTP for request and response without depending on WSDL and XML messaging. RESTful (Representational State Transfer (RESTful) web service) functionality is available in JAX-RS.
As the funtionality depends on HTTP, it's stateless and more suited for ad-hoc and simple scenarios.

How it works

Think of a scenario, how we access a web-site. There is no major difference between accessing a web-site or a web-service except for few differences. First is, the response by a web-site is a human-readable where-as the response by web-service is intended for another program (mostly machine readable). Web-site content can have text, multimedia or graphical content etc, where-as the web-service returns content in XML, JSON etc formats. 
We will see contract, request and response formats/samples in JAX-WS (JAX-RS is not in the scope of the post). Just to remind
  • WSDL defines set of contracts that means what are the operations are allowed on the web-service. 
  • SOAP is used for carrying request and sending the response back to the client.
Sample WSDL is as below. When we look at the operation tag in bindings we will find the operations supported by the Web-service

<definitions name="MyService"
   targetNamespace="http://www.examples.com/wsdl/GetDetails.wsdl"
   xmlns="http://schemas.xmlsoap.org/wsdl/"
   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 
   <message name="GetDetailsRequest">
      <part name="firstName" type="xsd:string"/>
   </message>
 
   <message name="GetDetailsResponse">
      <part name="greeting" type="xsd:string"/>
   </message>

   <portType name="GetDetails_PortType">
      <operation name="getDetails">
         <input message="tns:GetDetailsRequest"/>
         <output message="tns:GetDetailsResponse"/>
      </operation>
   </portType>

   <binding name="GetDetails_Binding" type="tns:GetDetails_PortType">
      <soap:binding style="rpc"
         transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="getDetails">
         <soap:operation soapAction="getDetails"/>
         <input>
            <soap:body
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:examples:myservice"
               use="encoded"/>
         </input>
  
         <output>
            <soap:body
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:examples:myservice"
               use="encoded"/>
         </output>
      </operation>
   </binding>

   <service name="Hello_Service">
      <documentation>WSDL File for MyService</documentation>
      <port binding="tns:GetDetails_Binding" name="GetDetails_Port">
         <soap:address
            location="http://www.examples.com/GetDetails/" />
      </port>
   </service>
</definitions>

SOAP Envelope is used for request and response. It consists of
  • Header (Optional): Header contains very specific information related to the application (like authentication etc).
  • Body: The actual content containing the details of the Request/Response based on the context.
  • Fault Block (Optional): Fault will be in response message if it contains an error. The details of the error, error number and error description will be inside the block.
Sample SOAP envelope, will be

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/1999/XMLSchema">
   <SOAP-ENV:Header>
     <!-- Header Data -->
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
     <!-- Body Info -->
     <!-- Optionally fault -->
     <SOAP-ENV:Fault>
     <faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode>
     <faultstring xsi:type="xsd:string">Error Message</faultstring>
      </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

In the next post, we will how to create and call the web-service in Java using JAX-WS.

Happy Learning!!!!

Monday, January 26, 2015

Cloning an Object - Deep and Shallow Copy

In Java, Cloning is a way to create an identical object adhering to some properties. clone() is one of the methods provided by the Object class. When we look at the javadoc of the clone method, it is explained as (The definition is short and modified version).

A Clone object should follow the properties even though these are not forced. ( a is an object of any type )
  • a != a.clone() must be true. 
  • a.getClass() should be equal to a.clone().getClass()
  • a.equals(a.clone()) must be true
In addition to the above properties, to make clone method to work, the class of the object must implement Cloneable interface otherwise, a cached exception CloneNotSupportedException will be thrown. (Even thought the Cloneable interface doesn't hold the method clone() but it should be implemented to clone an object).

Shallow and Deep Copying

Java default implementation of clone method clones only primitive members and copies the references of the other class type variables. This is Shallow Coping. Just call super.clone() inside the clone method. 

Example of Shallow Copy

Rectangle.java
public class Rectangle implements Cloneable
{
    private Long length;
    private Long breadth;
    
    public Rectangle(Long l, Long b)
    {
        this.length = l;
        this.breadth = b;
    }
    //getters and setters are ignored.

    @Override
    protected Object clone() throws CloneNotSupportedException
    {
        return super.clone();
    }
    @Override
    public boolean equals(Object obj)
    {
        if(obj instanceof Rectangle)
        {
            Rectangle other = (Rectangle)obj;
            return (other.length == length && other.breadth == breadth);
        }
        return false;
    }
    @Override
    public int hashCode()
    {
        int hashCode = 0;
        if(length != null)
            hashCode += length.hashCode();
        if(breadth != null)
            hashCode += breadth.hashCode();
        return hashCode;
    }
    @Override
    public String toString()
    {
        StringBuffer buffer = new StringBuffer();
        buffer.append("Length : ");
        buffer.append(length);
        buffer.append("; Breadth : ");
        buffer.append(breadth);
        return buffer.toString();
    }
}

Sample Execution
        Rectangle r = new Rectangle(10L, 12L);
        try
        {
            Rectangle s = (Rectangle)r.clone();
            System.out.println("r is : "+r);
            System.out.println("s is : "+s);
            System.out.println("Properties");
            System.out.println("r == s : "+(r == s));
            System.out.println("r.equals(s) : "+(r.equals(s)));
            System.out.println("r.getClass() == s.getClass() : "+(r.getClass() == s.getClass()));
        } catch (CloneNotSupportedException e)
        {
            e.printStackTrace();
        }

Output looks like:
 
r is : Length : 10; Breadth : 12
s is : Length : 10; Breadth : 12
Properties
r == s : false
r.equals(s) : true
r.getClass() == s.getClass() : true

Points to be noted

  • No need to write any implementation as Java by default does the shallow copying. 
  • clone method always return object of type Object
  • clone method throws CloneNotSupportedException
  • call super.clone() when only shallow copying is required Otherwise we need to copy the remaining objects.
  • Rectangle method implemented Cloneable Interface otherwise clone() cannot be called on the object of type Rectangle. 
  • hashCode and equals methods also to be implemented otherwise equals() doesn't return true when object and it's clone are compared.

Deep Copying

If the class contains non-primitive type members, the default implementation copies the references instead of creating a copy. So, the cloned object won't be a real copy. In order to clone the object with non-primitive members, we should explicitly copy the members. 

Example of Deep Copy

Person.java
public class Person implements Cloneable
{
    private String name;
    private Address address;

    //Getters and setters ignored.

    @Override
    protected Object clone() throws CloneNotSupportedException
    {
        Person p = (Person) super.clone();
        p.setAddress((Address)getAddress().clone());
        return p;
    }
    @Override
    public int hashCode()
    {
        int hashCode = 0;
        if(name != null)
            hashCode += name.hashCode();
        if(address != null)
            hashCode += address.hashCode();
        return hashCode;
    }
    @Override
    public boolean equals(Object obj)
    {
        if(obj instanceof Person)
        {
            Person other = (Person)obj;
            return (other.getName().equals(name) && other.getAddress().equals(getAddress()));
        }
        return false;
    }
    
}

Address.java
public class Address implements Cloneable
{
    private String city;
    private String country;
    //Getters and setters are ignored.

    @Override
    protected Object clone() throws CloneNotSupportedException
    {
        return super.clone();
    }
    @Override
    public int hashCode()
    {
        int hashCode = 0;
        if(city != null)
            hashCode += city.hashCode();
        if(country != null)
            hashCode += country.hashCode();
        return hashCode;
    }
    @Override
    public boolean equals(Object obj)
    {
        if(obj instanceof Address)
        {
            Address other = (Address)obj;
            return (other.getCity().equals(city) && other.getCountry().equalsIgnoreCase(country));        
        }
        return false;
    }
}

Points to be noted

  • Person class contains an member of type Address. If clone is not called on address type, then only name of the person will be copied onto the cloned object.
  • Instead of using the clone method on the Address object, we can copy field by field. (little clumsy though, if we wish we can).
  • The three properties still hold on all the objects which are Cloneable (Person and Address both).
  • To make clone to work, either all the sub-classes need to implement Cloneable or write the logic to copy the members.
And finally, the three properties which are followed by above classes need not to be satisfied, or Java doesn't force to implement but it's always good practice to make the class to follow if it has to be cloned. Otherwise write a simple method copy to create a new copied object, instead of using Clone method. 

Happy Learning!!!!