Feeds:
Posts
Comments

Posts Tagged ‘JAVA’

Recently I stumbled upon a particular Spring project  called Spring Loaded .The ReadMe section did catch my attention because it boosts developer productivity by reloading class files as and when they change.

There have been quite a few projects which provide such benefits and I believe the most popular commercial choice is JRebel. Those guys have done a great job in turning  one of the greatest JAVA Web developers pain into a line of business.  However there have been alternatives but none so simple as JRebel

Fortunately Spring Loaded was quite simple to use and configure. Its just a single jar. However, I am quite sure it is not a sophisticated as  other commercial options. But its getting there and is currently being used in Grails 2.

ReLoading in Action

The most reliable  way to show automatic reloading in action is by capturing a video. Unfortunately you guys will just have to trust me.

Start off by downloading the jar and including in your normal java project.

Create a POJO “Person”


public class Person {
	
	
	
	public  void printBody()
	{

		System.out.println("*********");
		this.hands();
//		this.gloves();
		System.out.println("Body");
		this.legs();
//		this.shoes();
		System.out.println("*********");
	}
	
	private  void hands()
	{
		System.out.println("Hands");
	}
	
	private  void gloves()
	{
		System.out.println("Gloves");
	}		
	
	private  void legs()
	{
		System.out.println("Legs");
	}	
	
	private  void shoes()
	{
		System.out.println("Shoes");
	}	

}

Now create a class to run the POJO

public class LiveEcho {

	
	public static void main(String[] args) throws Exception {
		
		while(true)
		{
			Thread.sleep(5000);
			new Person().printBody();

		}
		
	}
}

When you run the LiveEcho class you will see statements in the console like below.

*********
Hands
Body
Legs
*********
*********
Hands
Body
Legs
*********
*********
Hands
Body
Legs
*********

Nothing amazing. While the application is running, try uncommenting out “this.gloves()” or “this.shoes()”. Still nothing amazing.

In order to let Spring Loaded to be aware of the changes, we need to pass “-javaagent:springloaded-1.1.5.RELEASE.jar” as a java argument. I have done it here from my eclipse option

SprngLoadedConfig

SprngLoadedConfig

Run the LiveEcho class again. This time while the class is running, try uncommenting out “this.gloves()” or “this.shoes()”. You will see the output on the console changing

*********
Hands
Body
Legs
*********
*********
Hands
Body
Legs
*********
*********
Hands
Body
Legs
*********
*********
Hands
Gloves
Body
Legs
*********
*********
Hands
Gloves
Body
Legs
*********
*********
Hands
Gloves
Body
Legs
Shoes
*********
*********
Hands
Gloves
Body
Legs
Shoes
*********

As you can see, Spring Loaded has noticed the changes in the Person class files and reloaded the changes without re-starting the JVM.

Further reading

There are different ways of checking whether the classes have re-loaded or what are the changes that have taken place.

Q. How do I know when a reload has occurred so I can clear my state? A. You can write a plugin that is called when reloads occur and you can then take the appropriate action. Create an implementation of ReloadEventProcessorPlugin and then register it via SpringLoadedPreProcessor.registerGlobalPlugin(plugin). (There are other ways to register plugins, which will hopefully get some documentation!)

I have not tried it out on complex web project and their likes, but I am sure they are getting there.

Read Full Post »

 
Recently I was in need to tune some of the java services which I had implemented for for an iPhone project. When integrating services with mobile and hand held devices, it is very important that the services respond in a matter of seconds. In order to tune the services and get the best UI experience, the obvious step is to find the slowest service. However the intriguing question was ….HOW?

Following are some of the alternates most developers do

  • Have a System.out / Log.debug after you enter and before you exit the service, which prints the time
  • Write and aspect using AOP and log the time before and after invocation of the method

 

Serious developers choose the second approach, since monitoring is a cross cutting concern.

Before you fire up you IDE and start writing an Aspect and all those AOP jargon, I would like to introduce you to a class from the Spring Framework core portfolio called “JamonPerformanceMonitorInterceptor”. As the name suggests, it is an AOP interceptor that hooks into the framework called JAMon. JAMon is a java monitoring framework and it sure is sweet.

