Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Tuesday, September 07, 2010

404! Why? Where from?

Alright, so you got 404'd! Things aren't that bad because you handled it nicely, but the real question you have on the tip of your tongue is "What URL caused this 404?"

The request could receive the following attributes that can indicate what caused the error

Where did it come from?

To get the original URL of the request that is in trouble, look at javax.servlet.error.request_uri request attribute.

String uri = (String) request.getAttribute("javax.servlet.error.request_uri");

What caused it?

To cause of the error can be a HTTP error or an exception that was not handled by the web application and propagated all the way up. The three attributes that will give you more insight are:


  • javax.servlet.error.status_code:
    An Integer telling the error status code, if any
  • javax.servlet.error.exception_type:
    A Class instance indicating the type of exception that caused the error, if any
  • javax.servlet.error.message:
    A String telling the exception message, passed to the exception constructor
  • javax.servlet.error.exception:
    A Throwable object that is the actual exception thrown

Handling HTTP 404 - Page Not Found

If you develop web applications, you are most likely familiar with Java Servlets and Java Server Pages (JSP). JSPs can be accessed by a path that directly relates to their relative location to the web app's content root directory. Servlets however are typically accessed via path that match URL patterns defined for each servlet in the servlet mapping element of the deployment descriptor (web.xml).

What happens if a user types in a URL that will reach your web application, but does not map to to any of your servlets nor JSPs? Most likely this occurrence will be handler by the servlet container itself by sending HTTP 404 code back to the user's browser. A 404 page will be displayed. 404 is a HTTP response status code that indicates that a resource could not be found but may be available again in the future. Most of the servlet containers do not serve user-friendly 404 pages.

You are better off handling 404 by the web application itself. The content of the 404 page can be then customized to suit your web application's needs. You could take a funny approach or present something more helpful, e.g. a sitemap.

Example from YOU & I tee - couple t-shirts:
404 Page Not Found

So how do we do this?

Step 1 - Create error page description

Add an error-page element to your web applications deployment descriptor. Open web.xml file and add a section like the following:

<error-page>
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>

Step 2 - Create error JSP

At the location as specified in step 1 create a new JSP file that will serve the content you desire. And that's it really.

Handling exceptions

In a similar fashion you can handle uncaught exceptions that would otherwise end up in the user's browser. For example:

<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/exception.jsp</location>
</error-page>

Sunday, June 27, 2010

JavaZone Trailer: Java 4-ever

This is an absolutely awesome movie trailer!

...from the director of JAVATAR and .NOT


Monday, May 03, 2010

How to wire a constant in Spring

Spring is a great framework for dependency injection. It helps creating new instances and inject them with references to other objects via constructor arguments or setter methods.

To create a new instance of a class one simply declares a new bean

<bean id="firstDay" class="com.mypackage.Day">
<constructor-arg type="java.lang.Integer" value="1" />
</bean>

But what if you do not want to create a new instance. Perhaps you already have a class with instances declared as publicly accessible constants (public static) and you just want to access them in the wiring process.

It's easy to get a hold of a constant. Simply use the following

<util:constant id="firstDay" static-field="com.mypackage.Day.MONDAY"/>

For this to work you'll need to include the following

<beans
xmlns="http://www.springframework.org/schema/beans"
...
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util ..."
>

So there you go, now you have constants wired.

Thursday, July 30, 2009

Detect an AJAX request

Many web applications use AJAX nowadays. In a typical scenario, one fills out a form, which is then submitted to the server. If you don't use AJAX or JavaScript is disabled, your form should still submit with no problems. And you receive a new page. If you use unobtrusive enhancement via JavaScript, the form is submitted to the server and the page is updated with the result without a full page reload.

While developing with Grails writing Java and Groovy code, I noticed that a typical pattern is to create two actions in a controller. One to handle normal HTTP POST (e.g. save action) and one to handle HTTP POST coming from an AJAX request (e.g. saveAjax action). The two actions are almost identical. They perform the same business logic. The only difference is what is returned from each action. A normal action renders a new page. An AJAX one returns whatever your flavor is: XML, JSON, HTML, plain text.

So is there a way to tell the requests (ordinary and AJAX) apart?

You guessed it, there is. AJAX request comes with a special header - X-Requested-With. I usually have my controllers to extend my BaseController, which has a couple of useful methods that I use. isAjax(request) is one of them. And this is what it looks like.


