Friday, July 5, 2013

Tips to configure Git in Windows

We were facing the problem with 'EGit- Synchronize workspace' which showed all the files as changed, even if we haven't changed the content of those files. This happened only when we clone/ pull the repository using Git bash (Unix bash prompt). As we all know the reason for this problem - Windows uses both a carriage-return character and a linefeed character for newlines in its files, whereas Linux/ Mac use only the linefeed character.
Git Hub provides some configurations to override these cross-platform issues.
Do the following before cloning the remote repository, I have the folder structure as C:\Git\Project\, where I would clone the repository inside this folder.
  1. Open Git bash at C:\Git\Project\
  2. Enter, git config --system core.autocrlf true and click enter
  3. Enter, git config --system core.whitespace cr-at-eol and click enter
  4. Then clone the repository as usual, git clone 'https://github.com/xxxxx/xxxx.git' 
  5. Then open the local repository in your Eclipse and import projects. 
  6. Right click on your projects > Team > Share to Git
  7. Right click on your projects > Team > Synchronize workspace
  8. In your Team Synchronize perspective, check the list of modified files. No files will be shown.

To know more about the commands that we used in step 2 and 3, refer http://git-scm.com/book/en/Customizing-Git-Git-Configuration

Thursday, July 4, 2013

Memory leak and performance analysis

Tools:

JVM Profiler - We have a plugin for it which could be installed in Eclipse.
MAT - Memory Analyzer Tool for analyzing the heap dump.



JVM monitor plugin for Eclipse


http://www.jvmmonitor.org/doc/index.html

http://help.eclipse.org/helios/index.jsp?topic=%2Forg.eclipse.tptp.platform.doc.user%2Fconcepts%2Fceproftl.xhtml

Note:
CW-Tomcat is running with java 32 bit and Eclipse also should be 32 bit.


Steps:
  1. Installed Eclipse helios 32 bit for windows
  2. Installed Liferay Plugin, EGit plugins for Eclipse
    1. Through Install New Software -  http://releases.liferay.com/tools/ide/eclipse/helios/stable/
    2. Through Install New Software -  http://download.eclipse.org/egit/updates-2.1
  3. Installed JVM Monitor plugin for Eclipse
    1. Through Eclipse Marketplace - Search JVM monitor and Click Install
    2. Through Preferences > Java > Monitor > Tools, Set JDK Root directory as C:\....\Softwares\jdk1.6.0_21
  4. Launch eclipse helios 32 bit from command prompt making Eclipse to use the same jdk that is set for JVM monitor, C:\...\Softwares\eclipse-jee-helios-SR2-win32\eclipse>eclipse -vm "C:\Mahesh\Softwares\jdk1.6.0_21\bin\javaw"

Monitoring JVM on remote host

To monitor JVM on remote host:

  1. Add the following configurations to JAVA_OPTS in ..../WAR/tomcat_folder/bin/setenv.sh
        -Dcom.sun.management.jmxremote.port=9876
        -Dcom.sun.management.jmxremote.ssl=false
        -Dcom.sun.management.jmxremote.authenticate=false
  2. Press the button Add JVM Connection on Remote Host on JVM Explorer to open New JVM Connection dialog. 
    1. Enter the ip address of the remote server
    2. Enter the port: 9876
Note: Sometimes we may not be able to connect to remote server even after setting the above three JVM arguments. In that case, add the below argument as well.        
              -Djava.rmi.server.hostname= mention the host-name here


How to capture heap dump of JVM running in Remote host