To know more about JAMon check it out HERE. Make sure you download the jamon-2.7.jar file and put it on your classpath

That’s right, no writing of interceptors and joint points and what not AOP jargon out there.

All you need to to do is instantiate a JamonPerformanceMonitorInterceptor bean and tell it which all Spring beans to intercept

Add this to instantiate the bean

<bean id="jamonPerformanceMonitorInterceptor" class="org.springframework.aop.interceptor.JamonPerformanceMonitorInterceptor" >
   <property name="trackAllInvocations" value="true"></property>
   <property name="useDynamicLogger" value="true"></property>
</bean>

Next create a “BeanNameAutoProxyCreator” and hook in the interceptor.

<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
	<property name="interceptorNames">
		<list>
			<idref bean="jamonPerformanceMonitorInterceptor"/>
		</list>
	</property>
	<property name="beanNames">
		<list>
			<value>aRegularSpringBean</value>
			<value>statisticsDao</value>
			<value>statisticsService</value>
			<value>paymentDao</value>	
			<value>paymentService</value>				
		</list>
	</property>
</bean>

All you need to do now is, tell the BeanNameAutoProxyCreator which all Spring beans to intercept.”paymentDao”,”paymentService” etc are all classic Spring beans. Voila, your services and dao are all being monitored.

Oh…And one last thing.

Make sure you set the log4 logging level to TRACE or else it will NOT work!!

In the follow article , I shall show you have to generate reports from the JAMON framework using a simple servlet.

Read Full Post »

In one of our current integration projects, where we were using Spring, we had a Spring bean which was constantly running every 20 to 30 seconds pooling the database and fetching new status of records. These statuses would be constantly sent to our client as and when new status came up. This Spring bean is a simple Quartz(From opensymphony) bean of the class MethodInvokingJobDetailFactoryBean.

<bean id="jobBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
     <property name="targetObject" ref="queryDatabaseServiceTX" />
     <property name="targetMethod" value="getStatus" />
</bean>

Here the queryDatabaseServiceTX(Spring bean) is the business service with the method getStatus that actually retrieves the status and performs some updates also.

After this we define two more beans in the Spring context

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="simpleTrigger"/>
        </list>
    </property>
</bean>

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail" ref=" jobBean " />
    <property name="startDelay" value="10000" />
    <property name="repeatInterval" value="30000" />
</bean>

Recently we started noticing that multiple threads were instantiated and the business service was called multiple times. This eventually was causing multiple updates to occur. Our design was such that the scheduler should run sequentially, repeating itself every 30 seconds. However sometimes when the database is under too much load the query execution itself takes more than 30 seconds and the next thread is spawned causing dead lock kind of situations.

To overcome this we found a silver bullet. Following was the modification done.


<bean id="jobBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
   <property name="targetObject" ref="queryDatabaseServiceTX" />
   <property name="targetMethod" value="getStatus" />
   <property name="concurrent" value="false" />
</bean>

Setting the attribute concurrent to false ensures that no more threads are spawned until the first one is successfully completed.

Read Full Post »

Have you ever faced strange or unexpected problems with your application after putting it into production? Is the same code works just fine when you test it? Is the problem just too hard to even simulate?Well if the problem does not appear when you test it but its there in production and assuming you have a staging environment i.e. your test environment is the same as your production environment. Then the first question is, is your application thread-safe? When you test it, it is only one user but in production is it more than one user?

The only way to ensure that your application is thread-safe is by running more than one thread at the same time. This is a very simple test but it can clear out very serious issues. Here is how you can test it:

Public class theardTest
{
	Public static void main(String[] args)
	{
		Thread userOne = new Thread()
		{
                      Public void run()
                      {
	                 //call your application here
                      }
                  };

                  Thread userTwo = new Thread()
                  {
                        Public void run()
                        {
                               //call your application here
                        }
                  };

                  userOne.start();
                  userTwo.start();
         }
}

If your application is failing here and there, then it is not a thread-safe application and it can not be accessed by more than one user concurrently. There could be many reasons for that like improper user of static modifier, collection iteration, etc.

If your application should be accessed concurrently, then it should be thread-safe.

Read Full Post »

Barcode Encoding in JAVA