public static boolean isAjax(request) {
return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
}

I hope you'll find it useful. The all you need to do in your action is this:


def save = {

// business logic
// ...

if (isAjax(request)) {
render([ /* data */ ] as JSON)
}
else {
// render or redirect here
render(view: 'save', model: [ /* model data */ ])
}
}

Friday, December 05, 2008

Easy Groovy Iteration

The problem

Let's say we want to check the correct mimetype and file extension of the file being uploaded. In a typical Java way I would write something like this:

boolean isRightType = "image/jpeg".equals(contentType)
|| "image/png".equals(contentType)
|| "image/x-png".equals(contentType);

boolean isRightFileExt = filename.endsWith(".png")
|| filename.endsWith(".jpg")
|| filename.endsWith(".jpeg");

Groovy solution

The Groovy way is much simpler and more elegant.

private static CONTENT_TYPES = ["image/jpeg", "image/png", "image/x-png"]
private static FILE_EXTENTIONS = [".png", ".jpg", ".jpeg"]
...
boolean isRightType = CONTENT_TYPES.any { it.equals(contentType) }
boolean isRightFileExt = FILE_EXTENTIONS.any { filename.endsWith(it) }

This was just a small example. What I really find useful are some of the following constructs that make my programming life really pleasant

Groovy Iteration

each

Simple collection iteration

def fibList = [1, 1, 2, 3, 5, 8, 13]
fibList.each { println it } // prints all of the numbers in the list

any

If you need to find out if any element of the collection meets the condition.

def fibList = [1, 1, 2, 3, 5, 8, 13]
assert fibList.any { it == 3 }
assert fibList.any { it - 2 > 10 }

This is pretty much equivalent to a Java construct

boolean any(List list, Condition cond)
for (E e : list) {
if (cond.meets(e)) {
return true;
}
}
return false;
}

every

If you need to find out if any element of the collection meets the condition.

def fibList = [1, 1, 2, 3, 5, 8, 13]
assert fibList.every { it > 0 }

This is pretty much equivalent to a Java construct

boolean every(List list, Condition cond)
for (E e : list) {
if (!cond.meets(e)) {
return false;
}
}
return true;
}

collect

If you need to create a new collection that contains each element of the original collection transformed in some way.

def fibList = [1, 1, 2, 3, 5, 8, 13]
assert fibList.collect { it - 1 } == [0, 0, 1, 2, 4, 7, 12]

This is pretty much equivalent to a Java construct

List every(List list, Command command)
List result = new ArrayList(list.size());
for (E e : list) {
result.add(command(e));
}
return result;
}

findAll

If you need to create a new collection that contains all elements that meet the condition.

def fibList = [1, 1, 2, 3, 5, 8, 13]
assert fibList.findAll { it > 1 && it < 5 } == [2, 3]

This is pretty much equivalent to a Java construct

List findAll(List list, Condition cond)
List result = new ArrayList(list.size());
for (E e : list) {
if (!cond.meets(e)) {
result.add(e);
}
}
return result;
}

find

If you need to find first element that matches the condition.

def fibList = [1, 1, 2, 3, 5, 8, 13]
assert fibList.find { it > 1 } == 2

This is pretty much equivalent to a Java construct

E findAll(List list, Condition cond)
for (E e : list) {
if (!cond.meets(e)) {
return e;
}
}
return null;
}

References

Sunday, August 31, 2008

How to get the server's timezone

The problem

How to get the server's timezone display name correctly and display it to the user in his locale.

server's default timezone

Firstly, you need to get the server's default timezone. This is easily achieved by the following call

final TimeZone timeZone = TimeZone.getDefault();

use daylight time?

Secondly, you need to find out if this timezone uses daylight time. This is important as some timezones change their names during daylight saving. Don't use the TimeZone.useDaylightTime() method

//final boolean daylight = timeZone.useDaylightTime();

This method works fine only for systems where the timezone never changes. If the administrator changes the time on the server, this change won't be reflected in subsequent calls. What you need to do instead, is to find out is the daylight savings is on right now.

final boolean daylight = timeZone.inDaylightTime(new Date());

user's locale

