Friday, December 31, 2010

log4j.xml - A sample configuration

I could not post anything last month though all the time I was dying to post something. The reason behind this was I change in my profession profile. Actually, I changed my employer. All of the last month I was busy in official work and to settle down in my new office.
The last week of the year is normally a holiday in the new company. So, I could rest a while in my home and able to write the blog post.

Though I had a couple of other topics in mind but writing them will take more time which I don't want to spend during the festivities. So, I'll discuss about a simple but useful thing.
How many of us in Java sphere use log4j for logging? You know the answer. log4j is a very popular logging framework. Configuring log4j is quite simple. Still when you get the task of doing it, you try to find an example (I do the same). That is why I'll show a simple log4j configuration to print to a file.

 
 
 

 
  


 
  
  


  
  


    
    


There are 2 ways to configure log4j, log4j.properties and log4j.xml. I prefer the xml format.
In this example I have configured the log4j to generate logs in apache tomcat's log directory (the application is a web app). Also I have channeled hibernate logs to the same log file.
Another important feature which is used very often is rollingFileAppender. It can roll your log files when they reach their limits.
To use this example you need a log4j.jar (I used 1.2.16). Hibernate (3.6.0) uses self4j logging APIs. So, you'll need self4j-log4j.jar. It can be downloaded from self4j site. I have defined a CONSOLE appender to display log messages in system console. You can add it to root logger to enable the console logging. That's all for this sample log4j.xml.

I hope the New Year 2011 brings best for everyone.

Friday, October 29, 2010

Strings in Switch statements - a new JDK 7 feature

JDK 7 is the next release of Java language. There are lot of expectations from this release. For the first time Java is being modeled outside Sun Microsystems. Now JDK 7 has got a net host, openJdk community.

There are quite a few features planned in JDK 7. Some of them may prove to be a milestone for Java language. But my personal liking is a very small feature rather project called Project Coin. Coin serves to add small language features to Java which will make programmer's life easy. The JavaOne 2010 presentation for Project Coin lists the following features as accepted ones in JDK 7 time frame.


  • Binary literals and underscores in literals
  • Strings in switch
  • Varargs warnings
  • Diamond
  • Multi-catch and more precise rethrow
  • try-with-resources (formerly known as Automatic Resource Management, ARM)

Out of these features, the most attractive to me was "Strings in switch". This is something I've longed for from my college days. I mean, though it was not Java (it was C) still I dreamed of writing switch statements with strings. Finding a unique hashcode for each string to be switched was tedious. In Java 5, usage of Enum constants in a switch statement was allowed. Still it did not fit.
Why do you use a switch block? Simple, when we have many alternative possibilities. See the below code -


int monthNameToDays(String s, int year) 
{
   if(s.equals("April") || s.equals("June") ||
      s.equals("September") || s.equals("November"))
      return 30;
   if(s.equals("January") || s.equals("March") ||
      s.equals("May") || s.equals("July") ||
      s.equals("August") || s.equals("December"))
      return 31;
   if(s.equals("February"))
      return 28;
   else
      // do nothing
}

This method returns no. of days when you pass the name of the month. But till now Java programmers used to  write the method in this way. Some really cool dudes will try to construct an enum and use it in a switch block. But still we need a string comparison in order to set the value to the switch variable. Not too cool.

Won't it be great if we can do the same code using switch construct. JDK 7 is coming with exactly the same promise. It will allow developers to use strings in switch. Check it out-


int monthNameToDays(String s, int year) 
{
   switch(s) 
   {
      case "April":
      case "June":
      case "September":
      case "November":
           return 30;
      case "January":
      case "March":
      case "May":
      case "July":
      case "August":
      case "December":
           return 31;
      case "February":
      default
   }
}


This feature requies change in JLS as well as in Java compiler and JRE. The implementation still uses string.hashCode() to find out the integer which can be used in native switch blocks. But now this will be done by java compiler. This will reduce the effort of Java developer and make the code more readable. The detailed strings in switch proposal can be found here.

Wednesday, September 29, 2010

An unwise attack on the Singletons

