Tag Archives: programming

When Jenkin checkout the wrong SVN revision

Evolus have brought the Build Integration Server into function for a while. The thing I like most about Jenkin is that I don’t have to build the heavy web-application in my machine anymore (the build process eats RAM pretty fast). Instead, the build get packaged on the CI server and then deployed directly to our staging server.

In fact, we have to get over several issues before getting it done correctly. One of them is the “Wrong SVN version” issue.

Situation:
The last SVN version for development is 129. But the svn update on CI server always yields 127. We must wait several hours before it brings to the correct version of SVN to the CI server for building.

We have tried to switch to another checkout strategy. But even a full check-out doesn’t help to update the svn version correctly.

Cause:

It’s the time. The SVN server must be synced by time with the CI server. The mismatching of time (even in seconds) can caused a loss in SVN check out function.

Solution:

Since we don’t control the SVN server directly, we can’t have it synced with CI server. A work-around is that we can indicate Jenkin to check only for the HEAD version:

Put the link into the SVN box and it will be ok: svn://hostname/project/trunk@HEAD

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.

Gotchas of Authentication Flow for application on Facebook – OAuth 2.0 (2)

Facebook logo

/**

Vietnamese: bài viết này trình bày tiếp một số điểm có thể gây nhầm lẫn trong quá trình chứng thực Facebook OAuth 2.0.

**/

Following the first article, this one continue presenting about the cases that can make developers confused.

3. Big Facebook logo prevent redirection:

According to Facebook documents, the server must redirect users to “authorization page”  to grant permissions.

https://www.facebook.com/dialog/oauth?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream

But every redirect command sent from server leads to a blank page with a big blue Facebook logo instead!
If the same URL is put directly in a browser, then it goes to the correct page.

In short, Facebook has stopped the redirection from a third-party server. The user needs to redirect themselves, or we can help them by redirecting with javascript.

4. Tricky privacy settings:

One thing developers should know is that Facebook give full privacy control to the users. A user can change permissions any time they want. It means after a user approve your application, they still can:

  • Change their email, personal information
  • Choose to not provide you their real email, but a proxy email of Facebook
  • Remove some permission of your application (for example, publish feeds on wall)

Ofcourses, Facebook provides callback functions when those permissions change. However I don’t think it’s worth the efforts to handle all of these events, at least for a quick prototype application.

5. De-authorization callback

The authorization callback is the URL that Facebook will call if a user remove your application. At that time, the application should remove all user data that they save: access token, personal information…

At first glance, this seems to be a moral requirement. But in practice, obsolete data should not be kept anyway. Believe me, Facebook data flow is fragile, and you are asking for business logic troubles if not following the rule.

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().

Keeping shape in high pressure

openclipart,coffee

/* Vietnamese: Một vài cách để chống stress dành cho lập trình viên khi làm việc với cường độ cao */

In programming community, working under high pressure is often a “must have” ability. Here list some of my tips to maintain good conditions in those situation:

Take some rest: Keep in mind that a weary brain do more harm than good things. Men are no machine. If you are trying to get a bug solved, things may turn out that you created even more bugs.Don’t take quick fix: a common situation is that before an important release, we are inclined to take hot-fix. A hard-code message, a magic number, which seems no harm at the moment, will cause you BIG trouble later.

Be assured, in those time, you are inclined to make errors more than anytime. Be careful even to the log message, or you will find yourself among lots of trash code later.

Sleep enough: easy to say, but hard to do. IT guys often feels good working at the night: the network is fast, no intervention… But I still think working too late is a bad idea. 8 hours a day is enough – if you want to maintain health.

Supply foods: Brainstorming requires much of energy, just like physical activities. This item even more important if you can’t guarantee the time of your sleeps. Prepare some snacks, noodles if you’re going to work overtime. You will not regret it.

Stay cool: Keeping a calm emotion is important. No matter how important a release is, it’s surely not the end of world. When I began working, I feels great pressure everytime a bug pop out near our deadline. But my seniors are different. They solve the problem step by step. And in the end, everything is just fine.

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

Annotation Validation in Spring Framework 3

/* Vietnamese: bài viết hướng dẫn một cách ngắn gọn cách thực hiện kiểm tra điều kiện của đối tượng (validation) bằng cách dùng ký hiệu (annotation) với Spring Framework */

Validation is not a problem in Spring Framework, at least, by the normal way.

But the “Validation by Annotation” is not that popular, since this utility was only available from Spring 3. Up to now I found no resource which give a short & comprehensive tutorial yet (at least to this time – 05/2011)

How to make annotation validation works in Spring Framework 3

1. Configure Maven to include Hibernate Validator

2. Setup default validator bean in config file:
[sourcecoce language="xml"]
<bean id=”validator” class=”org.springframework.validation.beanvalidation.LocalValidatorFactoryBean” />
[/sourcecode]

3. Add @annotation

Let’s see what is annotation validation in its action:

public class User implements Serializable {
        private long id;
        @NotNull(message=&quot;{user.name.notnull}
        @Length(max = 255, message=&quot;{user.name.length}&quot;)
	private String username;
	public void setUsername(String name) {
		this.username = name;
	}
	public int getUsername() {
		return username;
	}
}

Code for the controller:

@Controller
@RequestMapping(&quot;/administration/*&quot;)
public class AdministrationController {
    /**
     * For every request for this controller, this will
     * create a user instance for the form.
     */
    @ModelAttribute
    public User newRequest(@RequestParam(required=false) String id) {
        return (id != null ? userService.getUserById(id) : new User());
    }

    @RequestMapping(value=&quot;/editUser&quot;, method=RequestMethod.GET)
	public final String edit(@Valid User user, BindingResult result) throws Exception {

		if (user == null) {
			return &quot;redirect:/administration/manageUser&quot;;
		}

		return null;
	}

	@RequestMapping(value=&quot;/editUser&quot;, method=RequestMethod.POST)
	public final String updateUser(@Valid User user, BindingResult result) throws Exception {

		if (result.hasErrors()) {
			return null;
		}

		userService.updateUser(user);

		return &quot;redirect:/administration/manageUser&quot;;
	}
}

And in the end, for the jsp:

&lt;/pre&gt;
&lt;h1&gt;Edit Site User&lt;/h1&gt;
&lt;div&gt;
&lt;fieldset&gt;&lt;legend&gt;Edit Site User&lt;/legend&gt;
 &lt;input type=&quot;hidden&quot; name=&quot;userId&quot; value=&quot;${user.id}&quot; /&gt;
				&lt;p&gt;
					&lt;form:label for=&quot;id&quot; path=&quot;id&quot;&gt;Id&lt;/form:label&gt;
					&lt;br /&gt;
					&lt;form:input path=&quot;id&quot; readonly=&quot;true&quot; /&gt;
					&lt;font color=&quot;red&quot;&gt;&lt;form:errors path=&quot;id&quot; /&gt;
					&lt;/font&gt;
				&lt;/p&gt;
				&lt;p&gt;
					&lt;form:label for=&quot;username&quot; path=&quot;username&quot;&gt;User Name&lt;/form:label&gt;
					&lt;br /&gt;
					&lt;form:input path=&quot;username&quot; readonly=&quot;true&quot; /&gt;
					&lt;font color=&quot;red&quot;&gt;&lt;form:errors path=&quot;username&quot; /&gt;
					&lt;/font&gt;
				&lt;/p&gt;
&lt;/fieldset&gt;
&lt;/div&gt;
&lt;pre&gt;

Start at StackOverflow: Writing good question

StackOverflow

** Vietnamese: Bài viết trình bày về những khó khăn khi bắt đầu tham gia cộng đồng StackOverflow, cùng một số mẹo có thể sẽ có ích cho người mới. **

Several months ago, I have written a native language post about Stack Overflow(SO), the current largest Q&A expertise sites for programmers. In short, the site’s goal is helping software developers find solutions and learn new things about all kinds of technology. It can also be known as a “knowledge pool” of programming. But from a user’s view, it’s more about sharing knowledge and earning trust.
The success of SO can be reasoned by its unique “reputation” model, which evaluate member contribution not by number of posts but by community responses. But this model also create obstacles that a newcomer must overcome if he/she wants to be a part of this community.

Problem of a new-comer

The fact is that, when starting, you only have the tiny cute “1″ reputation point. At this time, you only have two things to do: ask or answer. Fine, it’s the basic utilities of the site. If you want to go further and unlock more interesting functions, you must give back to the community by providing good posts. But the funny journey just begin: not any post you provide will get an up-vote(1) from other users. On the other hand, your poor question may likely get down-vote(2), which means throwing away your hard-work.

But there’s good news: as long as the new user know how to post good question, it’s not too hard to get enough reputation(15 points) for a start. The list of tips includes:

  1. Ask relevant questions: this is not only most basic rule, but also the most popular mistake. For a short explanation: SO is a QA site for questions that can be answered, which means no subjective questions or poll may survive here. A post like “which programming language you like most?” will get closed in few minutes, usually along with dozens of down-vote to the creator.
  2. Prove that you tried solving the problem: simple enough, no one will help you if you don’t help yourself first. Don’t ask question whose answer appears as the first result with a simple Google keyword. In short: search the answer first, only ask if you can’t find the appropriate result. A short summarization about your efforts is welcome: it saves others time for trying the way you already did and make the problem clearer.If you’d like to know, describe your problem in detail will benefits the users have the same problem with you. Doing good for others will be never a bad idea ;)
  3. Provide detailed information: like above, it’s necessary for others to understand your problem.
  4. Attach code: code is self-explanation. Specially if your English is not very good, posting code will help others understand your question better. But remember only posting the “relevant code”, which closely associated to the problem. No one will happily look through your 500 line HTML code to give you the answer ^^And the last thing: use the code tag to format your code. This snippet works very well for most of the programming language.
  5. Be open & polite: this is about communication. Treat people the same as you want people treat you.
That’s all :)

(1) & (2): up-vote & down-vote. When a SO user reach 15 reputation points, he/she can evaluate any other user’s post by up-vote or down-vote it. With each up-vote received, the owner of the post receive some reputation points as the prize. On the opposite, if the post is down-voted, the owner will lost some points as well.