The last important step is to get the right locale, the locale you want this timezone name to display in. You could call Locale.getDefault(), but this returns server's default locale. You want the locale that the user is using. In a web application, the user's locale can be obtained from getLocale() method of ServletRequest object.

final Locale locale = servletRequest.getLocale();

final step - timezone display name

Now we can call getDisplayName method with all required parameters.

return timeZone.getDisplayName(daylight, TimeZone.LONG, locale);

Solution

To put this all together, the final solution may look like this method

private String getServerTimeZoneDisplayName()
{
final TimeZone timeZone = TimeZone.getDefault();
final boolean daylight = timeZone.inDaylightTime(new Date());
final Locale locale = servletRequest.getLocale();
return timeZone.getDisplayName(daylight, TimeZone.LONG, locale);
}

References

Monday, August 27, 2007

Java Puzzlers, Episode 6

I am a big fan of Java Puzzlers.

Another part of the Java Puzzler series appeared on Google Video couple days ago. This is one named Advanced Topics in Programming Languages: Java Puzzlers, Episode VI and is a repeat of a talk given at Google in May and at JavaOne 2007.

Josh Bloch and special guest star Bill Pugh present yet another installment in the continuing saga of Java Puzzlers, consisting of eight more programming puzzles for your entertainment and enlightenment.

I really enjoyed watching it and also learnt a thing or two.

Funny thing was when Bill Pugh said in the conclusion:

Use FindBugs: it finds all 8 bugs in this talk!

I use FindBugs everyday and I have to tell you, our codebase (JIRA) is quite clean and FindBugs helps us to keep it that way.

Alright! Enough said. Go on! Watch it!

Related posts: Java Puzzlers

Sunday, August 26, 2007

Contract of the interfaces

As I mentioned in my previous post titled Don't test everything, unit testing is very valuable in the software development process, but on some occasions the test expects more that it should. In some cases those expectation work fine, in other they fail.

What the hell am I talking about? If you follow the good practice of coding against interfaces, you know that the interface defines the contract all implementation classes must adhere to. If you write an implementation of an interface your unit tests should test possibly everything that this contract specifies and nothing more.

Take a Set from Java Collections Framework for example. This interface is defined as:

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.

At some point I had a unit test that had some input values and my test was assuming the correct results in the set that was returned. I knew that my implementation wa returning a HashSet and I also knew what was in that set. The asserts were quite simple (the code is simplified):

String[] addresses = new String[] {"address1", "address2", "address3"};
Set set = new HashSet(Arrays.asList(addresses));
Iterator i = set.iterator();
assertEquals("address1", i.next());
assertEquals("address2", i.next());
assertEquals("address3", i.next());

It's a good test, you may think. Well, it isn't! This test runs or fails depending on which JDK you use. The problem with this test is that it assumes the order of the elements in the returning set. Set interface does not guarantee the order of its elements. We should not test that.

Let's have a look at the following unit test

import junit.framework.TestCase;

import java.util.Set;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;

public class TestJdkDiff extends TestCase
{
    public void testOrder()
    {
        String javaVersion = System.getProperty("java.version");
        String javaVendor = System.getProperty("java.vendor");
        System.out.println("Running " + javaVendor + " " + javaVersion);

        String[] addresses = new String[] {"address1", "address2", "address3"};
        final Set set = new HashSet(Arrays.asList(addresses));
        for (Iterator i = set.iterator(); i.hasNext();)
        {
            System.out.println(i.next());
        }
    }
}

Execution of the previous test on Java 6 produces the following output

Running Sun Microsystems Inc. 1.6.0_02
address1
address2
address3

The same test executed on Sun's JVM 1.4 prints out

Running Sun Microsystems Inc. 1.4.2_12
address2
address3
address1

Oops! Now I know why my test failed. Even, in JDK the implementation of some classes can change from time to time. As long as the contact is kept all should be fine.

So to fix my initial test one should write

String[] addresses = new String[] {"address1", "address2", "address3"};
Set set = new HashSet(Arrays.asList(addresses));
assertEquals(3, set.size());
assertTrue(set.contains("address1"));
assertTrue(set.contains("address2"));
assertTrue(set.contains("address3"));

Happy coding!

Thursday, August 16, 2007

Keep it simple

Recently I saw pieces of code that could be simplified. I see such code often, however, recently I came across code that seemed to follow the same pattern

The patern was as in the following example:


private boolean someFlag;

...