Few days back I was disturbed with some maven build issues in office. I got back home pretty late. Already, as you can understand, mood was off. I thought of relaxing by watching a good movie but next day I had an interview scheduled. So, I had to brush up my skills a bit (I don't use them often in office :-) ). The first topic I started with was Singleton pattern. This one is so famous among interviewers that you better be able to explain it.
I had read the pattern many a times already. Nothing to prove the book wrong, never occurred to me. But that day, may be due the horrible mood, I challenged the pattern. I thought I'll find ways to break the pattern down. I wanted to create 2 Singleton instances in same JVM. Thats how the attack began.

Below is the code for creating a Singleton class

package com.test;

import java.io.Serializable;

public class Singleton implements Serializable
{
   private static final long serialVersionUID = 1L;
   private static Singleton s = null;
   
   // to block instantiation by others
   private Singleton()
   {

   }
   
   public static synchronized Singleton getInstance()
   {
      if(s == null)
      {
         s = new Singleton();
      }
      return s;
   }
}

Here is the code to test the pattern

package com.test;

public class SingletonTest
{
   public static void main(String[] args)
   {
      Singleton s1 = Singleton.getInstance();
      Singleton s2 = Singleton.getInstance();
      try
      {
         // To wait for VisualVM to analyze
         Thread.sleep(60000);
      }
      catch (InterruptedException e)
      {
         e.printStackTrace();
      }
   }
}

I have used VisualVM (comes as part of JDK 6) tool to check the no. of instances for Singleton class. You just need to pass a VM argument (-Dcom.sun.management.jmxremote) while running the program.
So, far so good. Only one instance.


This was rather bookish experiment. I knew it would happen. But still tried to make sure my setup is ok. Though the actual action happens next.

Then I tried serialization of the singleton object. I saved the serialized object to a file. Next, I de-serialized the object from file. Hurray!!! 2 Singleton objects are loaded in JVM. The test class code is-


package com.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SingletonTest
{
   public static void main(String[] args)
   {
      Singleton s1 = Singleton.getInstance();
      Singleton s2 = null;
      try
      {
         ObjectOutputStream oos = new ObjectOutputStream(
             new FileOutputStream("D:\\singleton.ser"));
         oos.writeObject(s1);
         oos.close();
         ObjectInputStream ois = new ObjectInputStream(
             new FileInputStream("D:\\singleton.ser"));
         s2 = (Singleton)ois.readObject();
         // To wait for VisualVM to analyze
         Thread.sleep(60000);
      }
      catch (InterruptedException e)
      {
         e.printStackTrace();
      }
      catch (FileNotFoundException e)
      {
         e.printStackTrace();
      }
      catch (IOException e)
      {
         e.printStackTrace();
      }
      catch (ClassNotFoundException e)
      {
         e.printStackTrace();
      }
   }
}


Here is the VisualVM output-



So, the pattern has been broken. It is not anymore a Singleton. But the question here is, how to prevent this attack. The code goes here -



package com.test;

import java.io.Serializable;

public class Singleton implements Serializable
{
   private static final long serialVersionUID = 1L;
   private static Singleton s = null;
   
   // to block instantiation by others
   private Singleton()
   {

   }
   
   public static synchronized Singleton getInstance()
   {
      if(s == null)
      {
         s = new Singleton();
      }
      return s;
   }
   
   protected Object readResolve() 
   {
      return s;
   }
}

I have added a readReasolve() method in the modified Singleton class above. This gets called during de-serialization and the singleton static reference is returned.


Finally, I tried Java reflection (very elegant way indeed). It is so powerful that you can even call private constructors. See how-


package com.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;



public class SingletonTest
{
   public static void main(String[] args)
   {
      Singleton s1 = Singleton.getInstance();
      Singleton s2 = null;
      try
      {  
         Constructor<Singleton>[] con =
                  (Constructor<Singleton>[]) Singleton.class
                           .getDeclaredConstructors();
         for(Constructor<Singleton> c : con)
         {
            c.setAccessible(true);
            s2 = c.newInstance(null);
         }
         // To wait for VisualVM to analyze
         Thread.sleep(60000);
      }
      catch (InterruptedException e)
      {
         e.printStackTrace();
      }
      catch (InstantiationException e)
      {
         e.printStackTrace();
      }
      catch (IllegalAccessException e)
      {
         e.printStackTrace();
      }
      catch (IllegalArgumentException e)
      {
         e.printStackTrace();
      }
      catch (InvocationTargetException e)
      {
         e.printStackTrace();
      }
   }
}

Yahooo!!! again success. This time also I was able to create 2 instances of the singleton class. Though by this time I was more oriented to find a solution to this one. Let's see that-

package com.test;

import java.io.Serializable;

public class Singleton implements Serializable
{
   private static final long serialVersionUID = 1L;
   private static Singleton s = null;
   
   // to block instantiation by others
   private Singleton() throws InstantiationException
   {
      if(s != null)
      {
         throw new InstantiationException();
      }
   }
   
   public static synchronized Singleton getInstance()
            throws InstantiationException
   {
      if(s == null)
      {
         s = new Singleton();
      }
      return s;
   }
   
   protected Object readResolve() 
   {
      return s;
   }
}

In this solution, I have made the private constructor throw InstantiationException when the static reference is not null (yes, constructors can throw exceptions). Thus it will throw an exception if we call the private constructor 2nd time even if in a reflective way.
Is the last solution thread safe? Frankly speaking, I don't know. This part is yet to be explored. There may be some gotchas here. But I am not feeling wise enough to try it now. May be sometime later.

Sunday, August 29, 2010

Generate POM files for a 3rd party artifact in Maven

Maven is a popular software project management tool. It is used heavily for building you project deliverables. More information about maven can be found here.

Maven works on the dependency concept. It essentially means that every project should identify its required artifacts. These artifacts can be found in repositories. Repository is a central place where you keep all your required jars (or other resources). There is a specific structure required to put your artifacts into the repository. We can not just copy every thing at same place. To identify a resource through dependency mentioned in pom.xml, maven looks for the specific structure. Also ther should be a .POM file at the same location of the artifact.

Normally the artifacts generated by maven build comes with the POM for it. So that, any other project wanting to use this artifact can do that. But if the artifact is created from a build other than maven (e.g. ant, Makefile etc), it will not have the POM generated. So this artifact can not be readily used by maven. We need to use the below command to generate a POM for a 3rd party artifact which does not come with a POM by default.



mvn install:install-file -DgroupId=group-id \
                         -DartifactId=artifact-id \
                         -Dversion=version \
                         -Dpackaging=packaging \
                         -Dfile=fileToInstall \
                         -DgeneratePom=true




Here groupId is a string that identifies the product group. artifactId is the string to identify the artifact from its group. version is the artifact version. packaging is the file type of the artifact (e.g. jar). file attribute holds the complete path to the artifact in your local system. generatePom attribute creates the POM for this artifact.

This command will create the required directory structure for your 3rd party artifact and generate a POM for it. The output will be copied to your local repository. Now you can use this dependency in your POM to build your project.

Saturday, July 31, 2010

Using Multi threading with Drools

Drools is a very popular rule engine. It is based on Rete algorithm. To understand what is a rule engine and how to use it check here. But here I will assume that you have some working knowledge on Drools.

What I am going to discuss in this post is 'how to use multi-threading with Drools'. Below is a snippet which creates a KnowledgeBase from a DRL file.



public void buildKnowledgeBase()
{
    KnowledgeBuilder kbuilder = 
             KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add( ResourceFactory.newUrlResource( "file://myrules.drl" ),
    assertFalse( kbuilder.hasErrors() );
    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
}

If this method is called from multiple threads I get below exception -



Exception in thread "Thread-60" [Error: incomplete statement: (possible
use of reserved keyword as identifier: )]

[Near : {... globals != empt ....}]

^

[Line: 0, Column: 0]

at org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(*
MVELInterpretedRuntime.java:153*)

at org.mvel2.MVELInterpretedRuntime.parse(*
MVELInterpretedRuntime.java:44*)

at org.mvel2.MVEL.eval(*MVEL.java:514*)

at org.mvel2.templates.res.IfNode.eval(*IfNode.java:61*)

at org.mvel2.templates.res.TextNode.eval(*TextNode.java:46*)

at org.mvel2.templates.res.TerminalNode.eval(*TerminalNode.java:39*)

at org.mvel2.templates.res.ForEachNode.eval(*ForEachNode.java:116*)

at org.mvel2.templates.res.TextNode.eval(*TextNode.java:46*)

at org.mvel2.templates.res.TerminalNode.eval(*TerminalNode.java:39*)

at org.mvel2.templates.res.IfNode.eval(*IfNode.java:64*)

at org.mvel2.templates.res.TextNode.eval(*TextNode.java:46*)

at org.mvel2.templates.res.ExpressionNode.eval(*
ExpressionNode.java:53*)

at org.mvel2.templates.res.TextNode.eval(*TextNode.java:46*)

at org.mvel2.templates.TemplateRuntime.execute(*
TemplateRuntime.java:195*)

at org.mvel2.templates.TemplateRuntime.execute(*
TemplateRuntime.java:190*)

at org.mvel2.templates.TemplateRuntime.execute(*
TemplateRuntime.java:180*)

at org.mvel2.templates.TemplateRuntime.execute(*
TemplateRuntime.java:169*)

at
org.drools.rule.builder.dialect.java.AbstractJavaRuleBuilder.generatTemplates(
*AbstractJavaRuleBuilder.java:126*)

at org.drools.rule.builder.dialect.java.JavaConsequenceBuilder.build(
*JavaConsequenceBuilder.java:128*)

at org.drools.rule.builder.RuleBuilder.build(*RuleBuilder.java:86*)

at org.drools.compiler.PackageBuilder.addRule(*
PackageBuilder.java:1159*)

at org.drools.compiler.PackageBuilder.addPackage(*
PackageBuilder.java:649*)

at org.drools.compiler.PackageBuilder.addPackageFromDrl(*
PackageBuilder.java:290*)

at org.drools.compiler.PackageBuilder.addKnowledgeResource(*
PackageBuilder.java:488*)

at org.drools.builder.impl.KnowledgeBuilderImpl.add(*
KnowledgeBuilderImpl.java:25*)

at com.myfirm.RuleFlowProcess.init(*RuleFlowProcess.java:25*)

at com.myfirm.RuleFlowProcess.clone(*RuleFlowProcess.java:53*)

at com.myfirm.ThreadTest$CloneThread.run(*ThreadTest.java:35*)

Caused by: *java.lang.NullPointerException*

at org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(*
MVELInterpretedRuntime.java:113*)

... 27 more



The exception normally occurs at KnowledgeBuilder.add(...) method. This can happen infrequently depending on the thread behavior. But there is always a chance to find this error in your production environment.
Now the question is, how do we resolve this? One way, is to share the same knowledge base for all threads. But due to synchronized APIs you will not achieve the performance. Threads will run sequentially. There is another simple solution -




public void buildKnowledgeBase()
{
    //MyClass is holding this method
    synchronized(MyClass.class)
    {
       KnowledgeBuilder kbuilder = 
                KnowledgeBuilderFactory.newKnowledgeBuilder();
       kbuilder.add( ResourceFactory.newUrlResource( "file://myrules.drl" ),
                ResourceType.DRL);
       assertFalse( kbuilder.hasErrors() );
       KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
}

I have used synchronization on current Class object (don't confuse with the new instance of class). There is a single lock available for a Class. So, we can make threads sequential by synchronizing on the class level lock. This will not hit the performance much. Once the KnowledgeBase is created you can run parallel threads for rule execution. No further synchronization required.

Saturday, June 19, 2010

How to add new nonCacheable resource by inheriting Tomcat's DefaultServlet

Do you have a web resource in your application which is dynamically generated/modified? And do you use JavaScript/Ajax (i.e. you do not have the resource mapped to a servlet in your application web.xml) to read that resource? If both answers are yes, then you may have seen that the request for the resource does not return the updated file always. The reason is DefaultServlet class of Tomcat which implements a caching technique for resources. If there is a HTTP request to access the resource before 5 sec of the last modification time, DefaultServlet will send the file from its cache (older content).


DefaultServlet is a servet provided by Tomcat distribution (and JBoss too). As the name suggests, it is the default choice. If your web application does not map a web resource to some servlet, DefaultServlet serves that resource. Only exception is JSP pages. Check out DefaultServlet Javadoc and source code. The servlet mapping is defined in Tomcat web.xml which is normally present at $CATALINA_HOME/conf/web.xml. In JBoss 5.1.0 GA, we find this at $JBoss_HOME/server/default/deployers/jbossweb.deployer/web.xml. I have shown the part of web.xml below-

<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>
          org.apache.catalina.servlets.DefaultServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

...
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

The solution is simple. You need to extend the DefaultServlet and ProxyDirContext class of Tomcat and override the nonCacheable array. Below is the example code.


/** 
 * AppServlet extends DefaultServlet of Tomcat
 */
package com.myapp;

import java.io.File; 

import javax.naming.NamingException; 
import javax.servlet.ServletException; 

import org.apache.catalina.servlets.DefaultServlet; 
import org.apache.naming.resources.FileDirContext;

public class AppServlet extends DefaultServlet 
{ 
   private static final String APP_WEB_ROOT = "/"; 

   public AppServlet() 
   { 
      super(); 
   } 

   /** 
    * {@inheritDoc} 
    */ 
   @Override 
   public void init() throws ServletException 
   { 
      super.init(); 

      final FileDirContext appWebDirContext = new FileDirContext(); 
      
      final String realPath = getServletContext().getRealPath( APP_WEB_ROOT ); 
      final File realPathFile = new File( realPath ); 
      appWebDirContext.setDocBase( realPathFile.getAbsolutePath() ); // Get the absolute path of the application's real path.

      try 
      { 
         this.resources = new MyProxyDirContext( this.resources 
               .getEnvironment(), appWebDirContext ); 
      } 
      catch (NamingException e) 
      { 
         throw new IllegalStateException(); 
      } 
   } 

}


Override the ProxyDirContext class.



/**
 * MyProxyDirContext extends ProxyDirContext of Tomcat
 * Here override the nonCacheable array
 */
package com.myapp;

import java.util.Hashtable; 
import org.apache.log4j.Logger;
import javax.naming.directory.DirContext; 
import org.apache.naming.resources.CacheEntry; 
import org.apache.naming.resources.ProxyDirContext; 

public class MyProxyDirContext extends ProxyDirContext 
{ 
   private static final String[] NON_CACHEABLE_FOLDERS = 
   { "/WEB-INF/lib/", "/WEB-INF/classes/", "/xml/" }; 

   public MyProxyDirContext( final Hashtable env, 
         final DirContext dirContext ) 
   { 
      super( env, dirContext ); 
      nonCacheable = NON_CACHEABLE_FOLDERS; 
   }
}

Now my web application structure looks like this-


Notice the xml directory which contains app.xml (assume this as dynamic resource). My JSP will load the app.xml using JavaScript (add the function as onload item). As the /xml/ URL pattern is added as nonCacheable, Tomcat will read the resource from file system (not from cache). So, we will always get the updated file content. Here is the script code -



function loadXml()
{
   var file = location.protocol + "//" + location.host + location.port +  "/xml/app.xml";
   var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
   xmldoc.async = false;
   xmldoc.load(file);
   // print some data from the xml file
   alert(xmldoc.getElementsByTagName("MY")[0].firstChild.nodeValue);
}


Finally the web.xml for this app -




<servlet>
        <servlet-name>AppServlet</servlet-name>
        <servlet-class>
          com.myapp.AppServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>AppServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>



This approach suffers a performance hit. Do not use this technique for static files.

Saturday, May 22, 2010

'Copy attachment from another email' feature in web based email clients

This is purely an experience driven idea. Looks a bit crazy right now. But should be possible to implement this one. Let me brief about the feature I am looking for in web based email clients. To mention a few web based email clients- Gmail, Yahoomail, Hotmail etc which you use from your browser.
Lot of times we send some documents via email. These are called attachments. If you are using a web based email client you have to upload the document to the mail server to attach them in email. The uploading definitely takes time in a slow connection or for a big size attachment. The act gets annoying for me if the same attachment has to be sent in 3 or 4 different emails. Just think of a situation, where I have 3 mails from 3 different contacts requesting for my CV. The easiest way is to reply all of them in a single mail attaching the CV. But what if I don't want to disclose to any contact that I am sending my CV to others as well. I am sure you have been in such a situation many a times. What do you do then? You have to reply to each of them and while doing that you will end up by uploading the same document 3 times.


I genuinely feel something can be done here.  Once the attachment is uploaded to the server for the 1st time, it is stored there. You can check your sent items or drafts folder. The mail containing the attachment will be there. So, only thing the mail server has to do is, show a 'copy attachment from another email' option in new or reply mails. This will be a small but useful feature for web based email clients.

Thursday, May 13, 2010

Starting up

This is the first blog I'm creating and this is the first post. Feeling a bit nervy. Though its a great experience to write a blog. Initially I felt its not my stuff. But I follow other blogs and really like the whole idea of blogging.  Still somehow it took a long time for me to start on this space.  As they say, it is never late to start something new, I have started blogging.


This blog will be about tech topics that I occurs to me. I'll share my new ideas and hacks. Sometimes I may try to explain some common technology concepts in my own way. I do hope that it becomes useful for somebody.