Java DNS Cache and JVM TTL

When ever your java program performs a network operation the Domain name service (DNS) settings get cached inside JVM, meaning the IP address of the other machine get cached in the JVM for a period of time usually called TTL (a.k.a Time to Live) . During this time Java uses the cached IP address, even if the IP address gets changed for the machine your are trying to connecting to. Therefore if TTL is set to 300 secs and  the server or resource you are trying to connect to changes its IP address the java application won’t be able to connect to it. This can be solved if we restart the JVM which will flush out the cache.

We face this issue all the time when ever we are trying to move our  server cluster A to server cluster B, we need to reset or restart the clients connecting to those server clusters. For JDK 1.4 clients the default TTL settings is that it will cache the DNS for ever. The TTL value differs in version to version.

 

We can disable Java/JVM DNS caching by adding

1
-Dsun.net.inetaddr.ttl=0

on the command line starting the JVM or we can set TTL  in the file java.security, which is located in the directory %JRE%\lib\security.

following shows how to configure the TTL to 30 seconds.

1
networkaddress.cache.ttl=30

 

IP address is a unique address/number assigned to each computer/printer/device on internet. It is used to identify a computer on the internet. IPv4 is the most  commonly used Internet Protocol Version, its format is 0.0.0.0 (127.0.0.1) for local address.

The latest version of Internet Protocol to date  (Sept 2014) is IPv6. IPv6 is intended to replace IPv4 but still 96% of the internet traffic is still using IPv4.

If your java program (HttpServletRequest.getRemoteAddr() ) is returning IPv6 format of IP address and you need it to return IPv4 format then you need to add the following JVM param at your server startup.

1
-Djava.net.preferIPv4Stack=true

 

Quickly Maven

Maven

Maven

Quickly Maven

In short, maven is a build automation tool describing the structure of the Java project and its dependencies. Maven addresses dependency management, artifact versioning and project comprehension.

We already went through a brief steps to convert a ANT based project to maven in this article Convert an ANT project to Maven

Dependency management and transitive dependency

Dependency management allows combining and centralizing the management of dependencies and their versions via single configuration file (pom.xml).

Transitive Dependency can be simply explained as a functional dependency between dependencies for e.g. if Aà B and Bà C then AàC therefore A is transitive dependent on C. If project A has a dependency project B and project B has a dependency on project C, then while building the project A maven with automatically download all the dependencies of project A i.e. project B and will also download all the dependencies of project B and this will go on till nth level.

Make sure you don’t end up with cyclic dependency like AàB BàC CàA

Dependency Scope defines when these dependencies are needed for e.g compile means this dependency is needed at the Read full story »

Java DateUtils methods

Some Java Utility methods for date conversions

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private String getUTCTimeAfter(int hours)
{
 
SimpleDateFormat sdfUTC = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
sdfUTC.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = new Date(System.currentTimeMillis()
+ (hours * 60 * 60 * 1000));
return sdfUTC.format(date);
}
 
private Date getLocalTime(String utcDateStr, SimpleDateFormat sdfUTC)
throws Exception
{
SimpleDateFormat sdfLocal = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdfLocal.setTimeZone(TimeZone.getDefault());
 
Date date = sdfUTC.parse(utcDateStr);
String localTimeStr = sdfLocal.format(date.getTime());
return sdfLocal.parse(localTimeStr);
 
}

Java Convert LocalTime to UTC Time

Converts Local future/previous date in String to UTC date

A simple utility method to convert local time into UTC time. The important thing in this method is, you will find a lot of examples on the internet that changes the “current” local time to UTC time, but you will hardly find an example where you will change an old local time stored as string and change it to UTC time for that moment of time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 public static String convertLocalTimeToUTC(String saleTimeZone, String p_localDateTime) throws Exception{
 
  String dateFormateInUTC="";
  Date localDate = null;
  String localTimeZone ="";
  SimpleDateFormat formatter;
  SimpleDateFormat parser;
  localTimeZone = saleTimeZone;
 
  //create a new Date object using the timezone of the specified city
  parser = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
  parser.setTimeZone(TimeZone.getTimeZone(localTimeZone));
  localDate = parser.parse(p_localDateTime);
  formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss z'('Z')'");
  formatter.setTimeZone(TimeZone.getTimeZone(localTimeZone));
  System.out.println("convertLocalTimeToUTC: "+saleTimeZone+": "+" The Date in the local time zone " +   formatter.format(localDate));
 
  //Convert the date from the local timezone to UTC timezone
  formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
  dateFormateInUTC = formatter.format(localDate);
  System.out.println("convertLocalTimeToUTC: "+saleTimeZone+": "+" The Date in the UTC time zone " +  dateFormateInUTC);
 
 return dateFormateInUTC;
 }
 
  public static void main(String arg[]) throws Exception
    {
 
    	convertLocalTimeToUTC("EST", "12-03-2013 10:30:00");
    	convertLocalTimeToUTC("PST", "12-03-2013 10:30:00");
    }