public boolean isSomeFlagSet() {
if (someFlag) {
return true;
}
else {
return false;
}
}

Why not simply write:


public boolean isSomeFlagSet() {
return someFlag;
}

It is so much simpler!

Similarly to boolean flags, there where occurencies of other object types being used and methods invoked on them in the following manner:


public String getCity() {
if (address == null) {
return null;
}
else {
return address.getCity();
}
}

This can be also simplified (applying "change if-else to ?:" refactoring) to:


public String getCity() {
return address == null ? null : address.getCity();
}

Please strive for simplicity in your code (K.I.S.S. principle). Verbosity clutters the code and can hide the meaning or intention of it.

Sunday, August 12, 2007

ArithmeticException vs. NaN

Recently I worked on a small UI widget that renders bars that represent percentage. The percentage could be calculated by a simple formula such as the following:

percentage = value / total * 100%

Imagine a utility method that calculates the percentage and looks like the following:

public static int calcPercentage(int value, int total) {
return 100 * value / total;
}

You could say that this is a fairly simple method and would not be that hard to unit test it. Assuming that the given parameters will never be negative numbers one could whip up a sample test values very quickly.

public void testCalPercentage() {
assertEquals(0, calcPercentage(0, 2));
assertEquals(33, calcPercentage(1, 2));
assertEquals(50, calcPercentage(2, 2));
}

Take a bunch of positive numbers or zeros... Wait! Zeros?! But there could be a possible division by zero! That's right! There is our edge case. Let's test it! Aha! We now get an ArithmeticException.

public void testCalPercentageDivisionByZero() {
try {
assertEquals(0, calcPercentage(0, 0));
fail();
}
catch (ArithmeticException ex) {
// expected
}
}

That's understandable. So we need to work around this and the bar should not be rendered if not values (zeros) were entered.

And here comes the twist! Change the type of spent and remaining variables from primitive int to primitive float.

public static int calcPercentage(float value, float total) {
return (int) (100 * value / total);
}

No exception is thrown anymore. What happened? Why such a different behavior?

It all boils down to how Java and other programming languages handle float point arithmetic. I hope that the following quote sums it all.

Floating-point numbers in the JVM use a radix of two. Floating-point numbers in the JVM, therefore, have the following form:

sign * mantissa * 2 exponent

The mantissa of a floating-point number in the JVM is expressed as a binary number. A normalized mantissa has its binary point (the base-two equivalent of a decimal point) just to the left of the most significant non-zero digit. Because the binary number system has just two digits -- zero and one -- the most significant digit of a normalized mantissa is always a one.

The most significant bit of a float or double is its sign bit. The mantissa occupies the 23 least significant bits of a float and the 52 least significant bits of a double. The exponent, 8 bits in a float and 11 bits in a double, sits between the sign and mantissa. The format of a float is shown below. The sign bit is shown as an "s," the exponent bits are shown as "e," and the mantissa bits are shown as "m":

Bit layout of Java float
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm

The exponent field is interpreted in one of three ways. An exponent of all ones indicates the floating-point number has one of the special values of plus or minus infinity, or "not a number" (NaN). NaN is the result of certain operations, such as the division of zero by zero. An exponent of all zeros indicates a denormalized floating-point number. Any other exponent indicates a normalized floating-point number.

The JVM throws no exceptions as a result of any floating-point operations. Special values, such as positive and negative infinity or NaN, are returned as the result of suspicious operations such as division by zero. An exponent of all ones indicates a special floating-point value. An exponent of all ones with a mantissa whose bits are all zero indicates an infinity. The sign of the infinity is indicated by the sign bit. An exponent of all ones with any other mantissa is interpreted to mean "not a number" (NaN). The JVM always produces the same mantissa for NaN, which is all zeros except for the most significant mantissa bit that appears in the number. These values are shown for a float below:

Special float values
ValueFloat bits (sign exponent mantissa)
+Infinity0 11111111 00000000000000000000000
-Infinity1 11111111 00000000000000000000000
NaN1 11111111 10000000000000000000000


Things like these we learn when we learn computer programming and tend to forget over time. And then... a simple percentage calculation will remind us.

Happy coding!

Sunday, April 22, 2007

People still don't get String comparison

How many times we have seen String comparison done using == or != operators?! Yet, people still get it wrong.