Since 'JVM monitor' does not support viewing the Memory details when monitoring remote host, we may need to capture the heap dump for analyzing the heap memory usage. Below are the steps to capture the heap dump (Ref: http://www.jvmmonitor.org/doc/, under section "How can I enable the BCI mode of CPU profiler on remote host?")
  1. In the Eclipse JVM monitoring view, select the server to monitor. In the Properties screen, you will find Timeline, Threads, Memory, CPU, MBeans and Overview. Select 'Memory' tab.
  2. Click on the 'heap dump' symbol in the top-right corner to capture the heap dump.
  3. A dialog box will be shown with the path where the dump file should be saved in the remote server (eg. /home/liferay\32323432323.hprof). And it may not allow you to select the 'Transfer ....' checkbox or to click on OK button to initiate the dump. An info could be displayed saying that ' agent is not loaded'.
  4. Now follow the instructions given in  http://www.jvmmonitor.org/doc/, under section "How can I enable the BCI mode of CPU profiler on remote host?"
  5. Copy the jvmmonitor-agent.jar from ~..\eclipse-jee-helios-SR2-win32\plugins\
    org.jvmmonitor.core_3.8.1.201302030008\lib\jvmmonitor-agent.jar
    and drop it
    into '/home/liferay' directory of Staging server (remote server) using WinSCP tool.
  6. Add the following configurations to JAVA_OPTS in  .../WAR/tomcat_folder/bin/setenv.sh
                     -javaagent:/home/liferay/jvmmonitor-agent.jar     

     7. Done. Now we are ready to dump the file. The heap dump .hprof file will be saved at '/home/liferay/'

How to use JVM Profiler:




Suggestions from different sites:

It is definitely advisable to have on the -XX:+HeapDumpOnOutOfMemoryError setting.   What is dumped is a binary .hprof file.   The setting for the file location shuold be:
-XX:HeapDumpPath=/niku/logs/heapdump.hprof


Setup for this in setenv.sh
-XX:HeapDumpOnOutOfMemoryError –XX:HeapDumpPath=d:\heapDumps




 How to open or analyze the heap dump .hprof files?

Some of the tools suggested in net are,
  1. MAT - Eclipse Memory Analyzer Tool - (Free) - http://www.eclipse.org/mat/downloads.php
  2. Visual VM - https://visualvm.dev.java.net/
  3. HAT -  Java Heap Analysis Tool - http://docs.oracle.com/javase/6/docs/technotes/tools/share/jhat.html
  4. YourKit Java Profiler
 I used MAT to analyze the heap dump (.hprof file).


MAT for Windows 32 bit was unable to open large dump files. (I tried with a .hprof file of  ~2.2 GB). Also the max heap size of MAT-32 Bit was by default 1GB, which cannot be tweaked. As per suggestion from an Eclipse forum - installed MAT for Windows 64 bit which did the job and allowed to tweak the max heap size. Have configured the vm argument -Xmx to 3GB in MemoryAnalyzer.ini file. Then the heap dump loaded in MAT without errors. 
 

Thursday, July 15, 2010

Sample XML parsing

 package sample;  

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import com.sun.org.apache.xpath.internal.XPathAPI;

import java.io.FileNotFoundException;
import java.io.IOException;

public class XMLParser {

private static Element getRootElementFromXML() {
Element xmlRootElm = null;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(XML_FILE_PATH);
Document doc = builder.parse(is);
xmlRootElm = doc.getDocumentElement();
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException :" + e);
} catch (IOException e) {
System.out.println("IOException :" + e);
} catch (SAXException e) {
System.out.println("SAXException :" + e);
} catch (ParserConfigurationException e) {
System.out.println("ParserConfigurationException :" + e);
}
return xmlRootElm;
}

private static Element getXmlElement(Element inRootElement, String inXpath) {
NodeList list = null;
Element element = null;
try {
list = XPathAPI.selectNodeList(inRootElement.getOwnerDocument(), inXpath);
} catch (TransformerException e) {
System.out.println("Unable to read XML : " + e);
}
if (list != null && list.getLength() > 0) {
element = (Element) list.item(0);
}
return element;
}

public static void main(String[] args) {
Element rootElement = getRootElementFromXML();
/**
* below constructed xpath : //country[@name='India']//city[@name='Chennai']
**/
String xPath = "//" + "country" + "[@name='" + "India" + "']//" + "city" +
"[@name='" + "Chennai" + "']";

Element element = getXmlElement(rootElement, xPath);
System.out.println("Code of Chennai : " + element.getAttribute("code"));
}

public static final String XML_FILE_PATH = "./src/sample/Sample.xml";
}



Sample.xml

 <?xml version="1.0" encoding="UTF-8"?>  
