Category Archives: Java

Unit test – call the agel out of the stone

Angel

Angel, please come out of the stone

“I saw the angel in the marble and carved until I set him free” – Michelangelo

After the previous post when I managed to make Spring context wired for Unit test to run, now there’s more thing into it. Well, I gave my Test class the ability to do IOC (Inversion of Control), and from now they can call service beans, access databases, and so on… It seems the remaining should be easy, since the hardest part has been completed.

Well, things don’t easily go as we expect, in lots of occasions.

I actually made a running code, but when I try writing my first unit tests for my current working web-application, things turn bad. It turns out that I can’t write much meaningful non-trivial test, without making test-running-time tremendous slow. Why? It’s because:

1. Most of my code logic lies in the service. AND the service (in this project) OFTEN (if not always) works with Database. And when I says Database, it means the test is not the unit test anymore. It’s an Integration Test.

2. There’s some logic in my project which doesn’t relate to database. But I feels pretty confident about them – they are mostly simple. According to Pareto’s 80/20 rule, I don’t want to write tests that doesn’t enhance maintenance ability.

Those may be (some of) the reasons that my seniors don’t encourage me to write unit test. Unit tests are meant to be fast. If it’s not fast, there’s no reason to run it frequently, to help refactoring or development.

Another problem I meet is to set up the Database to a known state before running the test. Only then the test results will have some meanings.

So… are the efforts all useless. Absolutely no. The main problem here is that I need to stop regression bugs, by regularly running some kind of test. Whatever it is, but let me find bugs soon, and stop the system broken by ill-refactoring.

“And I have found the solution. The way to call the angel out of the stone”. If I can put up an in-memory database instead of Postgres, the running-time will be fast. I can also prepare the environment by database script or bootstrap code.

DBUnit seems to be a fair choice for a solution.

Quick note on Java time

The analog timer, From openclipart.org
One of the things I dislike most in Java is… unfriendly. DateTime manipulation is a typical example. I think at least one time, a Java developer will encounter this message: getYear() is deprecated.

Such a simple and often-heavily-used function is deprecated. So programmers must walk around by the Calendar class.

Calendar localCalendar = Calendar.getInstance();
Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Date date = new Date();
localCalendar.setTime(date);
utcCalendar.setTime(date);

TimeZone localTimeZone = localCalendar.getTimeZone();

System.out.println("Year: " + localCalendar.get(Calendar.YEAR));
System.out.println("Month: " + localCalendar.get(Calendar.MONTH) + 1);
System.out.println("Day: " + localCalendar.get(Calendar.DATE));
System.out.println("Day of week: " + localCalendar.get(Calendar.DAY_OF_WEEK));
System.out.println("Hour: " + localCalendar.get(Calendar.HOUR_OF_DAY));
System.out.println("Minute: " + localCalendar.get(Calendar.MINUTE));

System.out.println("Timezone: " + localTimeZone.getDisplayName());
System.out.println("UTC Hour: " + utcCalendar.get(Calendar.HOUR));
System.out.println("UTC Minute: " + utcCalendar.get(Calendar.MINUTE));

Although Java big heads all have valid reasons for this inconvenience – which is the complexity of time manipulation, I still think this way is over-killing. Yes, no computer is accurate enough to calculate the correct solar time. But we are no astronomy expert, who cares if the time lacks one or two leap seconds*? Daylight saving stuffs is still necessary, but shouldn’t be too much of a problem.

In the end, I think Java powerful libraries should also make it easy to do simple tasks, instead thinking ahead too much for easy enlargement later**. With the Internet as popular as today, I think we can safely calculate “simple” time only, leaving the task to do additional astronomy calculation for the big servers, and cover the gaps by synchronizing.


(*) Like leap year, a leap second is sometimes added to our current timeline to cover the gaps between solar year & normal year. Because a leap second is too small,  people seldom notice. Reference: http://tycho.usno.navy.mil/leapsec.html

(**) Java has the reputation for easy scaling, and this is very true in my experience. On the opposite, small application is suddenly heavy at their very first cradle time, because a fair amount of efforts are put in “making room” for future changes.

Lesson learned from the Exception Filter

Long time ago, while I’m still a student, I have a chance to read Foundation of Programming“. “All exception should be captured, to show a understandable, friendly error message to customer”.

But now I realize that it’s not enough. In a recent web project, I created an exception filter to handle all exceptions popping out:

@Override
public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		String errorMessage = "";

		try {
			chain.doFilter(request, response);
		} catch (SessionExpiredException e){
		    log.info(e.getMessage(), e);
                    errorMessage = "Your session has been expired";
                    request.sendRedirect(...);
		} catch (InvalidFacebookIdException e) {
                   // ...
		} catch(FacebookAccountAlreadyRegisteredException e) {
                   // ...
		} catch (Exception e) {
                   // ...
		}
	}

