Being brought up in India, we never have to worry about Daylight saving chores. But its very interesting and also important for any system designer to know all about DST.
More info at this link : http://webexhibits.org/daylightsaving/
DST also comes into play when we schedule jobs using cron or Quartz.
For e.g. In the US, many states implement DST at 2 a.m.
If we have a job scheduled at 2.15 am, then it won't be fired on the day when the cock is shifted ahead from 2.00 to 3.00 am :)
Thursday, February 15, 2007
Monday, February 12, 2007
Spring JDBC quirks
Spring JDBC's JdbcTemplate provides us with utility methods that return scalar values. For e.g. methods such as queryForObject, queryForInt, queryForLong etc. These methods are useful when we need to obtain a single row or single column from the database.
But there is a caveat here. Each of these 'scalar' methods throw an IncorrectResultSizeDataAccessException if the there are no results or more than one row in the resultset.
For e.g. if there is a valid business condition that no rows may be returned for a particular query, then we need to handle this exception and return null. The other option is to use the generic query methods that return a list. For empty resultsets we can return an empty list.
But there is a caveat here. Each of these 'scalar' methods throw an IncorrectResultSizeDataAccessException if the there are no results or more than one row in the resultset.
For e.g. if there is a valid business condition that no rows may be returned for a particular query, then we need to handle this exception and return null. The other option is to use the generic query methods that return a list. For empty resultsets we can return an empty list.
Printing Stack Trace in Java
Quite often, developers use the statement exception.printStackTrace() to print the stack trace on to the console. It is important to remember that printStackTrace method prints the stack trace to the System.Err stream and not the System.Out stream.
Due to this, there are a lot of exception stacks getting printed in the System.Err files on the application server, but we do not see any trace of it in the Log4J files or System.out files !!!!
As a best practice, I strongly recommend not using e.printStackTrace() in production code. If the project is using Log4J, then the method 'Logger.error(message, exception)' would print the stack trace to all the registered appenders.
Alternatively, I have written a utility method that would return the stack trace as String. Please use this method if you want to get a stacktrace as a string for more flexibility in printing.
---------------------------------------------------------
/**
* Gets the exception stack trace as a string.
* @param exception
* @return
*/
public String getStackTraceAsString(Exception exception)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.print(" [ ");
pw.print(exception.getClass().getName());
pw.print(" ] ");
pw.print(exception.getMessage());
exception.printStackTrace(pw);
return sw.toString();
}
---------------------------------------------------
But what if there is already production code that uses e.printStackTrace() and System.out and you want to redirect them to the Log Files. In that case, we can make use of the System.setOut() and System.setErr() methods. Also try the LoggingOutputStream class in the contribs/JimMoore folder of the log4j release.
Due to this, there are a lot of exception stacks getting printed in the System.Err files on the application server, but we do not see any trace of it in the Log4J files or System.out files !!!!
As a best practice, I strongly recommend not using e.printStackTrace() in production code. If the project is using Log4J, then the method 'Logger.error(message, exception)' would print the stack trace to all the registered appenders.
Alternatively, I have written a utility method that would return the stack trace as String. Please use this method if you want to get a stacktrace as a string for more flexibility in printing.
---------------------------------------------------------
/**
* Gets the exception stack trace as a string.
* @param exception
* @return
*/
public String getStackTraceAsString(Exception exception)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.print(" [ ");
pw.print(exception.getClass().getName());
pw.print(" ] ");
pw.print(exception.getMessage());
exception.printStackTrace(pw);
return sw.toString();
}
---------------------------------------------------
But what if there is already production code that uses e.printStackTrace() and System.out and you want to redirect them to the Log Files. In that case, we can make use of the System.setOut() and System.setErr() methods. Also try the LoggingOutputStream class in the contribs/JimMoore folder of the log4j release.
Monday, February 05, 2007
Redirecting system.out, system.err to a file on Unix/Solaris boxes
It is simple to redirect a process output to a standard file using the '>' operator.
But if you also want the std error to go to a file, then you need to type:
java className>file 2>&1
To understand what the above command means, it is imp to note that the shell reads arguments from left to right. The shell sees >file first and redirects stdout to file. Next 2>&1 sends fd2 (stderr) to the same place fd1 is going - that's to the file.
But if you also want the std error to go to a file, then you need to type:
java className>file 2>&1
To understand what the above command means, it is imp to note that the shell reads arguments from left to right. The shell sees >file first and redirects stdout to file. Next 2>&1 sends fd2 (stderr) to the same place fd1 is going - that's to the file.
Epoch - The start of time for computing
Recently working on a XML data feed program, I had to handle empty date XML elements. I wondered as to what date I can put into the database - the start of time?. What is the start of time used by computer systems?
As Java programmers we all know that the Date, Calendar classes in Java use January 1, 1970 as the start of 'time'. This is known as Epoch. Wikipedia defines epoch as follows:
"The epoch serves as a reference point from which time is measured. Days, hours and other time units are counted from the epoch, so that the date and time of events can be specified. Events that took place earlier can be dated by counting negatively from the epoch."
There are different epocs used by different systems:
- Unix and Java use Jan 1, 1970
- MS DOS uses Jan 1, 1980
- Excel and Lotus = Dec 31, 1899
More info can be found here.
As for me, I decided to use the Java Epoc for my program :)
As Java programmers we all know that the Date, Calendar classes in Java use January 1, 1970 as the start of 'time'. This is known as Epoch. Wikipedia defines epoch as follows:
"The epoch serves as a reference point from which time is measured. Days, hours and other time units are counted from the epoch, so that the date and time of events can be specified. Events that took place earlier can be dated by counting negatively from the epoch."
There are different epocs used by different systems:
- Unix and Java use Jan 1, 1970
- MS DOS uses Jan 1, 1980
- Excel and Lotus = Dec 31, 1899
More info can be found here.
As for me, I decided to use the Java Epoc for my program :)
Tuesday, January 30, 2007
Using ASCII mode for FTP of text files
Last week, I ran across a common problem -- I had transferred a INI file from Windows to Solaris in binary mode and the file did not work on Solaris. This was obviously due to the difference in newline characters.
I then realized that if we transfer in ASCII mode, then the FTP program automatically converts between windows and unix line feed characters :)
More info at these links:
http://www.editpadpro.com/tricklinebreak.html
I then realized that if we transfer in ASCII mode, then the FTP program automatically converts between windows and unix line feed characters :)
More info at these links:
http://www.editpadpro.com/tricklinebreak.html
Tuesday, January 16, 2007
Solaris tips - find out RAM and HD size
A few quick commands to help developers new on Solaris 10:
To find out the amount of RAM on the system.
> prtconf / grep Mem
To find out the Hard Disk capacity
> iostat -E / grep Size
To find out the file-system size
>df -h
To find out the CPU usage
> mpstat 12 5
> ps -e -o pcpu -o pid -o user -o args
> top
The following links give more info on common commands:
http://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html
http://www.geocities.com/arndike/Solaris_probe_process.html
http://projects.ericshalov.com/technotes/notes/solaris
To find out the amount of RAM on the system.
> prtconf / grep Mem
To find out the Hard Disk capacity
> iostat -E / grep Size
To find out the file-system size
>df -h
To find out the CPU usage
> mpstat 12 5
> ps -e -o pcpu -o pid -o user -o args
> top
The following links give more info on common commands:
http://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html
http://www.geocities.com/arndike/Solaris_probe_process.html
http://projects.ericshalov.com/technotes/notes/solaris
Labels:
Solaris
Monday, January 08, 2007
Getting the Client IP address on a J2EE server
The HTTPRequest object has 2 methods 'getRemoteAddr()' and 'getRemoteHost()'. These methods would return us the IPAddress/HostName of the last proxy or the client. So if the client is behind a proxy, then we would get the IPAddress of the proxy.
Some proxies (known as transparent proxies) pass the actual IP address of the client in the header HTTP_X_FORWARDED_FOR.
So on the server side we can code something like this:
if (request.getHeader("HTTP_X_FORWARDED_FOR") == null) {
String ipaddress = request.getRemoteAddr();
} else {
String ipaddress = request.getHeader("HTTP_X_FORWARDED_FOR");
}
But if the proxy is an anonymous proxy, then even this won't work. So the only way to get the Client Address correctly is using an Applet to capture the IP address of the client. For this, the client should be trusted and signed.
Another option that I came across in a forum is to create a Socket connection back to the web server from which you came and asking the Socket for the local address:
URL url = getDocumentBase();
String host = url.getHost();
Socket socket = new Socket(host, 80);
InetAddress addr = socket.getLocalAddress();
String hostAddr = addr.getHostAddress();
System.out.println("Addr: " + hostAddr);
Some proxies (known as transparent proxies) pass the actual IP address of the client in the header HTTP_X_FORWARDED_FOR.
So on the server side we can code something like this:
if (request.getHeader("HTTP_X_FORWARDED_FOR") == null) {
String ipaddress = request.getRemoteAddr();
} else {
String ipaddress = request.getHeader("HTTP_X_FORWARDED_FOR");
}
But if the proxy is an anonymous proxy, then even this won't work. So the only way to get the Client Address correctly is using an Applet to capture the IP address of the client. For this, the client should be trusted and signed.
Another option that I came across in a forum is to create a Socket connection back to the web server from which you came and asking the Socket for the local address:
URL url = getDocumentBase();
String host = url.getHost();
Socket socket = new Socket(host, 80);
InetAddress addr = socket.getLocalAddress();
String hostAddr = addr.getHostAddress();
System.out.println("Addr: " + hostAddr);
Friday, January 05, 2007
Secure FTP options
I was looking for an secure option to FTP files to a remote server.
There are 2 options available: FTPS and SFTP....and I was a bit confused in understanding the differences between the two.
FTPS is FTP over SSL/TLS.
SFTP (Secure FTP) is FTP tunneled thru SSH.
SFTP provides an interactive interface that is similar to that of FTP. In addition, the command line version of SFTP is scriptable in that it allows you to specify a batch file to control the file transfer process.
If U are using VPN, then another option would be to constrain FTP access to circuits created over VPN connections, then as long as the VPN is secure end-to-end, FTP will also be acceptably secure.
There are 2 options available: FTPS and SFTP....and I was a bit confused in understanding the differences between the two.
FTPS is FTP over SSL/TLS.
SFTP (Secure FTP) is FTP tunneled thru SSH.
SFTP provides an interactive interface that is similar to that of FTP. In addition, the command line version of SFTP is scriptable in that it allows you to specify a batch file to control the file transfer process.
If U are using VPN, then another option would be to constrain FTP access to circuits created over VPN connections, then as long as the VPN is secure end-to-end, FTP will also be acceptably secure.
File Encryption utility for windows
I was looking for a small light-weight encryption utility for encrpyting my personal information in files. There are a plethora of programs available on the internet, but I found the following ones cool and easy to use.
Kryptel Lite: http://www.kryptel.com/products/krlite/
Iron Key: http://www.kryptel.com/products/ikey/index.php
Kryptel Lite: http://www.kryptel.com/products/krlite/
Iron Key: http://www.kryptel.com/products/ikey/index.php
Thursday, January 04, 2007
FTPing in Java
For performing FTP operations programmatically, I use the Jakarta Commons Net Package. This is a super-cool utility package that makes writting FTP programs a breeze.
The jar file can be downloaded from here.
Tip: The jakarta-commons-net package also requires the ORO package which can be downloaded here.
Another important concept is that of Active and Passive FTP. A good explanation of the differences can be found here.
As a general rule, passive FTP is used as it works behind firewalls too.
The windows FTP can also be run unattended using the '-s' option and specifies a script file that contains the FTP commands.
The jar file can be downloaded from here.
Tip: The jakarta-commons-net package also requires the ORO package which can be downloaded here.
Another important concept is that of Active and Passive FTP. A good explanation of the differences can be found here.
As a general rule, passive FTP is used as it works behind firewalls too.
The windows FTP can also be run unattended using the '-s' option and specifies a script file that contains the FTP commands.
Tuesday, January 02, 2007
URL encoding and XML/HTML encoding
Recently in one of our applications we were passing XML data as a POST parameter to the server. For e.g. xml={xml string here}
We were using XML encoding to replace special characters in the XML. For e.g. '&' was replaced with '&' '<' was replaced with & lt; etc.
But on the server side whenever we were trying to get the XML string as a request parameter, we were getting a truncated string. After putting in a sniffer, I found out the reason why this was happening - I was getting confused between URL encoding and XML encoding.
In URL encoding as we know, we need to encode special characters such as '&'. So we replace them with '&'. But what if '&' was part of the data; i.e. an address contained &. In this case the URL encoding function should just replace '&' with '%26'. Otherwise the server would treat it as a parameter separator and break the string on the first occurance of '&'.
Now our XML string (passed as a POST parameter) contained the & character, because all XML special characters were encoded with a '&' at the beginning. So the trick in this case was to perform URL encoding of the element values after the XML encoding. Confused??
Ok...consider the following XML element:
<name>Naren&Sons<\name>
Now the above element data contains an & and hence would result in a XML parsing error. Hence I XML encode the data. So it would not look like:
<name>Naren&Sons<\name>
But when this string is passed as a HTTP GET/POST param, then it would be truncated.
Hence we have to URL encode it - replace & with %26
<name>Naren%26amp;Sons<\name>
So when the string reaches the server, the request.getParameter would perform the URL decoding and then we passed the XML string to Castor or any other XML parser.
Another good design to avoid all this confusion is to pass the XML in the request body stream and get the XML on the server side using request.getInputStream().
Even ASP.NET has 2 methods: HtmlEncode and UrlEncode.
HtmlEncode converts the angle brackets, quotes, ampersands, etc. to the entity values to prevent the HTML parser from confusing it with markup.
UrlEncode converts spaces to "+" and non-alphanumeric to their hex-encoded values. Again this is to prevent the the URL parser from misinterpreting an embedded ?, & or other values.
We were using XML encoding to replace special characters in the XML. For e.g. '&' was replaced with '&' '<' was replaced with & lt; etc.
But on the server side whenever we were trying to get the XML string as a request parameter, we were getting a truncated string. After putting in a sniffer, I found out the reason why this was happening - I was getting confused between URL encoding and XML encoding.
In URL encoding as we know, we need to encode special characters such as '&'. So we replace them with '&'. But what if '&' was part of the data; i.e. an address contained &. In this case the URL encoding function should just replace '&' with '%26'. Otherwise the server would treat it as a parameter separator and break the string on the first occurance of '&'.
Now our XML string (passed as a POST parameter) contained the & character, because all XML special characters were encoded with a '&' at the beginning. So the trick in this case was to perform URL encoding of the element values after the XML encoding. Confused??
Ok...consider the following XML element:
<name>Naren&Sons<\name>
Now the above element data contains an & and hence would result in a XML parsing error. Hence I XML encode the data. So it would not look like:
<name>Naren&Sons<\name>
But when this string is passed as a HTTP GET/POST param, then it would be truncated.
Hence we have to URL encode it - replace & with %26
<name>Naren%26amp;Sons<\name>
So when the string reaches the server, the request.getParameter would perform the URL decoding and then we passed the XML string to Castor or any other XML parser.
Another good design to avoid all this confusion is to pass the XML in the request body stream and get the XML on the server side using request.getInputStream().
Even ASP.NET has 2 methods: HtmlEncode and UrlEncode.
HtmlEncode converts the angle brackets, quotes, ampersands, etc. to the entity values to prevent the HTML parser from confusing it with markup.
UrlEncode converts spaces to "+" and non-alphanumeric to their hex-encoded values. Again this is to prevent the the URL parser from misinterpreting an embedded ?, & or other values.
Friday, December 29, 2006
Caching headers in HTTP
All dynamic applications need to prevent caching so that the request actually reaches the server each time.
In this post, I found over the internet, a good explanation of the different cache headers was given. Snippet from the post:
First of all you have to remember that these directives are used by all downstream caches (proxy servers and the browser) and therefore what might work in one situation (say, a direct connection between web server and client) may not work if there is a caching proxy server in between if the cache control headers are not thought through carefully.
Taking the directives in turn:
response.setHeader("Pragma", "no-cache");
This is the only cache control directive for HTTP 1.0, so should feature in addition to any HTTP 1.1 cache control headers you include.
response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
This directive does NOT prevent caching despite its name. It allows caching of the page, but specifies that the cache must ask the originating web server if the page is up-to-date before serving the cached version. So the cached page can still be served up i- f the originating web server says so. Applies to all caches.
response.setDateHeader ("Expires", 0); // HTTP 1.1
This tells the browser that the page has expired and must be treated as stale. Should be good news as long as the caches obey.
response.setHeader("Cache-Control", "private"); // HTTP 1.1
This specifies that the page contains information intended for a single user only and must not be cached by a shared cache (e.g. a proxy server).
response.setHeader("Cache-Control", "no-store"); // HTTP 1.1
This specifies that a cache must NOT store any part of the response or the request that elicited it. Adding these two headers should prevent the caching of pages anywhere between the web server and browser, as well as in the browser itself. The meaning of each directive is very specific and so a given combination of directives has a different effect in any one environment.
In this post, I found over the internet, a good explanation of the different cache headers was given. Snippet from the post:
First of all you have to remember that these directives are used by all downstream caches (proxy servers and the browser) and therefore what might work in one situation (say, a direct connection between web server and client) may not work if there is a caching proxy server in between if the cache control headers are not thought through carefully.
Taking the directives in turn:
response.setHeader("Pragma", "no-cache");
This is the only cache control directive for HTTP 1.0, so should feature in addition to any HTTP 1.1 cache control headers you include.
response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
This directive does NOT prevent caching despite its name. It allows caching of the page, but specifies that the cache must ask the originating web server if the page is up-to-date before serving the cached version. So the cached page can still be served up i- f the originating web server says so. Applies to all caches.
response.setDateHeader ("Expires", 0); // HTTP 1.1
This tells the browser that the page has expired and must be treated as stale. Should be good news as long as the caches obey.
response.setHeader("Cache-Control", "private"); // HTTP 1.1
This specifies that the page contains information intended for a single user only and must not be cached by a shared cache (e.g. a proxy server).
response.setHeader("Cache-Control", "no-store"); // HTTP 1.1
This specifies that a cache must NOT store any part of the response or the request that elicited it. Adding these two headers should prevent the caching of pages anywhere between the web server and browser, as well as in the browser itself. The meaning of each directive is very specific and so a given combination of directives has a different effect in any one environment.
Showing Modal windows in HTML Browsers
It had always been a challenge for web developers to show modal dialog boxes using Javascript that works across all browsers.
IE has a proprietary javascript method called 'showModalDialog', where as FireFox accepts an 'modal' attribute in the window.open function. Here's a sample code for the same:
function modalWin()
{
if (window.showModalDialog)
{window.showModalDialog("xpopupex.htm","name",
"dialogWidth:255px;dialogHeight:250px");}
else
{window.open('xpopupex.htm','name','height=255,width=250,toolbar=no,
directories=no,status=no,menubar=no,
scrollbars=no,resizable=no ,modal=yes');}
}
But there still remains one more problem. How to disable the close button in the dialog. There is no support in JS for that, hence the simple answer is that NO-it cannot be done.
But we can write our own custom dialog. An example of the same is given here:
http://javascript.about.com/library/blmodald1.htm But this involved a lot of work.
Being lazy, I was looking for a out-of-box solution and my prayers were answered - The Yahoo widget UI library. This is one of the coolest AJAX, DHTML library I have seen in years and its FREE for all use.
The Yahoo UI Library has a SimpleDialog Component that can be made modal and also the close button on the header can be disabled. Also the control is very simple to use.
http://developer.yahoo.com/yui/container/simpledialog/
IE has a proprietary javascript method called 'showModalDialog', where as FireFox accepts an 'modal' attribute in the window.open function. Here's a sample code for the same:
function modalWin()
{
if (window.showModalDialog)
{window.showModalDialog("xpopupex.htm","name",
"dialogWidth:255px;dialogHeight:250px");}
else
{window.open('xpopupex.htm','name','height=255,width=250,toolbar=no,
directories=no,status=no,menubar=no,
scrollbars=no,resizable=no ,modal=yes');}
}
But there still remains one more problem. How to disable the close button in the dialog. There is no support in JS for that, hence the simple answer is that NO-it cannot be done.
But we can write our own custom dialog. An example of the same is given here:
http://javascript.about.com/library/blmodald1.htm But this involved a lot of work.
Being lazy, I was looking for a out-of-box solution and my prayers were answered - The Yahoo widget UI library. This is one of the coolest AJAX, DHTML library I have seen in years and its FREE for all use.
The Yahoo UI Library has a SimpleDialog Component that can be made modal and also the close button on the header can be disabled. Also the control is very simple to use.
http://developer.yahoo.com/yui/container/simpledialog/
Thursday, December 28, 2006
Dealing with currency calculations
Many novice developers use 'float' and 'double' data-types to represent dollars and cents. This is dangerous as float/double calculations always involve rounding off and precision errors.
More info can be found at the following links:
http://www-128.ibm.com/developerworks/java/library/j-jtp0114/
http://www.javaworld.com/cgi-bin/mailto/x_java.cgi
http://en.wikipedia.org/wiki/IEEE_754
Currency values require exactness. Hence use the 'BigDecimal' class in Java for handling currencies. Here is some code snippet:
//Get the base value of the policy and store it in a BigDecimal object
BigDecimal d = new BigDecimal("1115.32");
//get the extra's multiplier from database
BigDecimal multiplier = new BigDecimal("0.0049");
//Do the multiplication - use methods of Big Decimal
BigDecimal d2 = d.multiply(multiplier);
System.out.println("Unformatted no scale: " + d2.toString());
//Set the scale (2 decimal places) and round-off mode
d2 = d2.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("Unformatted with scale: " + d2.toString());
NumberFormat n = NumberFormat.getCurrencyInstance(Locale.UK);
double money = d2.doubleValue();
String s = n.format(money);
System.out.println("Formatted: " + s);
More info can be found at the following links:
http://www-128.ibm.com/developerworks/java/library/j-jtp0114/
http://www.javaworld.com/cgi-bin/mailto/x_java.cgi
http://en.wikipedia.org/wiki/IEEE_754
Currency values require exactness. Hence use the 'BigDecimal' class in Java for handling currencies. Here is some code snippet:
//Get the base value of the policy and store it in a BigDecimal object
BigDecimal d = new BigDecimal("1115.32");
//get the extra's multiplier from database
BigDecimal multiplier = new BigDecimal("0.0049");
//Do the multiplication - use methods of Big Decimal
BigDecimal d2 = d.multiply(multiplier);
System.out.println("Unformatted no scale: " + d2.toString());
//Set the scale (2 decimal places) and round-off mode
d2 = d2.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("Unformatted with scale: " + d2.toString());
NumberFormat n = NumberFormat.getCurrencyInstance(Locale.UK);
double money = d2.doubleValue();
String s = n.format(money);
System.out.println("Formatted: " + s);
Labels:
Java floating point
Wednesday, December 27, 2006
Javascript: Conditional Comments and Conditional Compilation
Recently came across some cool new features of Javascript that reduced the amount of coding required. For many years, developers have been writing Javascript code to detect the browser type and accordingly fire javascript functions or do a document.write()
But now there are more developer-friendly ways of detecting the browser type and handling content.
Conditional Comments: These look like HTML comments, but IE browsers treat them differently.
For e.g.
<!--[if IE]>You are using IE (IE5+ and above).<![endif]-->
The above line would be rendered only if the browser is IE.
To render something if the browser in non-IE use the following:
<![if !IE]>You are NOT using IE.<![endif]>
We can also check the IE version number:
<!--[if IE 6]>You are using IE 6!<![endif]-->
Another feature of IE is Conditional Compilation. Non-IE browsers would ignore the @cc block
/*@cc_on
/*@if (@_win32)
document.write("OS is 32-bit, browser is IE.");
@else @*/
document.write("Browser is not IE (ie: is Firefox) or Browser is not 32 bit IE.");
/*@end@*/
But now there are more developer-friendly ways of detecting the browser type and handling content.
Conditional Comments: These look like HTML comments, but IE browsers treat them differently.
For e.g.
<!--[if IE]>You are using IE (IE5+ and above).<![endif]-->
The above line would be rendered only if the browser is IE.
To render something if the browser in non-IE use the following:
<![if !IE]>You are NOT using IE.<![endif]>
We can also check the IE version number:
<!--[if IE 6]>You are using IE 6!<![endif]-->
Another feature of IE is Conditional Compilation. Non-IE browsers would ignore the @cc block
/*@cc_on
/*@if (@_win32)
document.write("OS is 32-bit, browser is IE.");
@else @*/
document.write("Browser is not IE (ie: is Firefox) or Browser is not 32 bit IE.");
/*@end@*/
Labels:
Javascript
Wednesday, December 20, 2006
Beware of using Application Context in a WAS clustered environment
Websphere 6.1 Network Deployment App Server Package provides out-of-the-box support for clustering, thus providing for fail-over and load-balancing.
In a cluster, WAS provides data-replication services for 'session' data, 'WAS dynamic cache' data, etc. across member in a cluster.
But it does not provide replication of objects stored in the Application context or Servlet Context across the nodes of the cluster.
Hence if Ur application relies on state stored in the App Context, then it would fail in a cluster unless U make sure that all the concerned requests (which expect objects in the context) have the same JSESSIONID cookie and session affinity is configured on WAS. In this case, the WAS infrastructure would consider the jsession id present in the request and forward the request to the appropriate Appserver.
Another solution is to use a database or a file and not the Servlet Context for storing data to be shared across sessions.
In a cluster, WAS provides data-replication services for 'session' data, 'WAS dynamic cache' data, etc. across member in a cluster.
But it does not provide replication of objects stored in the Application context or Servlet Context across the nodes of the cluster.
Hence if Ur application relies on state stored in the App Context, then it would fail in a cluster unless U make sure that all the concerned requests (which expect objects in the context) have the same JSESSIONID cookie and session affinity is configured on WAS. In this case, the WAS infrastructure would consider the jsession id present in the request and forward the request to the appropriate Appserver.
Another solution is to use a database or a file and not the Servlet Context for storing data to be shared across sessions.
Monday, October 23, 2006
java.lang.error - Unresolved Compilation problem
Most of us have encounted this error when working with JSP pages. If JSP pages are compiled on the fly, then it is possible that errors are present in it that cannot be resolved at runtime. Hence it is a good idea to compile your JSPs as U develop them. Most of the modern IDE's have support for compiling JSP's during the 'build' process.
Recently I encountered the same error while building a web application on Netbeans. I was getting the "java.lang.error - Unresolved compilation problem" for a Struts Action class, that was referencing another bean. It was strange that this error was not caught by the compiler. I did a 'clean build' again and everything was OK. But still at runtime, I got the same error.
I was perplexed and could not understand what was the problem.
Then suddenly inbetween, I started getting ClassCastExceptions. It was then I reliazed that there was older classes in the classpath somewhere, that was messing things up.
Closer inspection revealed that someone had placed "classfiles" into source-control (VSS) and when we did 'get-latest', the old class files were also downloaded into our directory.
Moral of the story: Whenever U get ClassCastExceptions or Unresolved Compilation problems at runtime, check if U have stale class files somewhere in the classpath.
Recently I encountered the same error while building a web application on Netbeans. I was getting the "java.lang.error - Unresolved compilation problem" for a Struts Action class, that was referencing another bean. It was strange that this error was not caught by the compiler. I did a 'clean build' again and everything was OK. But still at runtime, I got the same error.
I was perplexed and could not understand what was the problem.
Then suddenly inbetween, I started getting ClassCastExceptions. It was then I reliazed that there was older classes in the classpath somewhere, that was messing things up.
Closer inspection revealed that someone had placed "classfiles" into source-control (VSS) and when we did 'get-latest', the old class files were also downloaded into our directory.
Moral of the story: Whenever U get ClassCastExceptions or Unresolved Compilation problems at runtime, check if U have stale class files somewhere in the classpath.
Friday, September 15, 2006
ClassLoaders and Packaging - J2EE Servers
I bet there is not a single J2EE developer who has not had nightmares trying to solve problems regarding ClassCastException when the J2EE application is deployed on the AppServer.
Resolving such problems require a sound knowledge of Java ClassLoading mechanism. In my previous post here, I had described the class loader heirarchy of standard JRE.
After this, we need to understand the class-loading mechanisms of the J2EE AppServer we are using. The classloading mechanisms of different appservers are different and also highly configurable through configuration files of the appserver. For e.g. make the classloaders execute child-first loading or the default parent-first loading, configure the same classloader for all modules in a ear file, etc.
Here is a good article that explains the fundamentals of ClassLoading in some J2EE servers:
http://www.theserverside.com/tt/articles/article.tss?l=ClassLoading
Resolving such problems require a sound knowledge of Java ClassLoading mechanism. In my previous post here, I had described the class loader heirarchy of standard JRE.
After this, we need to understand the class-loading mechanisms of the J2EE AppServer we are using. The classloading mechanisms of different appservers are different and also highly configurable through configuration files of the appserver. For e.g. make the classloaders execute child-first loading or the default parent-first loading, configure the same classloader for all modules in a ear file, etc.
Here is a good article that explains the fundamentals of ClassLoading in some J2EE servers:
http://www.theserverside.com/tt/articles/article.tss?l=ClassLoading
Alternatives to Apache webserver
Learned about some new webservers that claim to be faster than Apache and can handle more traffic under heavy load:
http://www.acme.com/software/thttpd/
http://www.lighttpd.net/
These servers are being used for heavy traffic websites and its definately worth evalauting them.
http://www.acme.com/software/thttpd/
http://www.lighttpd.net/
These servers are being used for heavy traffic websites and its definately worth evalauting them.
ArrayList Vs LinkedList
The Java SDK contains 2 implementations of the List interface - ArrayList and LinkedList.A common design dilemma for developers is when to use what ?
Some basics first:
An arraylist used an array for internal storage. This means it's fast for random access (e.g. get me element #999), because the array index gets you right to that element. But then adding and deleting at the start and middle of the arraylist would be slow, because all the later elements have to copied forward or backward. (Using System.arrayCopy())
ArrayList would also give a performance issue when the internal array fills up. The arrayList has to create a new array and copy all the elements there. The ArrayList has a growth algorithm of (n*3)/2+1, meaning that each time the buffer is too small it will create a new one of size (n*3)/2+1 where n is the number of elements of the current buffer. Hence if we can guess the number of elements that we are going to have, then it makes sense to create a arraylist with that capacity during object creation (using the overloaded construtor or ArrayList)
LinkedList is made up of a chain of nodes. Each node stores an element and the pointer to the next node. A singly linked list only has pointers to next. A doubly linked list has a pointer to the next and the previous element. This makes walking the list backward easier.
Linked lists are slow when it comes to random access. Gettting element #999 means you have to walk either forward from the beginning or backward from the end (depending on whether 999 is less than or greater than half the list size), calling next or previous, until you get to that element.Linked lists are fast for inserts and deletes anywhere in the list, since all you do is update a few next and previous pointers of a node. Each element of a linked list (especially a doubly linked list) uses a bit more memory than its equivalent in array list, due to the need for next and previous pointers.
Ok. Cool...Now that the fundamentals are clear, let's conclude on when to use what:
Here is a snippet from SUN's site.
The Java SDK contains 2 implementations of the List interface - ArrayList and LinkedList.
If you frequently add elements to the beginning of the List or iterate over the List to delete elements from its interior, you should consider using LinkedList. These operations require constant-time in a LinkedList and linear-time in an ArrayList. But you pay a big price in performance. Positional access requires linear-time in a LinkedList and constant-time in an ArrayList.
Here are a few more links that give interesting perspectives:
http://www.javaspecialists.co.za/archive/Issue111.html
http://joust.kano.net/weblog/archives/000066.html
http://soft.killingar.net/documents/LinkedList+vs+ArrayList
http://jira.jboss.com/jira/browse/JBXB-65
Some basics first:
An arraylist used an array for internal storage. This means it's fast for random access (e.g. get me element #999), because the array index gets you right to that element. But then adding and deleting at the start and middle of the arraylist would be slow, because all the later elements have to copied forward or backward. (Using System.arrayCopy())
ArrayList would also give a performance issue when the internal array fills up. The arrayList has to create a new array and copy all the elements there. The ArrayList has a growth algorithm of (n*3)/2+1, meaning that each time the buffer is too small it will create a new one of size (n*3)/2+1 where n is the number of elements of the current buffer. Hence if we can guess the number of elements that we are going to have, then it makes sense to create a arraylist with that capacity during object creation (using the overloaded construtor or ArrayList)
LinkedList is made up of a chain of nodes. Each node stores an element and the pointer to the next node. A singly linked list only has pointers to next. A doubly linked list has a pointer to the next and the previous element. This makes walking the list backward easier.
Linked lists are slow when it comes to random access. Gettting element #999 means you have to walk either forward from the beginning or backward from the end (depending on whether 999 is less than or greater than half the list size), calling next or previous, until you get to that element.Linked lists are fast for inserts and deletes anywhere in the list, since all you do is update a few next and previous pointers of a node. Each element of a linked list (especially a doubly linked list) uses a bit more memory than its equivalent in array list, due to the need for next and previous pointers.
Ok. Cool...Now that the fundamentals are clear, let's conclude on when to use what:
Here is a snippet from SUN's site.
The Java SDK contains 2 implementations of the List interface - ArrayList and LinkedList.
If you frequently add elements to the beginning of the List or iterate over the List to delete elements from its interior, you should consider using LinkedList. These operations require constant-time in a LinkedList and linear-time in an ArrayList. But you pay a big price in performance. Positional access requires linear-time in a LinkedList and constant-time in an ArrayList.
Here are a few more links that give interesting perspectives:
http://www.javaspecialists.co.za/archive/Issue111.html
http://joust.kano.net/weblog/archives/000066.html
http://soft.killingar.net/documents/LinkedList+vs+ArrayList
http://jira.jboss.com/jira/browse/JBXB-65
Monday, September 11, 2006
Info about Credit Cards
There are always new wonderful things that U learn - things that never caught Ur attention.
I found out a few interesting things about credit card numbers recently.
Did U know that all VISA/MasterCard credit card numbers start with "4" ???
Did U know that it is possible to do basic validation of a credit card number without even hitting any database ???
For more such interesting things about Credit cards, follow these links:
http://www.merriampark.com/anatomycc.htm
http://euro.ecom.cmu.edu/resources/elibrary/everycc.htm
I found out a few interesting things about credit card numbers recently.
Did U know that all VISA/MasterCard credit card numbers start with "4" ???
Did U know that it is possible to do basic validation of a credit card number without even hitting any database ???
For more such interesting things about Credit cards, follow these links:
http://www.merriampark.com/anatomycc.htm
http://euro.ecom.cmu.edu/resources/elibrary/everycc.htm
Reload of Struts-config file
In earlier versions of Struts (v1.0), there was a ReloadAction that allowed us to reload the struts-config file from disk without reloading the web application or restarting the server.
But since Struts 1.1, this Action was removed. So it was no longer possible to reload the struts-config file using any in-built capabilities. I could not understand why this had been done. Finally a post by Craig R. McClanahan (founder of Struts) resolved all doubts:
ReloadAction is not supported in 1.1 for two reasons:
* It never did let you reload everything that you would really want to -- particularly changed classes -- so many people ended up having to reload the webapp anyway.
* Not supporting ReloadAction lets Struts avoid doing synchronization locks around all the lookups (like figuring out which action to use, or the detination of an ActionForward) so apps can run a little faster.
But under ordinary conditions, if we reload the webapp, then all sessions are lost - atleast that's what I thought; but I was wrong. Looks like the session is kept alive, but all session objects are destroyed unless they implement the 'Serializable' interface. I found this out from another post of Craig.
You can avoid webapp reload problems (which will likely be requiredfor *any* server, not just Tomcat) by following a couple of simple rules:
* For session attributes, make sure that they implement java.io.Serializable (and that any classes used in instance variables are also Serializable). Tomcat 4+, at least, will save and restore these sessions and their attributes for you.
* For context attributes, make sure that your webapp startup procedures properly restore anything that needs to be there. For a servlet 2.3 or later container, the proper way to do this is with a class that implements ServletContextListener, regsitered in a element in your web.xml file.
Proper application architecture will avoid any reloadability problems.
But since Struts 1.1, this Action was removed. So it was no longer possible to reload the struts-config file using any in-built capabilities. I could not understand why this had been done. Finally a post by Craig R. McClanahan (founder of Struts) resolved all doubts:
ReloadAction is not supported in 1.1 for two reasons:
* It never did let you reload everything that you would really want to -- particularly changed classes -- so many people ended up having to reload the webapp anyway.
* Not supporting ReloadAction lets Struts avoid doing synchronization locks around all the lookups (like figuring out which action to use, or the detination of an ActionForward) so apps can run a little faster.
But under ordinary conditions, if we reload the webapp, then all sessions are lost - atleast that's what I thought; but I was wrong. Looks like the session is kept alive, but all session objects are destroyed unless they implement the 'Serializable' interface. I found this out from another post of Craig.
You can avoid webapp reload problems (which will likely be requiredfor *any* server, not just Tomcat) by following a couple of simple rules:
* For session attributes, make sure that they implement java.io.Serializable (and that any classes used in instance variables are also Serializable). Tomcat 4+, at least, will save and restore these sessions and their attributes for you.
* For context attributes, make sure that your webapp startup procedures properly restore anything that needs to be there. For a servlet 2.3 or later container, the proper way to do this is with a class that implements ServletContextListener, regsitered in a
Proper application architecture will avoid any reloadability problems.
Tuesday, August 15, 2006
Using java.ext.dirs to ease setting classpath
If U are in a hurry to compile code and there is a big list of Jar files to include in the classpath, there U don't have to struggle to include the names of all the jar's in the classpath.
There is a neat trick - use the "java.ext.dirs" JVM param to point to the directory containing the jar files.
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes MyJavaClass
There is a neat trick - use the "java.ext.dirs" JVM param to point to the directory containing the jar files.
java -Djava.ext.dirs=c:\java\axis-1_1\lib -classpath classes MyJavaClass
Prevent web images from being saved.
Many novice web-developers struggle with the idea of preventing users from stealing the images present on a HTML page.
The truth is that it is impossible to prevent the user from saving the images on a HTML page.
We can watermark them and prove that they belong to us and enter comments that say this in clear text, but it still doesn't keep people from issuing an HTTP request and saving the image.
The truth is that it is impossible to prevent the user from saving the images on a HTML page.
We can watermark them and prove that they belong to us and enter comments that say this in clear text, but it still doesn't keep people from issuing an HTTP request and saving the image.
Funny thing about URL's
Recently after years of web-programming I noticed a subtle thing.
Whenever we make a request for a website, say http://narencoolgeek.blogspot.com, the URL in the browser changes to http://narencoolgeek.blogspot.com/ . (Notice the forward slash at the end of the URL)
I put in a sniffer to see what is exactly happening. The server on receiving the first URL sends a 301/302 (temporary moved) response redirecting the client to the new URL. Why is this necessary? Maybe some legacy reason, or maybe this is necessary to pick up the default page of the website directory.
Whenever we make a request for a website, say http://narencoolgeek.blogspot.com, the URL in the browser changes to http://narencoolgeek.blogspot.com/ . (Notice the forward slash at the end of the URL)
I put in a sniffer to see what is exactly happening. The server on receiving the first URL sends a 301/302 (temporary moved) response redirecting the client to the new URL. Why is this necessary? Maybe some legacy reason, or maybe this is necessary to pick up the default page of the website directory.
Sorting objects in a Java collection
We all have felt the need to sort our custom objects based on the value of ainstance varaible of that object..For e.g. sorting of a Vector of AddressCard objects according to theDisplayName.i.e Consider the following class:
class AddressCard{ public String sDisplayName; // Other instance variables.}
Now say we want to sort a Vector of AddressCard objects according to the valueof sDisplayName.Though we can write a custom sorting mechanism for this, we have another neatsolution which requires miminal coding.We make use of the TreeMap object as follows, which is sorted internally..Given below is the code snippet.
//Instantiate a TreeMap object....If Case sensitive is desired, use a emptyconstructor.
TreeMap tMap = new TreeMap(String.CASE_INSENSITIVE_ORDER);
//keep on adding the object's field (to be sorted) as the key and the object reference as the value.
for loop:
tMap.put(sDisplayName, AddressCardObject);
//-------------------end of for loop
Once all the objects have been entered into the TreeMap, they are sorted automatically..So if U want the sorted Vector ofobjects then just do the following:
Collection c = tMap.values();
Vector v = new Vector(c); //Pass the collection in the constructor.
And Voila !!!....we have a sorted Vector of objects sorted according to therequired field...and that too in just 4-5 lines of code.
class AddressCard{ public String sDisplayName; // Other instance variables.}
Now say we want to sort a Vector of AddressCard objects according to the valueof sDisplayName.Though we can write a custom sorting mechanism for this, we have another neatsolution which requires miminal coding.We make use of the TreeMap object as follows, which is sorted internally..Given below is the code snippet.
//Instantiate a TreeMap object....If Case sensitive is desired, use a emptyconstructor.
TreeMap tMap = new TreeMap(String.CASE_INSENSITIVE_ORDER);
//keep on adding the object's field (to be sorted) as the key and the object reference as the value.
for loop:
tMap.put(sDisplayName, AddressCardObject);
//-------------------end of for loop
Once all the objects have been entered into the TreeMap, they are sorted automatically..So if U want the sorted Vector ofobjects then just do the following:
Collection c = tMap.values();
Vector v = new Vector(c); //Pass the collection in the constructor.
And Voila !!!....we have a sorted Vector of objects sorted according to therequired field...and that too in just 4-5 lines of code.
Why execute() replaced perform() in Struts
Recently a friend of mine asked me why the "perform()" method in Struts was replaced with the "execute()" method?
A closed look at the signatures of the two methods revealed that the "execute()" method throws java.lang.Exception whereas the old "perform()" method throws IOException and ServletException.
This new execute method was necessary because of this reason. Due to the declarative exception handling that has been added,the framework needs to catch all instances of java.lang.Exception from theAction class.
Instead of changing the method signature for the perform() method and breakingbackwards compatibility, the execute() method was added.
Currently, the execute() method just turns around and invokes the perform() method anyway.
A closed look at the signatures of the two methods revealed that the "execute()" method throws java.lang.Exception whereas the old "perform()" method throws IOException and ServletException.
This new execute method was necessary because of this reason. Due to the declarative exception handling that has been added,the framework needs to catch all instances of java.lang.Exception from theAction class.
Instead of changing the method signature for the perform() method and breakingbackwards compatibility, the execute() method was added.
Currently, the execute() method just turns around and invokes the perform() method anyway.
Thursday, July 27, 2006
Diff btw Cache and History in Browsers
Cache is the segment of the physical hard-disk that stores the web resources that we browse.
For IE, the folder for cache is "Temporary Internet Files"
History is just a stack of URL's that the user has visited (For a number of days). The state of the page is not stored in History. If U open IE options dialog box, then U will see different settings for Temporary Internet Files and History.
So what happens when the user presses the back button?
The browser uses a stack (History) to remember visited pages. Each time a link is followed, or the user gives an URL to retrieve, the browser will push the current URL on its stack. If the user selects the back function of his browser, the browser will go to the document whose URL is saved on the top of the stack (if the stack is non empty) and will pop the URL from the stack.
If the URL resource can be obtained from the cache, then the browser does so, otherwise a fresh request is made.
Hence even if we disable cache thru response headers, the user can still click back and reload the page from the server. But the current state on the server may not be 'ready' for that request.
There are many strategies that can be used to disable back: Remove the top bar of the browser thru javascript, write a javascript function that will get executed on page load and reset the history stack etc.
On the server side, we can use the "Synchronizer Token pattern"
For IE, the folder for cache is "Temporary Internet Files"
History is just a stack of URL's that the user has visited (For a number of days). The state of the page is not stored in History. If U open IE options dialog box, then U will see different settings for Temporary Internet Files and History.
So what happens when the user presses the back button?
The browser uses a stack (History) to remember visited pages. Each time a link is followed, or the user gives an URL to retrieve, the browser will push the current URL on its stack. If the user selects the back function of his browser, the browser will go to the document whose URL is saved on the top of the stack (if the stack is non empty) and will pop the URL from the stack.
If the URL resource can be obtained from the cache, then the browser does so, otherwise a fresh request is made.
Hence even if we disable cache thru response headers, the user can still click back and reload the page from the server. But the current state on the server may not be 'ready' for that request.
There are many strategies that can be used to disable back: Remove the top bar of the browser thru javascript, write a javascript function that will get executed on page load and reset the history stack etc.
On the server side, we can use the "Synchronizer Token pattern"
More on Cookies
Found a few new things about cookies :)
What is the difference between a third-party cookie and a first-party cookie?
If you connect to Web site A and it sets a cookie, that's a first-party cookie. If an ad, embedded within site A is coming from site B, and the ad sets a cookie, that would be a third-party cookie.
What is the difference between persistent and session cookies?
Persistent cookies are cookies that "persist" or reside on your system even after you have closed your browser. Such cookies contain information that can be used to personalize your experience for a particular web site the next time you visit it. Examples would be online community and discussion boards. Unfortunately, such information could also be gathered by hackers and malicious programs and disclose your personal information.
Session cookies are cookies that exist only for a particular "session" or logon. These cookies are deleted automatically the moment you close your browser or choose logout/exit from the web site. Examples would be online banking services. Such cookies are usually safe as they are automatically deleted from your system the moment you exit from the sites.
Persistent and session cookies differ as their life span and lifetime are different.
What is the difference between a third-party cookie and a first-party cookie?
If you connect to Web site A and it sets a cookie, that's a first-party cookie. If an ad, embedded within site A is coming from site B, and the ad sets a cookie, that would be a third-party cookie.
What is the difference between persistent and session cookies?
Persistent cookies are cookies that "persist" or reside on your system even after you have closed your browser. Such cookies contain information that can be used to personalize your experience for a particular web site the next time you visit it. Examples would be online community and discussion boards. Unfortunately, such information could also be gathered by hackers and malicious programs and disclose your personal information.
Session cookies are cookies that exist only for a particular "session" or logon. These cookies are deleted automatically the moment you close your browser or choose logout/exit from the web site. Examples would be online banking services. Such cookies are usually safe as they are automatically deleted from your system the moment you exit from the sites.
Persistent and session cookies differ as their life span and lifetime are different.
Subscribe to:
Posts (Atom)