Generating barcodes, be it 1D or 2D, have never been easier. I will be using the Barbecue open source project hosted on sourceforge to generate a 1D barcode. After the barcode is generated I will decode the barcode by uploading it to a website whose service we shall use. However its also very simple to write a barcode decoder which shall be a topic of discussion later.

How to ….

First of all you need to download the Barbecue . Following are the jars added in my classpath

  • barbecue-1.5-beta1.jar
  • jdom.jar

Following is the code to generate a sample barcode

package com.datel.barcode;

import java.io.File;

import net.sourceforge.barbecue.Barcode;
import net.sourceforge.barbecue.BarcodeFactory;
import net.sourceforge.barbecue.BarcodeImageHandler;

public class GenerateBarcode {

	public static void main(String[] args) throws Exception {

		Barcode barcode = BarcodeFactory.createCode128("HelloWorld:0505124456");
        File f = new File("c:\\barcode.png");
        BarcodeImageHandler.savePNG(barcode, f);

	}

}

Now you should find a file named barcode.png in you file system in C: drive. It should look like this

Barcode

Barcode

We shall try to decode this image the easy way by uploading it to a website. Navigate to this website: ZXing This is a website hosted by the ZXing project team who have a java api for decoding barcode images. Upload your image and click Submit Query. You should see this as the output

HelloWorld:0505124456

A few words….

Even the Barbecue encoder is only beta and has been beta since May 2007. Also I really don’t comprehend why in the world these cool guys would make the Barcode class extend from javax.swing.JComponent. This really drives me mad to see such a thing but the BarcodeImageHandler class comes to the rescue. Anyways keep up the good work.

Humble Insight…

After my extensive search on the web I could not find a single open source java barcode encoder worth mentioning. I would be very much happy if any one could mention a good open source barcode encoder. But there were quite a few decoders though. Sadly to mention, if you want to encode data into barcodes on production applications you will have to rely on some commercial products out there. They are very good at what they do and are can very easily be integrated into your application. Many have facilities for resizing/rotating your image and can be very handy at times.

Using Barbecue looks all nice, simple and dandy but when you start getting requirements from your customers saying “Hey I want to put 100 MB of data in a 2D barcode” then things get hard. Although that’s a bit exaggerated, I know cases where my colleagues were asked for all weird kinds of things to be done with barcodes. To them I have only one thing to say… “Technology was made to help mankind and was not made to be abused by mankind”.

There is tremendous potential in this barcode industry and advanced encoding techniques keep coming out.

Read Full Post »

Today we shall look into a nice feature on how to secure our JDBC connections. It’s generally a standard to make JDBC connections in java applications to connect to database. We mostly have web applications running in a web container. These web applications make JDBC connections to the databases to retrieve data for the applications. How many of us have really thought how secure these JDBC calls are. Well they aren’t actually. Like any other insecure network protocol call, so are these JDBC connections. However these JDBC connections can be very easily encrypted. Well this discussion is purely based on Oracle databases and wouldn’t work with other drivers. However, if any one finds out about other databases please let me know.

Before we go any further let us see some of the security threats we face when we use normal JDBC connections

  • Eavesdropping and Data Theft
  • Data Tampering
  • Falsifying User Identities
  • Password-Related Threats

Data flowing over the network is prone to network sniffers, be it insider or outside you company. Any one can pick up these data packets and tamper with them.

Imagine you send a query for transfer of balance for $100 from Account A to Account B. Someone could intercept this request and just play around with the zeroes (This is only hypothetical. I sure shall try this out).

Since a picture is worth a thousand words, let us look at a typical application environment.

Application Infrastructure

Application Infrastructure

I believe now it is clear as to how your JDBC connections can get insecure.

Now we shall look into how to get around these issues. To solve these security challenges we have two special features that can be used

  • Data Encryption
  • Data Integrity

In simple lay man terms, it means that your JDBC calls will be transparently encrypted using standard encryption algorithms, there by making your data transfer secure. Secondly your data will be hashed to form messages digests, there by preventing data tampering. So that’s it. Let us get into action.

In order to encrypt and hash the data, certain configuration has to be done both at the client end and the server end. We shall look into them one at a time.