Do you notice the duplicate code? At any exception caught, the system must log the error, compose the mesage, then redirect to the error page.There are more than dozen of exceptions like that. How can we “clean” the code?

Thanks bro Tinh, here’s a (customized) solution:

@Override
public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
//...
		try {
			chain.doFilter(request, response);
		} catch (Exception e) {
                   errorMessage = e.getMessage();
                   log.error("Error occur: " + e.getMessage(), e);
                   res.sendRedirect(...);
		}
	}

All errors now are caught in one place: general Exception instead of concrete type.Two problems remain:

  • How to catch the right exception, because they are wrapped by Servlet Exception.
  • Guarantee all Customized Exception have a message

The answer for the first question:

private String getUsefulMessage(Exception e) {
Exception default = e.getMessage();
do {
if (e.getClass().getName().equals(InvalidFacebookId.class.getName())) return e.getMessage();
// ... same for other exceptions
e = e.getCause();
} while(e.getCause() != null);

return default;
} 

It’s the same, yes, for logic. But the later is more clearer.

The second question is more about coding policy than a technical problem, so I leave it out. In the case of our team, we decide that each exception should have an understandable getMessage().

Warning about primitive ModelAttribute

Recently while working with Spring Framework 3.0, I stumbled upon a trap that might be a bug of Spring Framework. It costs our team lots of time & efforts, since the bug is like a mystery that happens randomly. Eventually we decide to take a work around, but it’s still take lots of time to change the way the system was working.

The mystery is called Model Attribute, a handy utility supported by Spring 3.x.

Personally, I like this feature a lot. The ModelAttribute Annotation way gives me the ability to declare and init a variable just once, then it will be automatically added into model of any action. For example:

@ModelAttribute("user")
public User getCurrentUser() {
return userService.getCurrentUser();
}

But a problem happen here & there when I use primitive type (long, int, …) or even their wrapper type (Long, Integer,…) for the ModelAttribute. An error just pop out of nowhere:

java.lang.NoSuchMethodException: long.()<init>

Following my senior hint, I even comes to the code of Spring Framework, and actually see that it try to call the default constructer of Long type. Since that constructer does not exist (certainly), it fails and brings up the error. The headache is that this thing does not always happen: I still can not figure what trigger it up. But the fact that it’s out there make me & our team change the course of the program: instead of an tidy assignment, now we need to call the same function again & again whenever we need that modelAttribute (almost always in my case).

I have put a question out there in StackOverflow, but it still get no-good answer. I wonder if I should raise a bug for Spring… but until then I think that this “brilliant” way shouldn’t be used.

Hope this post is useful for anyone come across the same problem.

Finding key issues of the framework

Website System

1. How to learn a framework fast?

2. To learn a framework, you should grasp the “key” issues. But how to know what is a key issue?

Those two questions are pinned in my head somehow.

Not long ago, I’m investigating MVC model in Spring Framework 3.0. Most of the concept is fine, but I have problems doing the work with Spring 3 annotation config. It just seems all the book out there mention about Spring 2.x syntax, which is “xml configuration”. It’s easy to understand because that Spring 3 just appear and it will take a relative time to make a book available. So my habit about following book guides was discarded aside. I must try to find another source.

According the advice of my seniors, I go to the Spring document & find most of the thing is already here. Enough details, though a bit complex to a not-quite-familiar-with-java coder. I struggle with those concept a bit. But by comparing the document to several examples, finally I got some “working things”, which is great.

But here comes the most complicated part: integrating between frameworks. In one of my projects, I should use Spring combined with Freemarker. I investigate, and luckily enough, find this page which tell me how to use Freemarker macro to perform bindings (it’s not an easy luck).

But WTH, I can’t find a way to use the formCheckboxes! I found no working sample, and I’m not alone.

Dozens people out there can’t find a way to use that macro.

And the solution?

Well, I write my own macros.

It took me quite a time before I relize that simple solution, and curse how stupid I am. Since the end results of freemarker is HTML, who cares if it was rendered by supported macro or customed macro?

When you know what actually happens inside that big system, the answer seems to be natural.


Still remember 2 questions at the beginning of this post?

I must says the truth, that I don’t know the best answer. But I have something that seems to work:

The solution depends on the needs. If you just use the surface of the libraries API as the common “players”, some popular tutorials might be enough. Parsing XML maybe a good example for this issue. With the same reason, I think with beginner, Grails (instead of Spring) is a good start, cause it requires little work to make a full-fledge simple application.

If you want to create a customized & not-so-popular web application, it requires more tons of work. And a solid background is preferable.

Put Tomcat in Eclipse

Photobucket

/**

Vietnamese: bài viết hướng dẫn về cách cấu hình để tích hợp Tomcat vào Eclipse

**/