I have seen some blog posts recently where the authors had a good intention to show a case where hard-coding values went wrong. Unfortunately, they fell into the common mistake of comparison of String references.

So, if you really need to compare two String using == or != make sure you call String.intern() method before making comparison. Otherwise, always prefer String.equals(String) for String comparison.

Fail-fast vs. complete validation

Almost all applications work with data that come from the interaction with humans or other applications. These data, however, may not necessarily meet the requirements of the accepting applications. Data must be validated.

What is validation?

Data entered must pass a set of validation rules in order to be recognized as valid and allowed for further processing.

As an example, lets take a class that has three members: name:String, created:Date and total:int. Our application requires that name is set (not null) and has at least three characters; created is also required and must be a date representing time before now; and total must be a non-negative integer.

There are two common approaches to data validation: fail-fast validation and complete validation.

Fail-fast validation

How it works

If any of the validation rules fails, validation is stopped and data is pronounced invalid and rejected for further processing.

Output

Boolean result that indicates the validity of input data: true for valid, false for invalid.

Pros

It is generally faster than complete validation as first failure terminates the execution of consecutive validation rules. Does not have the over of failure cause reporting.

Cons

Does not provide enough information about the cause of failure.

When to use it

If a simple result: true or false is enough; detailed information about the cause of failure is not required. May be suitable for cases when the source of data cannot correct the data (usually a system without human input).

Example

boolean isValid(String name, Date created, int total)

Data is passed in and boolean result is returned.

Complete validation

How it works

Failure of a validation rule does not stop the validation process. Data is marked as invalid and rejected for further processing after completing whole validation process.

Output

Boolean result that indicates the validity of input data: true for valid, false for invalid. Some form of error collection that contains the information about the causes of validation failure.

For examples see ActionMessages class from Struts framework, Errors class from Spring framework or ErrorCollection class in Atlassian JIRA.

Pros

Provides information about the cause or causes of validation failure. This information can provide the necessary feedback for correcting the input data.

Cons

Slower than fail-fast validation as extra information about causes of validation failure are reported and full set of validation rules is executed independently on the validation result.

When to use it

When a complete set of failure causes is required. The causes of failure may provide hints to the user entering the data about how to correct the data.

Example

void validate(String name, Date created, int total, ErrorCollection errorCollection)

Data is passed in along with the error collection. Method does not have to return anything (void) as invalid data is indicated by the presence of errors in the error collection.

Conclusion

If the complex validation rule set can be broken down into separate validations per input field, these can be used in order to enhance the user experience (via JavaScript or AJAX) – they can provide a real-time feedback for the data being entered.

Also consider that some cases can involve several other input values in order to make a decision about validity of input data. Such case can for example be a single date value consisting on the values from three input fields (don't do this, it's not a really good way of entering dates)

or conditionally required fields, such as the text area in the next picture is only required to be filled in if "other" is selected.

Both types of validation serve their purpose. Which one you decide to use depends mostly on how much information about data being validated you really need in order to make a decision or to correct it in case of failure.

Tuesday, February 27, 2007

toString() and primitive values

How can one convert a primitive value such as integer or boolean to String object?

Well, there are many ways. There is one way that I have seen so many times:

String strValue = new Integer(intValue).toString();

or

String strValue = new Boolean(booleanValue).toString();

Similarly new instance can be created and the toString() method invoked on classes such as Integer, Long, Float, Double, Byte, Short and Boolean.

The problem is that a boxed primitive is allocated just to call toString() method on it. Each time this is executed, a new instance, new object is created. However, object creation is not necessary and can be avoided. Creating object just for one method call is highly inefficient as the object can be garbage collected on the consecutive line.

The solution

It is more efficient to use the static form of toString() method, which takes the primitive value as a parameter.

String strValue = Integer.toString(intValue);

or

String strValue = Boolean.toString(booleanValue);

Side note

...and please don't do the following

Integer number = ...
String strValue = Integer.toString(number.intValue());

If you already have an instance of integer wrapper class, simply call

String strValue = number.toString();

Thursday, February 22, 2007

Log4J Logger vs. Category

Logging is the practice of recording sequential data. This is also a low-tech method of debugging and in some cases also the only way as the proper debugging tools may not be always available or applicable. Logging in Java can range from simple System.out.println() statements to usage of sophisticated logging frameworks.