<countries>
<country name="India">
<city name="Delhi" code="011"/>
<city name="Mumbai" code="022"/>
<city name="Kolkata" code="033"/>
<city name="Chennai" code="044"/>
</country>
<country name="USA">
<city name="SanFrancisco" code="055"/>
<city name="Newyork" code="066"/>
<city name="Washington" code="077"/>
<city name="Florida" code="088"/>
</country>
<country name="Australia">
<city name="Sydney" code="099"/>
<city name="Melbourne" code="100"/>
<city name="Adelaide" code="111"/>
<city name="Perth" code="222"/>
</country>
</countries>

Friday, June 4, 2010

Factory pattern

Factory Pattern - a type of Creational Pattern. The creational patterns deal with the best way to create instances of objects.

Sample design

 public interface IEquipment {
String getType();
}

public abstract class Equipment implements IEquipment{
public String getNumber() {
return number;
}
protected void setNumber(String number) {
this.number = number;
}
private String number;
}


public class Container extends Equipment{
public Boolean getIsReefer() {
return isReefer;
}
protected void setIsReefer(Boolean isReefer) {
this.isReefer = isReefer;
}
public String getType() {
return "Container";
}

private Boolean isReefer;
}


public class Chassis extends Equipment {
public Boolean getIsWheeled() {
return isWheeled;
}
protected void setWheeled(Boolean isWheeled) {
this.isWheeled = isWheeled;
}
public String getType() {
return "Chassis";
}

private Boolean isWheeled;
}


public class Accessory extends Equipment {
public String getDescription() {
return description;
}
protected void setDescription(String description) {
this.description = description;
}
public String getType() {
return "Accessory";
}

private String description;
}


// Factory producing Equipments
public class EquipmentFactory {
public static IEquipment createEquipment(String inEquipmentType) {
IEquipment equipment = null;
if (CONTAINER.equals(inEquipmentType)) {
equipment = new Container();
} else if (CHASSIS.equals(inEquipmentType)) {
equipment = new Chassis();
} else if (ACCESSORY.equals(inEquipmentType)) {
equipment = new Accessory();
}
return equipment;
}

private static final String CONTAINER = Container.class.getName();
private static final String CHASSIS = Chassis.class.getName();
private static final String ACCESSORY = Accessory.class.getName();
}

Tuesday, July 7, 2009

Stack and Heap in java

Stack in java is used to store methods and local variables or stack variable.
It is useful in threading and exception handling. As per the behavior of stack (LIFO) Last In First Out, the elements in the stack depends on each other.

For example

 void test() { 
int a;
chain();
}

Here while running the above code, first test() method will get invoked. After that chain() will be called..now test() will be in the top of stack memory.
After the execution of chain() only, the test() will finish its execution (as per LIFO).

On the other hand Heap is mainly used to store Objects. Whatever objects (instance variables) that is created is stored in Heap only.

Java uses Pass-by-Value and no pass-by reference

Java uses Pass-by-Value and no pass-by reference

Java does manipulate objects by reference, and all object variables are references.
However, Java doesn't pass method arguments by reference; it passes them by value.
 public void swap1(int var, int var2) { 
int temp = var1;
var1 = var2;
var2 = temp;
}

When swap1() returns, the variables passed as arguments will still hold their original values.
The method will also fail if we change the arguments type from int to Object, since Java passes object references by value as well.
 public void swap2(Point arg1, Point arg2) { 
arg1.x = 100;
arg1.y = 100;

Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}

public static void main(String[] args) {
Point pnt1 = new Point(0, 0);
Point pnt2 = new Point(0, 0);
System.Out.printIn("X= " + pnt1.x + " Y=" + pnt1.y);
System.Out.printIn("X= " + pnt2.x + " Y=" + pnt2.y);
}

IF we execute this main() method, we see the following output:
X= 0 Y= 0
X= 0 Y= 0
X= 100 Y= 100
x= 0 y= 0

Sunday, June 28, 2009

Sort a list of Objects based on their names

 List sortSubPanelBasedOnNames(List subPanels) { 
Collections.sort(subPanels, new Comparator() {
public int compare(TestPanel panel1, TestPanel panel2) {
return (panel1.getInspectorName()).compareTo(panel2.getInspectorName());
}
});
return subPanels;
}