Client Configuration

This is one the easiest steps. You will only have to tell your JDBC driver to encrypt and digest the message as and when you make JDBC calls. Lets looks at a sample code

package com.datel.secure;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import oracle.net.ano.*;

public class StartAction {

    // The machine on which the database resides
    public final static String hostName    = "127.0.0.1";
    // The TNS listener port
    public final static String port  = "1521";
    // The database name (SID)
    public final static String databaseSID = "home";
    // The database User login
    public final static String userName    = "scott";
    // The database user password
    public final static String password    = "tiger";	 

    Connection connection;  

    public static void main(String[] args) {
		// TODO Auto-generated method stub
		new StartAction().makeDbConnection();
	}

	 public void makeDbConnection(){
		    try{

		      DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());

		      // Form the database connect string using the connection parameters
		      // as specified in ConnectionParams.java
		      String dbConnectString ="@"+StartAction.hostName+":"+
		          							StartAction.port+":"+
		          							StartAction.databaseSID;

		      Properties prop = new Properties();

		      // Set the user name and password property
		      prop.put("user", StartAction.userName);
		      prop.put("password", StartAction.password);

		      int level = AnoServices.REQUIRED;

		      // Set the Client encryption level
		      prop.put("oracle.net.encryption_client", Service.getLevelString(level));

		      // Set the Client encryption selected list
		      prop.put("oracle.net.encryption_types_client", "(RC4_40)");

		      // Set the Client integrity level
		      prop.put("oracle.net.crypto_checksum_client", Service.getLevelString(level));

		      // Set the client integrity selected list
		      prop.put("oracle.net.crypto_checksum_types_client", "( MD5 )");

		      connection = DriverManager.getConnection("jdbc:oracle:thin:"+dbConnectString,prop);

		      if ( connection != null )
		      {

		    	  Statement stmt = connection.createStatement();
		    	  ResultSet rs;
		    	  rs = stmt.executeQuery("SELECT * from EMP"); 

		    	  while (rs.next()) {
		              String lastName = rs.getString("sal");
		              System.out.println(lastName + "\n");
		           }

		      }

		    } catch(SQLException ex){
		    	//Trap SQL errors

		    	ex.printStackTrace();

		    } catch(Exception ex){
		    	ex.printStackTrace();
		    }

		  }

}

  • The first thing that you would have noticed different is the client encryption level. I have set it to REQUIRED by setting the property oracle.net.encryption_client. This value signifies, encryption is required and mandated at the client end without which the connection would fail. It supports four different legal values. They are REJECTED, ACCEPTED, REQUESTED and REQUIRED. Similar configuration is required at the server end which we shall see in the server configuration. That means we can have 16 different combinations between client and server. I prefer to leave both the Client and the Server as REQUIRED, because it enforces the encryption security check and cannot be bypassed.
  • The next property that is set is oracle.net.encryption_types_client.This tells the JDBC driver to follow RC4_40 encryption standard. There are other encryption standards like DES and Triple DES. Possible values are RC4_256; RC4_128; RC4_56; RC4_40; 3DES112; 3DES168
  • The next property set is oracle.net.crypto_checksum_client. This tells the JDBC driver to generate checksums for the data and its values can also be REJECTED; ACCEPTED; REQUESTED; REQUIRED.
  • The last property that is set is oracle.net.crypto_checksum_types_client. This tells the JDBC diver to follow the MD5 hashing algorithm to form checksums.

If you were to run this code you would obviously get an error message which states that encryption is not enabled on the server. So let us step into the server configuration.

Server Configuration

On your database server access the Oracle Net Manager. You could find this at Start->Programs->OracleHome->Configuration and Migration Tools->Oracle Net Manger on your database server. Actually this Oracle utility does nothing special but writes to your SQLNET.ORA .You could directly edit this file or else use this utility. So fire up the application and you would see a screen such as this

Oracle Net Manager

Now click on the Profile properties which will bring up another screen. Choose Oracle Advance Security from the drop down list.

Set the encryption type to Required and Selected methods to RC4_40. If you recall this is the same encryption setting that was enabled on the client. The noticeable difference is the encryption seed. Set some hard difficult string in this field. This is used by oracle to encrypt the data in its algorithms. Next chose the integrity tab which fires up this screen