At the time of writing there are several logging frameworks for logging in Java available. There is a popular and probably the most widely used Log4J framework. Younger brother of Log4J is the Java's Logging API that became part of Java SE in version 1.4. See How does the Java logging API stack up against log4j for comparison. The are many other logging frameworks: SimpleLog, jLo, Protomatter Syslog, etc.

There are also several frameworks that enable abstraction from logging frameworks, also known as logging bridges (Apache Commons Logging, log-bridge). These allow switching between logging frameworks. These and many others can be found at Open Source Logging Tools in Java at java-source.net.

Log4J was one of the early logging frameworks that gained popularity and is present in many source code bases. In some cases you could encounter usage of Category class rather than Logger. If you work or worked on projects that are built on top of relatively young frameworks, you may not even know that Category class exists as its natural habitat is in old Java code. I hadn't known that Category class existed until I saw it one day. I saw it in a place where I would usually use Logger class. Since that day I kept reminding myself to look at it and see what's different from Logger class and why would one use it.

So what is the difference between Category and Logger classes? The Java documentation in Category class states

This class has been deprecated and replaced by the Logger subclass. It will be kept around to preserve backward compatibility until mid 2003.

Logger is a subclass of Category, i.e. it extends Category. In other words, a logger is a category. Thus, all operations that can be performed on a category can be performed on a logger. Internally, whenever log4j is asked to produce a Category object, it will instead produce a Logger object. Log4j 1.2 will never produce Category objects but only Logger instances. In order to preserve backward compatibility, methods that previously accepted category objects still continue to accept category objects.

Then the following example shows how Category was used and how Logger should be used.

// Deprecated form:
Category cat = Category.getInstance("foo.bar");

// Preferred form for retrieving loggers:
Logger logger = Logger.getLogger("foo.bar");

And that's it. That's all you have to do to replace Category with Logger (apart from renaming the variable).

The documentation also says

There is absolutely no need for new client code to use or refer to the Category class. Whenever possible, please avoid referring to it or using it.

Why is this important? The plan is that from Log4J version 1.3 Category class will be removed! What can we do to prepare our code for Log4J 1.3? Well Preparing for Log4J version 1.3 has it all spelled out. It's worth to read if you want to understand all implications this upgrade may have. I just shamelessly paste the steps here:

  1. Never refer to the Category class directly, refer to Logger instead.
  2. Do not invoke the deprecated Category.getRoot method. Invoke Logger.getRootLogger method instead.
  3. Do not invoke the deprecated Category.getInstance(String) method. Invoke Logger.getLogger(String) method instead.
  4. Do not invoke the deprecated Category.getInstance(Class) method. Invoke Logger.getLogger(Class) method instead.
  5. Never refer to the Priority class, refer to Level class instead.
  6. Do not invoke the deprecated Category.setPriority(Priority) method. Invoke Logger.setLevel(Level) method instead.
  7. Do not invoke the deprecated Priority.toPriority(int) method. Invoke Level.toLevel(int) method instead. The same holds true for the other variants of the Priority.toPriority method.
  8. Never refer to the deprecated Priority.FATAL, Priority.ERROR, Priority.WARN, Priority.INFO, Priority.DEBUG fields. Refer to the Level.FATAL, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG fields instead.

  9. If you confiugure appenders programmatically, do not forget to invoke the activateOptions method of an appender after you have instantiated it and set its options.

and as the above mentioned document says

For 99.99% of users, this translates to the following string find-and-replace operations:
  1. Replace the string "Category.getInstance" with the string "Logger.getLogger".
  2. Replace the string "Category.getRoot" with the string "Logger.getRootLogger".
  3. Replace the string "Category" with the string "Logger".
  4. Replace the string "Priority" with the string "Level".

Happy logging!

Sunday, February 04, 2007

Trailing Comma in Arrays

Most of us know how to initialize arrays. A usual way to initialize array is to specify all its elements. For example an array of integers can be initialized in following way:

Integer[] integerArray = new Integer[] {
new Integer(1),
new Integer(2),
new Integer(4)
};

I was generating code for a unit test and needed to create a List that I would pass to the constructor of a particular class I wanted to test. So I took the easiest way to create array then convert it to the list. In the process I generated the elements of the array by copying and pasting previously added element. The code looked like this:

List initList = Arrays.asList(new Integer[] {
new Integer(1),
new Integer(2),
new Integer(1),
new Integer(2),
});

Notice the trailing comma! To my surprise, my IDE did not warn me about compilation error, moreover the code compiled and ran just fine.

According to Java Language Specification, chapter 10.6 Array Initializers

An array initializer is written as a comma-separated list of expressions, enclosed by braces "{" and "}".

The length of the constructed array will equal the number of expressions.

The expressions in an array initializer are executed from left to right in the textual order they occur in the source code. The nth variable initializer specifies the value of the n-1st array component. Each expression must be assignment-compatible (§5.2) with the array's component type, or a compile-time error results.

If the component type is itself an array type, then the expression specifying a component may itself be an array initializer; that is, array initializers may be nested.

A trailing comma may appear after the last expression in an array initializer and is ignored.

I must admit that I never used trailing commas in arrays in my whole software engineering career and on this occasion, this took my be surprise. I guess making mistakes it one way of discovering the truth and realizing that a mistake may not be a mistake after all.

So, there you go! Initializing arrays in Java with a trailing comma is totally valid. I learn something new every day :-)

Tuesday, January 30, 2007

Method Invocation vs. Local Store

On many occasions, I have seen the code that invokes the same method on the same object several times within few consecutive lines of code. Let's have a look at the following code snippet:

if(person.getDateOfBirth() != null) {
System.out.println("Date of birth: " + person.getDateOfBirth());
}

When I see this repetition of code I feel like I should refactor it order to remove the duplicity. Refactoring itself would be very easy. The return value would be stored in a local variable and used wherever the original method was invoked.

The example above could be refactored in following way:

final Date dob =person.getDateOfBirth();
if (dob != null) {
System.out.println("Date of birth: " + dob);
}

The reason behind my urge to refactor such code is in performance. Method invocation can repeatedly cause execution of potentially expensive operations such as slow database access, network communication or some lengthly calculations.

If in the example above the date of birth of person object was very unlikely to change between the two getDateOfBirth() method invocations and therefore it was a safe bet to store the result locally in a local variable.

Invoking a method once, storing the result in a local variable could speed the application up. However, it could also break it.

Why would a local store break the application? Well, it may not, it really depends on the invoked method itself and the way our application uses the returned value. If a method performs some side operations it actually may rely on its invocation. Such operations can be for example increasing a counter, retrieving updated stock ticker info, etc. The return value may also depend on the number or time of invocations or other things that may affect it. Another example would be an application that performs business logic based on the most recent data.If the data that method returns varies frequently and business logic depends on it, storing it may not be such a good idea.

I'll give you a very bad example here, but this is the extreme where the result is guaranteed to return a different result almost every time:

if (Math.random() < 0.5) {
// notify developer A
} else if(Math.random() >= 0.5) {
// notify developer B
} else {
// this should never happen,right?
// :-)
// but it does happen with likelihood of 25%
}

So it really brings us down to the point where we have to examine what the method does, what data it returns and what the client does with the returned data.

Conclusion

  • Use local store if the invoked method returns consistent results and has no side-effects. Method invocation could be slower or potentially break the client code.

  • Use method invocation if the method invoked has side-effects or the data returned changes frequently and the client relies on the latest result.

Sunday, December 17, 2006

Recursion vs. Loop

Problem

Imagine that your application is meant to process an XML file. It is given a tag and needs to find a "special tag" that this tag might be nested in. This problem has several solutions. I tackled a similar problem some time ago and I will present you with some of the solutions that I considered.

While loop

private SpecialTag findSpecialTag()
{
Tag parent = this.getParentTag();
while (parent != null && !(parent instanceof SpecialTag))
{
parent = parent.getParentTag();
}
return (SpecialTag) parent;
}

Do-while loop

private SpecialTag findSpecialTag()
{
Tag parent = this;
do
{
parent = parent.getParentTag();
}
while (parent != null && !(parent instanceof SpecialTag));
return (SpecialTag) parent;
}

Recursion

private SpecialTag findSpecialTag()
{
return findSpecialTag(this.getParentTag());
}

private SpecialTag findSpecialTag(Tag tag)
{
if (tag == null || tag instanceof SpecialTag)
{
return (SpecialTag) tag;
}
else
{
return findSpecialTag(tag.getParentTag());
}
}