Since most of the step-to-step-guide about this problem (at least the guides I found) are a bit out-dated, I think I had better create a guide here. In fact, this guide is taken from my brothers at Evolus. Special thanks to bro Trương Xuân Tính and bro Lê Hồ Bá Phước for this piece of knowledge and their patience to repeat-and-repeat this damn process for me.

Notice: this guide is not a complete guide, just some kind of a checklist. I’ll add more details over time. Please feel free to ask if there’s something you don’t understand.

0. Download & install Tomcat & Eclipse.

1. Find the Tomcat sysdeo plugin for eclipse. I found a download source here, but the location can change in the future.

2. Install the plugin (taken from the official guide). Extract the plugin file (in my case, its version is 3.3.0). Copy the plugin to:
- “Eclipse_Home/dropins” for Eclipse 3.4, 3.5 and 3.6
- “Eclipse_Home/plugins” for Eclipse 2.1, 3.0, 3.1, 3.2 and 3.3

Plugin activation for Eclipse 3.x :

  • launch eclipse once using this option : -clean
  • if Tomcat icons are not shown in toolbar : select menu ‘Window>Customize Perspective…>Commands’, and check ‘Tomcat’ in ‘Available command groups’

Set Tomcat version and Tomcat home : Workbench -> Preferences, select Tomcat and set Tomcat version and Tomcat home (Tomcat version and Tomcat home are the only required fields, other settings are there for advanced configuration).

This plugin launches Tomcat using the default JRE checked in Eclipe preferences window.

  • To set a JDK as default JRE for Eclipse open the preference window : Window -> Preferences -> Java -> Installed JREs. This JRE must be a JDK (This is a Tomcat prerequisite).
  • The plugin sets itself Tomcat classpath and bootclasspath. Use Preferences -> Tomcat ->JVM Settings, only if you need specific settings. Often, I set the variable -Denv=dev to use different config file for development & production.

3. Finalize

Go to the plugin folder, you will see 2 files: “DevLoader.zip” & “DevloaderTomcat7.jar”. As their name implies, you will use “DevLoader.zip” for Tomcat with version less than 7, and “DevLoaderTomcat7.jar” for Tomcat 7.

  • If you are using Tomcat 7, copy “DevloaderTomcat7.jar” to <TOMCAT_HOME>/lib
  • If you are using other Tomcat 6, rename “DevLoader.zip” to “DevLoader.jar”, then put it in <TOMCAT_HOME>/lib.

Create a web project (I’m using Maven to manage the builds). Go to the properties of your project, go to “Tomcat/Class Loader/”, un-check “servlet-api.jar” and other libraries that are already provided by Tomcat. This is for preventing conflicts among duplicate libraries.

Also in “Project/Properties”,  set the context name and web application root. Context name is the name that you use to access the web-app, for example, if the context name is “test”, your server url may be like: “localhost:8080/test/”. Web application root is the place you put your web-application (it’s the folder that contains WEB-INF folder, often named webapp).

If you are using Maven, remember, all these eclispe settings will be removed if you do “maven eclipse:clean”, so don’t use that command unless you want to do config again. Only use “maven eclipse:eclipse” instead.

That should complete the task. Good luck!

Reference: http://www.eclipsetotale.com/tomcatPlugin.html

Dollar sign($) and the ReplaceAll Gotchas

/* Vietnamese summarization: String.replaceAll() là một hàm tiện dụng của Java, nhưng do cách đặt tên lại dễ bị hiểu nhầm tác dụng với String.replace(). Bài viết trình bày sự khác biệt giữa hai hàm này qua một trường hợp nhầm lẫn ngớ ngẩn của người viết. */

Today I got a “big” mistake, which take a fairly long time to solve. It’s a problem related to String.replaceAll() function of Java. The experience is so hot that I want to share it immediately.

Here’s the simplified problem: I need to construct a template for sending Email. The web application will take the template and insert user information into it. This task is performed by replacing some placeholder by user true information, for example:

Template: {USER_NAME}‘s hometown is {USER_COUNTRY}

Sending content: Long‘s hometown is Vietnam.

Usually, content = template.replaceAll(“{USER_NAME}”,username); is enough. It works well in most cases, but problem occurs when username contains some special characters, specifically, the dollar signs ($).

I know the “$” must have been interpreted different by Regex, so I try to escape the character. My first thought is that replacing “$” by “$”, but no matter how many “”, “QE” or “String.quote()” I put in, replaceAll still refuse to work.

I do a quick search on Google, and find this post. The writer once had the same problem but find no answer, so he decided to go for a quick fix. Temporarily, I accept the proposed solution.

But when asking the seniors about the solution, he tells me that there’s one thing I missed at the beginning: in Java6, ReplaceAll is for regex-replacement , in my case, I can use String.replace() instead!

In short, replaceAll() when you use Regex, if not, a String.replace() is enough.