Here we select the similar configurations as the client. Checksum level is Required and the Selected method is MD5

Now go to File->Save Network Configuration. If you want to see where these properties are save go to you Oracle Home folder. Under Network->Admin there will be a file called SQLNET.ORA which would look something like follows

# sqlnet.ora Network Configuration File: c:\OraHome_1\NETWORK\ADMIN\sqlnet.ora

# Generated by Oracle configuration tools.

SQLNET.AUTHENTICATION_SERVICES= (NTS)

SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER= (MD5)

SQLNET.ENCRYPTION_SERVER = required

NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)

SQLNET.CRYPTO_SEED = somerandomlonghardstring

SQLNET.ENCRYPTION_TYPES_SERVER= (RC4_40)

SQLNET.CRYPTO_CHECKSUM_SERVER = required

There are ways to check if your encryption is working or not. I shall give you a hint thought. You can just check your database trace files. It would log something as follows


[29- -2008 15:49:06:398] nau_adi: exit
[29- -2008 15:49:06:398] na_tns: authentication is not active
[29- -2008 15:49:06:398] na_tns: encryption is active, using RC4_40
[29- -2008 15:49:06:398] na_tns: crypto-checksumming is active, using MD5
[29- -2008 15:49:06:398] na_tns: exit
….

Now fire up your application and enjoy transparent network encryption.

Read Full Post »

One of the days at work, we had some requirements to deploy a java web application in an OC4J container (Oracle Container for Java). We are using MyEclipse as our development tool. We had easily integrated it with Tomcat for all the previous deployments. So, we thought it is going to be a cake walk. Not a big deal. Unfortunately it took us a day to figure out how to do it. Here are the steps to integrate MyEclipse with the OC4J container:

  • Install OC4J
    • Download the oc4j container
    • Unzip it to some directory e.g. c:\oc4j
    • Set the JAVA_HOME environment variable to your java directory
    • Set the ORACLE_HOME environment variable to where you unzipped the oc4j i.e c:\oc4j
    • Start the oc4j container by running the oc4j batch file located in c:\oc4j\bin from the command prompt
      c:\oc4j\bin\oc4j -start
    • It will prompt for the admin password. Set the password. You would need to remember it for later
    • Stop the oc4j either by pressing CRTL+C or just close the window
  • Integrate OC4J with MyEclipse
    • In the menu bar of MyEclipse go to Windows → Preferences → MyEclipse → Application Servers
    • Click on Oracle AS
    • Set Oracle AS to Enable
    • Set Oracle AS Home Directory to c:\oc4j\j2ee\home
    • Provide the Administration Password that you have just configured
    • Click ok
    • Start the Oracle AS to ensure that it has been configured properly
  • Deploy your web application in OC4J

    Assuming that you already have a web project that you need to deploy, you would need to create an Enterprise Application Project. This is because you can only deploy ear files in OC4J container and not war files

    • Create new Project File → New → Project
    • MyEclipse → J2EE Projects → Enterprise Application Project
    • Add your web project as a module to the Enterprise Application Project before deployment you would need to change the server.xml that is located at c:\oc4j\j2ee\home\config.
    • <application-server application-directory="../applications"
      deployment-directory="../application-deployments"
      connector-directory="../connectors"
      application-auto-deploy-directory="../application-autodeploy"
      check-for-updates="true">
      
    • In MyEclipse, click on the Deploy button to bring up deployment dialog.
    • Choose the Enterprise Application’s project from the selection box, Click Add button, choose Oracle AS as the server, choose Packaged Archive and click Deploy.
    • If you want to change the deployment mode to Exploded Mode, shutdown the OC4J.
    • Go to deployment dialog, choose the same project in the list of deployments below the project selection box. Click on Remove. Now repeat deployment with only one exception.
    • Instead of choosing Packaged Deployment, choose Exploded Deployment option.
    • Start OC4J as usual, now it’ll have a fully hot deployable application.

Just to note that the version we are using are MyEclipse 5.1.0 and OC4J 10.1.3.3.

For more information, you can check http://www.myeclipseide.org/

Read Full Post »