Hope this helps.

Java Heap Dump

After JDK6 its easy to generate Java Heap dumps using jmap.
here is a quick example, make sure your user has the permission to write on the dump folder.

./jmap -dump:live,format=b,file=/var/tmp/abc.hprof pid
where pid is the process id, live option ensures to dump only live objects (yes JVM executes FULL GC before dumping heap)

you can search your java process pid using
ps -ef | grep java

once done you might need to give permission right to download the file, I just simply change the mode to all permission.
chmod 777 /var/tmp/abc.hprof

Once downloaded, I use visualvm or jvisualvm to analyze the heap dumps.

General Contract for Equals and Hashcode

Java Equals and Hashcode general Contract

Overiding BOTH, equals and hashcode method is not a common practice among java developers, but is strongly recommended in order to avoid the followings.

1) duplicate Objects in a set
2) list’s contains method returns false even you have added that object in the list
3) Can not find same content object in a hashtable even the contents of the objects are same

First thing first:
The first thing you must remember is when ever you override equals method, you must override the hashcode method as well.
The reason for doing so is the default implementation of equals method is to compares the memory addresses of the objects and if you override the equals() and you dont override hashcode you are violating the general contract for Object.hashCode, which can have unexpected consequences when your class is used with hash-based collections like hashmap and hashtable

The simplified version of General Contract for HashCode method

a) The hashcode must return the same integer value, if called multiple times on the same object, considering that the object properties are not modified.

b) If the equals method returns true for two objects then the hashCode method of the two objects must return the same integer value.

c) If two objects are not equal, there hashcode still can be the same but its a good practice producing distinct integer results for unequal objects becuase it may improve the performance of hashtables.

more to come when ever I got time/chance to write…

 

Log4j Stop Axis debugging

Log4j debugging to rescue

In one of my JNLP based fat client project we were using axis client to perform web services call to get the initialization data. The application is built and deployed using Maven.  LOG4j is the logger for the application and the application logging was controlled via java.util.logging. One of the problems we use to face during production support was the axis client prints a lot of DEBUG messages in the Java console that we were not able to see the error log messages. Therefore we needed to stop axis log messages. The easiest way to solve this was to change the log level to INFO, but the strange thing is even we changed the log level for console handler to INFO; the axis client was still printing DEBUG log messages on the Java Console.

 

1
2
3
4
5
6
7
Level logLevel = Level.parse(“INFO”);
 
ConsoleHandler consoleHandler = new ConsoleHandler();
 
consoleHandler.setLevel(logLevel);
 
Logger.getLogger("").addHandler(consoleHandler);

 

After some research I found that axis is using log4j for logging but we don’t have log4j.xml or log4j.properties file in our project. This was wired until I set the debug level for lof4j to true

1
-Dlog4j.debug=true

After this now I could clearly see that one of my project dependencies have a log4j.xml and that was being loaded to set the log level.

Modifying the log4j.xml solves our problem

1
2
3
4
5
<logger name="org.apache.axis">
 
<level value="info"/>
 
</logger>

Restriction on required library rt.jar Error

Restriction on required library rt.jar Error

I encountered the following error in my eclipse when I import an existing project.

Access restriction: The type <class name> is not accessible due to restriction on required library C:\Program Files\Java\jdk6\jre\lib\rt.jar

After researching on the internet I found one possible reason is that, may be you are using a class that is only meant to be used by Java itself or may be you are replacing a standard class which ships with Java 6 with one in a library you have. But I can not confirm this.

Solution

The recommended Solution is to get rid of this class and use any alternative

short term Solution is remove the JRE library from your project and Add it again

for example this will work in eclipse

1. Open project properties.
2. Select Java Build Path node.
3. Select Libraries tab.
4. Remove JRE System Library.
5. Add Library JRE System Library.

 

And it works.

I hope both solutions helps

 

 

Deep and Shallow comparison

Deep and Shallow comparison

Yeah, its comparison :) I agree you must have heard deep copy or shallow copy.
Usually “deep” and “shallow” are used to refer to copying, not comparison but here I would like to give a brief difference between deep comparison and shallow comaparison of objects.
Shallow Comparison
When you do == you are comparing the references for equality. You are checking, is the address in memory the same for both Objects?

Deep comparison
When you do .equals() you are comparing the Objects themselves for equality. You are checking, do these two Objects consider themselves equal?

Here is a short example how you will write an equals method having deep comparison and shallow comparison

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.syed.rizvi.test;
 
public class Employee {
 
private int empid;
private String name;
public int getEmpid() {
return empid;
}
public void setEmpid(int empid) {
this.empid = empid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
 
public boolean equals(Object obj)
{
if (obj == null)
return false;
// shallow comparison
if (this == obj)
return true;
 
if (!(obj instanceof Employee))
return false;
 
Employee other = (Employee) obj;
// Deep comparison
if (this.getEmpid() == other.getEmpid() && this.getName().equals(other.getName()))
{
return true;
}
return false;
}
}
Einfobuzz Site Map