Tuesday, February 12, 2013

Use CountDownLatch as a CyclicBarrier

Following is a program to use CountDownLatch as a CyclicBarrier: (However, unlike CyclicBarrier, CountDownLatch cannot be restarted!) Just to understand how/if CountDownLatch can be used instead of CyclicBarrier.

public class CountDownLatchTry {
      private static CountDownLatch latch = new CountDownLatch(2);

      /**
      * @param args
      */
      public static void main(String[] args) {
            // TODO Auto-generated method stub
            Runnable r1 = new Runnable() {
                  public void run() {
                        System.out.println("T1: Before countDown()");
                        latch.countDown();
                        System.out.println("T1: After countDown()... sleeping");
                        try {
                              Thread.sleep(2000);
                        } catch (InterruptedException e1) {
                              // TODO Auto-generated catch block
                              e1.printStackTrace();
                        }
                        try {
                              latch.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T1: After await()");
                  }
            };
           
            Runnable r2 = new Runnable() {
                  public void run() {
                        System.out.println("T2: Before countDown()");
                        latch.countDown();
                        System.out.println("T2: After countDown()... sleeping");
                        try {
                              Thread.sleep(2000);
                        } catch (InterruptedException e1) {
                              // TODO Auto-generated catch block
                              e1.printStackTrace();
                        }
                        try {
                              latch.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T2: After await()");
                  }
            };

            Thread t1 = new Thread(r1, "T1");
            Thread t2 = new Thread(r2, "T2");
           
            t1.start();
            t2.start();
            System.out.println("Done!");
      }
}

Corresponding CyclicBarrier example:

public class CyclicBarrierTry {

      private static CyclicBarrier cb = new CyclicBarrier(2);
      /**
      * @param args
      */
      public static void main(String[] args) {
            // TODO Auto-generated method stub
           
            Runnable r1 = new Runnable() {
                  public void run() {
                        System.out.println("T1: Before await()");
                        try {
                              cb.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        } catch (BrokenBarrierException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T1: After await()");
                  }
            };
           
            Runnable r2 = new Runnable() {
                  public void run() {
                        System.out.println("T2: Before await()");
                        try {
                              cb.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        } catch (BrokenBarrierException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T2: After await()");
                  }
            };

            Thread t1 = new Thread(r1, "T1");
            Thread t2 = new Thread(r2, "T2");
           
            t1.start();
            t2.start();
            System.out.println("Done!");
      }

}

Saturday, February 9, 2013

Potential perf issues with String.substring()

This post is relevant for Oracle’s java implementation of 1.6!

Following is the implementation of substring method in String class:

    public String substring(int beginIndex, int endIndex) {
      if (beginIndex < 0) {
          throw new StringIndexOutOfBoundsException(beginIndex);
      }
      if (endIndex > count) {
          throw new StringIndexOutOfBoundsException(endIndex);
      }
      if (beginIndex > endIndex) {
          throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
      }
      return ((beginIndex == 0) && (endIndex == count)) ? this :
          new String(offset + beginIndex, endIndex - beginIndex, value);
    }

Now, if you take a look at the highlighted part of the code, it says a new String is created with same char sequence (‘value’), but with different offset!
Let’s take a scenario where we have a huge string, say of 100MB and we take a substring containing last 100 chars of that string.

String s100MB = <100MB String>; //memory occupied is 100MB
String substring = s100MB.subString(s100MB.length() – 100); //does not occupy any additional memory for the chars of substring as it uses the same char array as the parent string
s100MB = null; //‘substring’ still occupies 100MB of memory where as what it requires is only 200k (for 100 chars)

Now, in real world this may not be a very serious issue as GC is not as instantaneous but cases where ‘substring’ hangs around in memory for very long time – this can be unnecessary wastage of memory! (Worse…. think of the original string being 1GB instead of 100MB!)

<![if !supportLists]>-          <![endif]>Sarang



Thursday, January 31, 2013

final Collection in java

An interesting aspect about final Collection that many java developers may not be familiar with is that making a collection final means only the reference cannot be changed but you can add, remove or change an object inside collection.

 

Example:

            private final List<String> names = new ArrayList<String>();

            names.add("Name1"); //Allowed

            names.add("Name2"); //Allowed

                       

            names = new ArrayList<String>(); //Error

 

Friday, December 28, 2012

Setup yum repository from a linux iso shared on remote windows machine

1. Mount remote windows share on linux system

In general, a useful stuff – specially when important software-installers are stored on a windows share. It can be useful to mount the windows share on your linux system to use it efficiently.

Following are the steps:
  • Login to Linux as root user
  • > mkdir /mtn/winshare 
  • > mount -t cifs //<windows-machine-IP-addr>/<folder-path/ -o username=<user>,password=<pw> /mnt/winshare (For RHEL > 4)
  • > mount -t smbfs //<windows-machine-IP-addr>/<folder-path/ -o username=<user>,password=<pw> /mnt/winshare (For RHEL < 4)

2. Extract Files from iso image and create yum repository

  • > mkdir -p /mnt/iso/{1,2,3}
  • > mount -o loop /mnt/winshare/disk.iso /mnt/iso/1
  • > rpm -ivh  /mnt/iso/1/Packages/<createrepo-package-name>.rpm
  • > cd /mnt/iso
  • > createrepo .
  • > yum clean all

3. Create yum repository configuration file

  • > vi /etc/yum.repos.d/iso.repo
  • Place following text in iso.repo
           [iso] 
           name=My ISO Repo
           baseurl=file:///mnt/iso
           enabled=1
           gpgcheck=0 

Now you should be able to install any package from iso using yum.

- Sarang Anajwala

Monday, December 24, 2012

Debug class-not-found exception

Print ClassNotFoundException

A simple problem that I have found many people struggling with – how to print class-path. Following is the line that can be used to print classpath.

Arrays.toString((((URLClassLoader) Test.class.getClassLoader().getURLs()));

This code returns an array list of all jars and directories on the classpath of the classloader.

-          Sarang Anajwala

 

Friday, December 14, 2012

End of Public Updates for Java SE 6

A quick update on future of Java 6.

From oracle blog -
“The last publicly available release of Oracle JDK 6 is to be released in February, 2013. This means that after 19 February 2013, all new security updates, patches and fixes for Java SE 6 and Java SE 5 will only be available through My Oracle Support and will thus require a commercial license with Oracle.“


Presents a case for upgrade to Java 7!

- Sarang Anajwala

Tuesday, December 11, 2012

Log4j 2.0 - Some important features


Log4j’s latest 2.0 version has been recently released. Following are few of the important and very useful features of Log4j-2.0:

1.       Supports parameter substitution (same as slf4j)
For example:
   LOGGER.info (“User Id is { } and User Email is { }”, userId, userEmail);

2.       Flow Tracing:
To print the entry and exit of a method.
Example:
  public String getUserEmail(int userId) {
    logger.entry(userId);
    User user = UserDao.getUser(userId)
    String email = user.getEmail();
    return logger.exit(email);
  }
  This method will log following messages:
    19:08:07.061 TRACE com.class.MyClass 10 getUserEmail -  entry parms(1)
    19:08:07.061 TRACE com.class.MyClass 13 getUserEmail -  exit with (User.Email@gmail.com)
 
3.       Markers:
To log some special messages.
For example:
 public class MyApp {
 
   private Logger logger = LogManager.getLogger(MyApp.class.getName());
   private static final Marker QUERY_MARKER = MarkerManager.getMarker("SQL");
               
   public String doQuery(String table) {
     logger.entry(param);
     logger.debug(QUERY_MARKER, "SELECT * FROM {}", table);
     return logger.exit();
   }
} 
 
4.       Messages:
Very useful to standardize the format of an application’s log messages.
Example:
            logger.info("User {} has logged in using id {}", username, userId);        
      The above log message can be standardized by implementing a class ‘LoggedInMessage’ implementing ‘Message’ interface.
            logger.info(new LoggedInMessage(userName, userId)); 
                    (‘getFormattedMessage’ method of ‘Message’ interface is used to log the message string.)
        
Some more important types of messages are ThreadDumpMessage, TimestampMessage, MapMessage and few more.
 
5.       Plug-ins:
Log4j 2 uses a Plugin system that makes it extremely easy to extend the framework by adding new Appenders, Filters, Layouts, Lookups, and Pattern Converters without requiring any changes to Log4j.           


-          Sarang Anajwala      

Friday, November 23, 2012

git - tips

  • git remote –v                    
o   Shows remote branches

  • git remote add <remote branch name> <remote branch url>
o   Add a new remote branch

  • git push <remote branch name> <local branch name>
o   push changes from local branch to remote branch

Ref:

Thursday, November 22, 2012

Maven - include a lib manually in local repo

Use following command to include a lib manually in local maven repository:

 

mvn install:install-file -Dfile=./EWSJavaAPIWithJars_1.2.0.jar -DgroupId=local.disk -DartifactId=EWSJavaAPI -Dversion=1.2 -Dpackaging=jar

Thursday, October 25, 2012

Installing git man pages

Git installation by default does not include all the man pages.
So if you try to look for help on git commands like “git help commit”, you may see and error like this: “No manual entry for git-commit”.
It is strange to see a popular tool like git does not including man pages by default; however, following are the steps to download and install the man pages.

> Download man-pages: 
http://git-core.googlecode.com/files/git-manpages-[GIT_VERSION_NO].tar.gz >  git-manpages-[GIT_VERSION_NO].tar.gz 
> Untar the man-pages: 
tar xvj -C /usr/local/share/man -f git-manpages-[GIT_VERSION_NO].tar.gz
Done – Now you should be able to use all git manpages.

Thursday, August 30, 2012

How to enable jmx-agent to monitor a java process from remote machine:

A quick tip on how to enable jmx-agent to monitor a java process from remote machine:

Add following system property in the java process while starting it: “-Dcom.sun.management.jmxremote.port=<port number>”
 
We can add security features as well to it: 
For example, (run com.example.MyApp with jmx-agent enabled) 
% java -Dcom.sun.management.jmxremote.port=3000
-Dcom.sun.management.jmxremote.password.file=password.properties
-Dcom.sun.management.jmxremote.access.file=access.properties
-Djavax.net.ssl.keyStore=keystore
-Djavax.net.ssl.keyStorePassword=password
com.example.MyApp


Monday, June 25, 2012

Security - Array is stored directly

Sonar Violation: Security - Array is stored directly
Means: Constructors and methods receiving arrays should clone objects and store the copy. This prevents future changes from the user (caller/client) affect the internal functionality.

public void setMyArray(String[] myArray) {
  this.myArray = myArray;
}

Solution:

public void setMyArray(String[] newMyArray) {
  if(newMyArray == null) {
    this.myArray = new String[0];
  } else {
   this.myArray = Arrays.copyOf(newMyArray, newMyArray.length);
  }
}

Friday, May 18, 2012

JBoss - Too many open files

Issue: I faced this issue in JBoss while doing load testing. Under heavy load, jboss http connector crashed and it refused to accept any new connections. On checking logs, I found out that the root cause was “Too many open files” issue.

 

Resolution: “Too many open files” – this issue is a linux issue. OS enforces a limit on each process for maximum number of files that can get attached to a process. Normally the default value is 1024. (Default value can be checked using this command: “ulimit -n“) This value is not sufficient for processes like application containers.

 

All the files associated with given process can be seen with this command: lsof -p <pid>

 

More details about how can this value be changed is available on this wonderful blog post - http://tech-torch.blogspot.com/2009/07/linux-ubuntu-tomcat-too-many-open-files.html

 

One thing missing in this blog is that for ‘root’ user, you have to specifically mention the user name while modifying /etc/security/limits.conf file. Wild cards are not applicable for root user.

For example, following lines should be enter in /etc/security/limits.conf file for root user –

 

root            soft      nofile        4096

root            hard    nofile        8192

 

Tek-Olweiz,

Sarang

 

Friday, May 4, 2012

JBoss TimerService - bug fix

As such the TimerService implementation is not stable in jboss6.1.
The version of timer-service library (of JBoss6.1.0.Final) itself says it is only an ALPHA lib… not a GA (jboss-ejb3-timerservice-mk2.jar, version 1.0.0-alpha-13)

I was facing an issue with the TimerService and while looking for a solution, found out JBoss team doesn’t support issues of JBoss-6x any longer.
The issue was related to Transaction management in Timer Service implementation.

Following is the JIRA defect and attached is the library with fix of the issue.
You can get the source code also at my GitHub page mentioned below.

Fixed lib jar file – https://www.box.com/s/5c6d4a99cfd7e07df091/1/275092885/2167714863/1

Regards,
Sarang