Solution

In my personal opinion, I find the while loop cleanest and simplest to understand. Do-while loop gets a bit messy with the condition at the end and recursion is probably the worst. I find recursion a bit hard to follow. It can also introduce an extra method just for its own sake (as in this example).

I do not have a strong opinion on this topic. If you like to program recursions, while loops, do-while loops, or for loops, it's fine by me. I certainly will not change your code, but if you ask me to write some code, it'd most likely be a while (or for) loop.

I use while and for loops interchangeably. The previous example with while loop would look like this with for loop:

private SpecialTag findSpecialTag()
{
Tag p = this.getParentTag();
for(; p != null && !(p instanceof SpecialTag); p = p.getParentTag());
return (SpecialTag) parent;
}

What is your preference?

Monday, December 11, 2006

Project Automation

I just finished reading Pragmatic Project Automation (How to Build, Deploy and Monitor Java Applications) written by Mike Clark.

This book is very well written and an easy read. I picked it from the shelf in our Atlassian library two months ago. I read it mostly in the mornings and evenings on the train commuting to the office. I must say that even my trips take only 20 minutes, in those 20 minutes I managed to read just enough to get me started thinking about software processes that we have in place and how to improve them.

There were many things in the book that I was quite familiar with. I have already used Ant, written unit tests, created scripts that build new releases. Although I was familiar with many of these aspects of project automation, there were new ideas, other angles of application of the automated processes I've never thought about. I was quite interested in reading the chapters dedicated to installation, deployment and monitoring. I have faced the dilemmas of these stages of software development and I was quite curious to find out how the author solved them.

This book is truly inspirational. In a sense it is a cook book for project automation. It's easy to follow and proves useful to a novice as well as experienced developer.

I will put this book back on the shelf in our office. It's worth sharing and I will highly recommend reading it to anybody who wants to automate almost anything in software development.

Wednesday, September 27, 2006

First element in the List

Imagine this scenario. You are working on an existing application. There is a framework used. One of the benefits that this framework gives you is retrieving and processing parameters coming from the client, let's say a web application. The framework gives you all parameters as a List. Now in this particular case you always get only one parameter, but is it enclosed in the List. How do you get it out efficiently?

The intended method would be described: Get the list of parameters and if not empty, return first element in the list otherwise return null. The code was looked similar to this:

1 public E getSingleParam(List params) {
2 E param = null;
3 if (params != null && params.size() >= 1) {
4 param = params.iterator().next();
5 }
6 }

This code works fine but it has several points for improvement. First is how the code at line 3 expresses the intention of check whether the list of parameters is not null and not empty, specifically the later. List interface defines boolean isEmpty() method that is in most cases more efficient to run than getting the size and comparing it to 0 (greater than) or 1 (grater than or equal). That is if the list implements an internal flag for its "emptiness" state or has an internal counter as opposed to re-counting its elements. In the worst case scenario the efficiency will be the same as getting the size and comparing it with 0. In that case isEmpty() method is still a nice convenience method to call and should be preferred before the size() > 0 alternative. Another reason is that it speaks for itself. All we need to know is whether there are any elements in the list or not. Getting the size should be used to for other purposes (e.g. calculating the width of the table column when displaying the results in a tabular form – 100% / size()).

1 public E getSingleParam(List params) {
2 E param = null;
3 if (params != null && !params.isEmpty()) {
4 param = params.iterator().next();
5 }
6 }

The second point of making the code to perform better and to make it easier to read is the line 4. On this line we are getting the first element of the list. As shown in the example above, this is an inefficient way as we construct an Iterator only for the purpose of one iteration. Constructing new objects and disposing of them is usually expensive and should be avoided. A better way is to access the element directly, such as:

1 public E getSingleParam(List params) {
2 E param = null;
3 if (params != null && !params.isEmpty()) {
4 param = params.get(0);
5 }
6 }

This way no new objects are constructed (no Iterator). Another difference between the two is the exception that could be possibly thrown. The exception would be thrown if we did not have the previous check or in the case of concurrent modification of the list which is very unlikely in this case. The exception thrown in first case would be a NoSuchElementException. In the second way, an IndexOutOfBoundsException would be thrown. Both of them are runtime exceptions and do not have to be declared. In this case getting one exception or the other should not make any difference.


Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License.