Monday, December 27, 2010

Unit testing Freemarker macros with JUnit and HtmlUnit

I recently had to modify a pagination macro in FreeMarker. That pagination system is a bit different from the ordinary ones, and the safest way to make sure that it was working properly was to unit test it. Making a lot of data to test it would have been to much hastle, so I looked for a way to test the FreeMarker macro out of the web container. I wanted to make sure that the generated page numbers were correct, and also that the previous and next arrows were displayed when needed. All pages are html anchors, all contained into a div tag. To test it, I had to :
  1. Make a unit test class for the macro.
  2. Make FreeMarker interprete the macro.
  3. Confirm that the expected html elements like divs and anchors were present.
Why using HtmlUnit ? Because it has some useful methods to retrieve html elements by their name or by their id.

Getting the necessary libraries

All I needed was : JUnit, FreeMarker and HtmlUnit. HtmlUnit has quite a lot of dependencies, but all the necessary libraries are part of the HtmlUnit archive. You can easy go to their respective homepage and download them yourself, or get them via Maven. Here are the necessary dependencies for the sample we'll make in this tutorial :
<dependencies>
    <dependency>
      <groupId>net.sourceforge.htmlunit</groupId>
      <artifactId>htmlunit</artifactId>
      <version>2.8</version>
    </dependency>
 <dependency>
     <groupId>org.freemarker</groupId>
     <artifactId>freemarker</artifactId>
     <version>2.3.16</version>
 </dependency>
 <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.8.2</version>
 </dependency>
  </dependencies>

A basic macro

Let's make a basic pagination macro. We'll keep it simple. The page links won't point anywhere. We just want to show page numbers. The current page will be plain text, other page numbers will be html anchors. The macro parameters will be the total number of pages and the current page. It will also show previous and next if necessary.
<#macro doPagination totalPages currentPage >
 <#if (totalPages > 1)>
  <div id="pagination">
   <#-- Previous page -->
   <#if (currentPage > 1)>
    <a href="#">Prev</a>
   </#if>
   
   <#-- Page number -->
   <#list 1 .. totalPages as pageNumber>
    <#if (pageNumber == currentPage)>
     <div id="currentPage">${pageNumber}</div>
    <#else>
     <div><a href="#">${pageNumber}</a></div>
    </#if>  
   </#list>
   
   <#-- Next page -->  
   <#if (currentPage < totalPages)>
    <a href="#">Next</a>
   </#if>  
  </div>
 </#if>
</#macro>

Using a dummy template

We need a FreeMarker template to use the pagination macro. This template will just import the file where the macro is, and call the macro.
<#import "/main/webapp/templates/macros/pagination.ftl" as pagination/>
<html>
<body>
<@pagination.doPagination totalPages currentPage />
</body>
</html>

Preparing FreeMarker for the tests

We'll use the FreeMarker API to convert the dummy template into html. We'll make use of the following two classes : freemarker.template.Configuration and freemarker.template.Template. Let's set this up in the @Before method of our test class.
public class PaginationTest {

 /** Root directory where the FreeMarker templates are */
    private static final String TEMPLATE_ROOT = "src";
    /** Dummy pagination template location */
    private static final String PAGINATION_TEMPLATE = "test/java/com/kuriqoo/templates/macros/pagination_test.ftl";

    private Configuration cfg;
    private Template template;

    private Map<String, Object> rootMap;
    
    @Before
    public void setUp() throws Exception {
        cfg = new Configuration();
        cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_ROOT));

        template = cfg.getTemplate(PAGINATION_TEMPLATE);
        
        rootMap = new HashMap<String, Object>();
    }
}
First, the TEMPLATE_ROOT. The macro is in "/src/main/webapp/templates/macros/pagination.ftl" and the dummy template is in "/src/test/java/com/kuriqoo/templates/macros/pagination_test.ftl". So the common template root is "src".

Then, the PAGINATION_TEMPLATE. This points to the dummy template. Note that the root ("src") is not included in it.


We create a Configuration and set its template root directory. Using that Configuration instance, we can build some templates, by calling its getTemplate method. Here, we are making our dummy template. Note that this template is not yet trnasformed into html. This will come after.

The HashMap call rootMap is used by FreeMarker when it generates the html code from the template. This map must contain all the necessary information used by our macro, like the total number of pages and the current page. This information will be set in the test methods.


Unit testing

Each test will be executed with the following steps:
  1. Set the information used by the pagination macro in the root map.
  2. Make FreeMarker generate html from our template.
  3. Feed HtmlUnit with our html to generate an HtmlPage instance.
  4. Declare some expectations, like the expected anchor tags representing page numbers.
  5. Get the anchor tags present in the pagination div and compare them to the expected ones.
  6. Assert that the current page is present and is not a link.

Set the information used by the pagination macro in the root map

Our simple macro only need to know the number of pages and the current page, so we'll set that information in the root map used by FreeMarker :
private void setPaginationAttributes(int totalPages, int currentPage) {
        rootMap.put("totalPages", totalPages);
        rootMap.put("currentPage", currentPage);
    }

Make FreeMarker generate html from our template and feed HtmlUnit with our html to generate an HtmlPage instance

This is the interesting part. Remember the Template instance we created above ? We'll use it to generate html. The method used for this is process(Map, Writer). We'll output the html content into a StringWriter. The reason is that we want to use the output to generate an HtmlUnit HtmlPage.
private HtmlPage getHtmlPageFromTemplate() throws TemplateException, IOException {

    // Process template
    StringWriter out = new StringWriter();
    template.process(rootMap, out);

    // Get HtmlPage
    WebClient client = new WebClient();
    PageCreator pageCreator = client.getPageCreator();
    WebResponseData responseData = new WebResponseData(out.toString().getBytes(), 200, "OK", new ArrayList<NameValuePair>());
    WebResponse response = new WebResponse(responseData, new URL("http://localhost:8080/"), HttpMethod.GET, 10);
    return (HtmlPage)pageCreator.createPage(response, client.getCurrentWindow());
}
There's a lot going on here, but most of it is dummy data. First, we call the process method of the Template method, and set the ouput into a StringWriter. Then, in order to create an HtmlPage, we setup a WebClient and generate a dummy response containing our html.

Declare some expectations

We want to check the following:
  1. All page numbers are anchors tags, except the current page
  2. The previous and next anchors tags are present when necessary
  3. The number of generated anchor tags equals the number of expected anchor tags
  4. The current page is present, and is not an anchor tag
Here is an example where there are only two pages, and the first one is the current page.
@Test
public void testPagination_twopages_currentisone() throws IOException, TemplateException {
    // Make FreeMarker template
 setPaginationAttributes(2, 1);
    HtmlPage page = getHtmlPageFromTemplate();

    // page links
    List<String> expectedContent = makeExpectedLinks(new String[]{"2"}, false, true); 
    List<HtmlElement> pageLinks = getPaginationLinks(page);
    Assert.assertEquals(expectedContent.size(), pageLinks.size());
    assertContainsLinks(expectedContent, pageLinks);
    assertCurrentPageIs(page, "1");
}
First, we set our FreeMarker information and generate the HtmlPage : two pages, page one is the current page. Then, we declare some expectations. makeExpectedLinks is a method generating the expected anchor links text. We pass an array of page numbers, and whether or not the previous and next links should be present:
private List<String> makeExpectedLinks(String[] links, boolean prev, boolean next) {
    List<String> expectedContent = new ArrayList<String>();
    expectedContent.addAll(Arrays.asList(links));
    if ( prev ) {
        expectedContent.add("Prev");
    }
    if ( next ) {
        expectedContent.add("Next");
    }
            
    return expectedContent;
}
The getPaginationLinks extracts the anchor tags from the html content. This is where HtmlUnit becomes useful. Here, we look for the pagination div and get all anchor elements.
private List<HtmlElement> getPaginationLinks(HtmlPage page) {
    HtmlDivision div = page.getHtmlElementById("pagination");
    return div.getElementsByTagName("a");
}
We make sure that the number of links meets our expectations : Assert.assertEquals(expectedContent.size(), pageLinks.size());. Then the content of the links are checked via the assertContainsLinks method :
private void assertContainsLinks(List<String> expectedLinks, List<HtmlElement> anchors) {
    List<String> anchorsText = new ArrayList<String>();
    for (HtmlElement htmlElement : anchors) {
        anchorsText.add(htmlElement.getTextContent());            
    }
    for( String expectedLink : expectedLinks ) {
        Assert.assertTrue("Expected page link["+expectedLink+"] was not found", anchorsText.contains(expectedLink));
    }
}

The current page is also checked via the assertCurrentPageIs method :
private void assertCurrentPageIs(HtmlPage page, String pageNo) {
 HtmlElement currentPage = getPaginationCurrent(page);
 Assert.assertTrue(!(currentPage instanceof HtmlLink));
    Assert.assertEquals(pageNo, currentPage.getTextContent());
}

From there, it's easy to make other tests for different page numbers and current pages:

@Test
    public void testPagination_twopages_currentistwo() throws IOException, TemplateException {
        // Make FreeMarker template
     setPaginationAttributes(2, 2);
        HtmlPage page = getHtmlPageFromTemplate();

        // page links
        List<String> expectedContent = makeExpectedLinks(new String[]{"1"}, true, false); 
        List<HtmlElement> pageLinks = getPaginationLinks(page);
        Assert.assertEquals(expectedContent.size(), pageLinks.size());
        assertContainsLinks(expectedContent, pageLinks);
        assertCurrentPageIs(page, "2");
    }

    @Test
    public void testPagination_threepages_currentistwo() throws IOException, TemplateException {
        // Make FreeMarker template
     setPaginationAttributes(3, 2);
        HtmlPage page = getHtmlPageFromTemplate();

        // page links
        List<String> expectedContent = makeExpectedLinks(new String[]{"1","3"}, true, true); 
        List<HtmlElement> pageLinks = getPaginationLinks(page);
        Assert.assertEquals(expectedContent.size(), pageLinks.size());
        assertContainsLinks(expectedContent, pageLinks);
        assertCurrentPageIs(page, "2");
    }

Running the tests under Eclipse shows the expected green bar :

Conclusion

Making FreeMarker macros and checking the content via a browser can be annoying and time wasting. The more branches you have in your logic, the more data you have to create. Changing the logic afterwards quickly becomes dangerous, unless you reuse the same data as before to make sure you've not broken the original logic. Unit testing the macro using JUnit, FreeMarker and HtmlUnit allows to prevent these problems.

Wednesday, December 22, 2010

Maven update remote indexes broken in IntelliJ10

I was trying to use Maven with IntelliJ10, but I could not update the indexes of the Maven Central Repository. After wasting a couple of hours, I found out that it was a know bug, IDEA-63043 Maven update remote indexes broken. Why do I keep running into all sorts of problems when using IntelliJ ? I love the interface and all the features it offers, but I wish I could use them at their full potential without having to look for bug reports.

Monday, December 20, 2010

JPA 2.0 with Spring 3.0 bug

I was trying to make a sample application using Spring3 and JPA2 on my new shiny IntelliJ IDEA 10, but stumbled quickly on a problem when I tried to run the application. Spring was complaining that the version attribute in my persistence.xml was wrong. It was set to "2.0", but Spring insisted that it could only be "1.0". I spent hours trying to figure out where the problem was. A wrong XMLSchema being picked up ? A problem with my JPA libraries ? A problem with my JPA provider ? No. The problem was coming from Spring itself (SPR-6711). Upgrading to Spring 3.0.5 fixed it. What a waste of time. It wouldn't have happened if I had used the latest libraries in the first place, instead of letting IDEA automatically import them (I guess version 3.0.0 were downloaded and added to my project).

Monday, November 8, 2010

Book review : Essential GWT: Building for the Web with Google Web Toolkit 2 (Developer's Library)

Essential GWT: Building for the Web with Google Web Toolkit 2 (Developer's Library)


Essential GWT is a misleading title. You could suppose, as I did, that it contains at least GWT basics. It doesn't. There is an overview of GWT, but nothing which will get you started if you're a beginner. So if you're expecting a tutorial about GWT development, widgets, etc..., pass your way. You should read another book or the online tutorial first. This book should have been named something like "Practical GWT Cookbook", as it contains some recipes about common web development topics like file uploading, security and much more.

I felt that the first half of the book was not very well structured. For example, I didn't understand why there is a paragraph on Code Generation in Chapter 4, Working with Browsers. Explanations are illustrated with code samples, but there are either too few, or too much. Too much, like the methods of the JDBC examples. Only one would have been enough. Too few, like the EJB example. Someone who knows EJB will know how to call a bean. Someone who doesn't will need much more information.

There are some annoying errors, especially in the MVP explanation. The same class gets three or four different names, making it very difficult to follow. MVP is an "essential" topic in this book, so it should have been carefully polished.

Nevertheless, the book still contains some interesting tips and techniques. I particularly enjoyed the speed measurement and the testing chapter. But overall I think it is falling short at explaining the essential.

Wednesday, November 3, 2010

Book review : Expert Oracle Database Architecture: Oracle Database Programming 9i, 10g, and 11g Techniques and Solutions, Second Edition

Expert Oracle Database Architecture: Oracle Database Programming 9i, 10g, and 11g Techniques and Solutions, Second Edition

No need to introduce Tom Kyte from "Ask Tom". Now imagine this great Oracle Database expert, sitting in front of you, lecturing about topics like table and index design or file management. Impossible you think ? Think twice. "Expert Oracle Database Architecture: Oracle Database Programming 9i, 10g, and 11g Techniques and Solutions" is Tom Kyte giving you a lecture. The book talks to you. The book forces you to open SQL*Plus and try yourself. This book is full of examples. Reading about databases might not be as fun as reading about programming, but you'll never get bored.

A chapter at the beginning of the book will help you create a proper test environment. Other chapters can be picked up in any order. In each chapter the author introduces some features, explains why you could be interested in them and how to use them. This includes tons of examples, common pitfalls and misuses.

I've been using Oracle Database for years, not as a DBA, but as a software developer. The amount of knowledge I have learnt with this book is tremendous. Tom Kyte has completely changed the way I see the database. Every developer using the Oracle Database should know more than just SQL. If you're one of them, grab this book as soon as possible.

Tuesday, October 5, 2010

Vimperator

Vimperator is a Firefox plugin which turns your browser into a kind of "Vi" for the web. If you like the Vi/Vim editor, you should give it a try. You can do most common tasks using the keyboard. After some experiment, I got addicted to it. Opening a link in the same tab, in a new tab, searching something with one of the installed search engines, filling forms, switching tabs... No need to reach for the mouse.

After installing it, the menu bar, navigation toolbar and bookmark toolbar will be hidden. This may be inconvenient at first, but you can display them again via ":set guioptions+=mTB". You can display the help screen at any time via the ":help" command.

Here is some of the commands I usually use :

  • Open a URL in the current tab : ":open ". Pressing tab while writing the url will show possible results.
  • Open a URL in a new tab : t
  • Open a link in the current tab : "f" followed by the number assigned to the link
  • Open a link in a new tab : "F" followed by the number assigned to the link
  • Click on a button, select a checkbox, move into a textarea... : "f" followed by the number assigned to the element
  • Close a tab : d
  • Open a previously closed tab : u
  • Use one of the search engines to search for some keywords : ":open ". The engine name is displayed in Firefox Search Engines dialog (:dialog searchengines). For example, ":open wikipedia something" will search for something on Wikipedia. To show the results in a new tab, use "t" or ":tabopen" instead of ":open"
  • Move around : h,j,k,l
  • Page Up/Down : Ctrl+f,Ctrl+b
  • Go to beginning/end of page : gg/G
  • Go forward/barckward in history : Ctrl+i/Ctrl+o
  • Go to next/previous tab : gt/gT
  • Reloading a page : r
  • Search in page : / followed by the keyword. After pressing enter, use "n"/"N" to go the next/previous occurence.
  • Copy the current URL in clipboard : y
  • Selecting text within a page : "i" to switch to CARET mode. This allows you to move at the beginning of the text you want to paste. "v" to switch to VISUAL mode to select the text, then "y" to yank it. "/" to search some text, before entering CARET mode is even faster.
  • Invoke gVim from a textarea : Ctrl+i. It helps if you have a long text to write.

There are other ways to browse efficiently. Check the help and find which one suits you best.

Tuesday, September 28, 2010

Book review : Eclipse Rich Client Platform, 2nd Edition

Eclipse Rich Client Platform will teach you how to create professional and redistributable RCP applications. Part I and II look like a tutorial, but the rest of the book goes far beyond. First, you will create a chat application, adding views, editors, actions, help, integrating a third party library... The style is clear, and the progression is logical. API details are left for Part III, where RCP indispensable components are discussed, and that is where the simple tutorial ends.

Part IV introduces more advanced features like p2, dynamic plug-ins, product configurations for various platforms, testing... I found that this part required more thinking than the rest of the book, but it is invaluable if you aim at making a professional application. The last part is a reference about Eclipse and OSGi.

If you plan to make an Eclipse RCP application, if you have some interest in it or in Eclipse plug-ins, if you just like the Eclipse IDE, this book is for you. You'll learn a lot about the Eclipse architecture, and you will learn it the easy way. I also own another book of the Eclipse Series, Eclipse Plug-ins, 3rd Edition, which I enjoyed a lot. I was not disappointed by Eclipse Rich Client Platform, 2nd Edition. I highly recommend it.

Wednesday, August 11, 2010

Beginning Java EE 6 with GlassFish 3, Second Edition delayed again

I'm looking forward to reading Beginning Java EE 6 with GlassFish 3, Second Edition. The book was supposed to be released at the end of July, but it has been postponed once to mid-August, and again to the end of August. Let's hope it's the last time the publication date is being delayed.

Tuesday, August 10, 2010

Grails 1.3.4 and the Functional Testing Plugin 1.2.7

I've reached the end of chapter 7 of Grails in Action, where functional testing is introduced. I was using Grails 1.1, but I encountered some problems with the Navigation plugin, so I upgraded to the latest version. The good news is that the Navigation plugin is now working fine. The bad news is that the Functional Testing Plugin is not ! "grails create-functional-test PostList" does not create PostListTests.groovy in the functional directory. It looks like somebody already reported that problem. No hands-on exercise this time. I'm not going to bother downgrading Grails to make it work.

Tuesday, July 27, 2010

Using the Tasks view effectively in Eclipse

There are times while coding when I know I have to do something, but it will take some time, so I decide to leave it for later. To remember the tasks I left, I'm using Eclipse Tasks, by writing a comment in the source, starting with "TODO". Before committing anything to a source repository, I always check that I don't have any unfinished tasks.

The Tasks view can be displayed via Window->Show View->Tasks. It shows a list of tasks. The default settings shows various type of tasks, including those with the word "TODO" or "FIXME" in it. In our project, there are a lot of unwanted TODOs left in the source. They all show up in the Tasks view.


Using a TODO is inconvenient, because I can't easily tell which are mine. The solution is to use a filter. Instead of writing a comment with "TODO ...", I use a comment with "TODO CHRIS...". By setting a filter in the Tasks view, I can show only tasks containing "TODO CHRIS".

In Eclipse Helios Tasks view, click the View Menu (the icon shaped as an arrow pointing downwards). Select Configure Contents. Then press New... to make a new configuration. I set the scope to "On any element". I leave all the Completed, Priority and Types check boxes selected. Set the description to "contains" and "TODO CHRIS". This will include my comments. Finally, I check my configuration, set the "show results matching" to "Any enabled filter" and press OK. Voila ! All unwanted default tasks disappear, and only my own tasks are shown.


By the way, default Task Tags in Java comments can be configured in the Preferences, in Java->Compiler->Task Tags. Default tags include "FIXME", "TODO" and "XXX".

Monday, July 26, 2010

My top 10 Eclipse keyboard shortcuts

Keyboard shortcuts are time-savers. Surprisingly, not many people around me use them. Programming is much more fun when you can control most of the action via the keyboard. I introduce some of the shortcuts I use the most in Eclipse. I don't bother mentioning some very common ones, like Ctrl+S for saving, or the king of all, Ctrl+Space, for auto-completion. Here is my top 10 Eclipse keyboard shortcuts to beat the uninitiated.

Ctrl+. : Navigate to the next item. When there are errors in the source, this jumps to the next error. The uninitiated uses his mouse and clicks on the little red square, or clicks in the Problem view, or worse, PgUps/PgDowns to the error. Press Ctrl+. while he is still scrolling his way to the error.

Ctrl+1 : Quick Fix. This will bring a list of possible fixes for errors. For example, on a method which does not exist, it will show fixes like "Create method in...", "Rename method to...", etc... The uninitiated hovers over the error to display the quick fix, which is not so bad after all. But the Ctrl+. Ctrl+1 double combo leaves him way behind.

Ctrl+E : Quick Switch Editor. Open the editor drop down list. Very useful when you have many resources open. The uninitiated clicks on a tab. When there are too many tabs, he clicks on the "Show List" icon and looks for his tab in the list, without even typing the name of the tab, because he still has his hands scotched on the mouse.

Ctrl+Shift+G : Search for references in workspace. Use this on variables, methods, classes to quickly find out where they are used. This one always leaves the uninitiated on their butt :)

Ctrl+Shift+R : Open resource. When you get used to a project and want to quickly jump to a resource, like a properties file, this is very useful. The uninitiated browse through the Package Explorer or Navigator view to find it.

Ctrl+Shift+T : Open type. Like the previous shortcut, but for types. I use it a lot.

Alt+Shift+R : Rename and refactor. This allows to not only rename a variable, method, class, etc..., but also to refactor the places which use the entity being renamed. The uninitiated renames it by hand, and goes through all errors to fix it. I'm exaggerating, aren't I ? But, I'm curious to know how many uninitiated go to the Navigator view, right-click on a class, and choose "Rename..." to rename a class ?

Ctrl+O : Quick outline. In a class, this allows to quickly jump to a method. The uninitiated uses the Outline view, or worse, Ctrl+F (ouch). Ctrl+O is a knock out shortcut.

Ctrl+Shift+O : Organize imports. I always leave Eclipse manage imports. Especially for unused imports. Auto-completion also takes care of the imports most of the time. The uninitiated uses his mouse to do the same.

Ctrl+F8 : Select perspective. Press repeatedly to cycle through available perspectives. Again, the uninitiated uses his mouse.

That's it ! I don't think that you have to remember a lot of shortcuts to increase your productivity, but these surely help me increase it. Think about the actions you often do and make your own list !

Friday, July 23, 2010

Removing unwanted kernels in Ubuntu and updating Grub2 configuration

The installation of a new kernel adds two new entries in the Grub menu. I have set the default selected entry to something different from the first item, so each time a new kernel is installed, the default entry points to the wrong menu item. Using update-grub will automatically update all Grub2 configuration files, and that's when the kernels present in the file system are automatically detected (Grub2).

I want to remove the old kernels, which I won't need anymore. There are several ways to do it. I'll show how to do it on the command line. First, let's list the installed kernels


dpkg -l | grep linux-im

ii linux-image-2.6.32-23-generic 2.6.32-23.37 Linux kernel image for version 2.6.32 on x86
ii linux-image-2.6.32-24-generic 2.6.32-24.38 Linux kernel image for version 2.6.32 on x86
ii linux-image-generic 2.6.32.24.25 Generic Linux kernel image


Here, we see package names and package version numbers. The syntax to completely remove packages is "apt-get purge packagename". Let's remove the unwanted kernel image, which is 2.6.32-23.37. The string used after "purge" is a regular expression. I don't bother to escape it.

sudo apt-get purge .*.2.6.32-23

All packages matching this regular expression will be completely removed. This operation must be done with caution. Fortunatly, before packages are removed, a confirmation will be displayed (in Japanese in my local environment):

以下のパッケージは「削除」されます:
linux-headers-2.6.32-23* linux-headers-2.6.32-23-generic*
linux-image-2.6.32-23-generic*
アップグレード: 0 個、新規インストール: 0 個、削除: 3 個、保留: 0 個。
この操作後に 184MB のディスク容量が解放されます。
続行しますか [Y/n]? Y

This shows that three packages will be removed. That's what I was expecting. After accepting the changes, the Grub configuration will be automatically updated ! No need to update it yourself.

Running postrm hook script /usr/sbin/update-grub.
Generating grub.cfg ...
...
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-2.6.32-24-generic
Found initrd image: /boot/initrd.img-2.6.32-24-generic
Found memtest86+ image: /boot/memtest86+.bin
Found Microsoft Windows XP Home Edition on /dev/sda1
Found Windows NT/2000/XP on /dev/sda3
done

Voila ! The unwanted kernels should be gone from the file system and from the Grub menu.

Thursday, July 22, 2010

Griffon 0.9 released

Griffon 0.9 is out, with a bunch of bug fixes and new features. Once thing which caught my eyes was Spock. It's not a name easy to miss ! But it's the first time I hear about it. Yet another framework on my todo list.

Sadly, I've stopped studying Griffon recently. My lack of Groovy/Grails knowledge is wasting all the fun. I've decided to study Groovy and Grails first, as Griffon is not only based on Groovy, but it also gets a lot of its inspiration from Grails. I bought Grails In Action and started studying it. There's a whole chapter on Groovy basics. Developping Grails application helps to get used to it. I must say that this is a very cool framework ! Once I'm finished with it, I plan to go back to Griffon, and restart reading Griffon In Action's MEAP book.

I'm late to dive into the Groovy world. There's so much I have to do to get back on tracks. But the efforts are well worth it. Groovy is fun. Grails is fun. But I'm yet to know just how fun it can be.

Friday, July 9, 2010

Preventing services to startup at boot time in Ubuntu

After installing Tomcat6 via the Synaptic package manager, Tomcat is automatically started at boottime. This was fine, until I started playing with Grails. Without changing any configuration settings, Grails will start its own web server instance at the default http port, 8080, the same as Tomcat's default. This results in an error when trying to start a Grails application :

grails run-app

Server failed to start: java.net.BindException: Address already in use

There are different ways to avoid this error. Make Grails use Tomcat's instance, change either Grails or Tomcat's default http port, or don't start Tomcat at boot time. I decided to remove Tomcat's automatic startup. How do we do that in Ubuntu ?

Init scripts are in /etc/init.d, and symbolic links to these scripts are separated in runlevels, each residing in /etc/rcX.d/, where X is the runlevel. We could remove them by hand, but this can be done easily with one single command : update-rc.d

sudo update-rc.d tomcat6 disable

update-rc.d: warning: tomcat6 start runlevel arguments (none) do not match LSB Default-Start values (2 3 4 5)
update-rc.d: warning: tomcat6 stop runlevel arguments (none) do not match LSB Default-Stop values (0 1 6)
Disabling system startup links for /etc/init.d/tomcat6 ...
Removing any system startup links for /etc/init.d/tomcat6 ...
/etc/rc0.d/K20tomcat6
/etc/rc1.d/K20tomcat6
/etc/rc2.d/S20tomcat6
/etc/rc3.d/S20tomcat6
/etc/rc4.d/S20tomcat6
/etc/rc5.d/S20tomcat6
/etc/rc6.d/K20tomcat6
Adding system startup for /etc/init.d/tomcat6 ...
/etc/rc0.d/K20tomcat6 -> ../init.d/tomcat6
/etc/rc1.d/K20tomcat6 -> ../init.d/tomcat6
/etc/rc6.d/K20tomcat6 -> ../init.d/tomcat6
/etc/rc2.d/K80tomcat6 -> ../init.d/tomcat6
/etc/rc3.d/K80tomcat6 -> ../init.d/tomcat6
/etc/rc4.d/K80tomcat6 -> ../init.d/tomcat6
/etc/rc5.d/K80tomcat6 -> ../init.d/tomcat6

There are a couple of warning because I used the disable command without any parameters. These can be ignored. As the man page says : "If no start runlevel is specified after the disable or enable keywords, the script will attempt to modify links in all start run‐levels.". Enabling back the service at bootime is as simple (same warnings):

sudo update-rc.d tomcat6 enable

update-rc.d: warning: tomcat6 start runlevel arguments (none) do not match LSB Default-Start values (2 3 4 5)
update-rc.d: warning: tomcat6 stop runlevel arguments (none) do not match LSB Default-Stop values (0 1 6)
Enabling system startup links for /etc/init.d/tomcat6 ...
Removing any system startup links for /etc/init.d/tomcat6 ...
/etc/rc0.d/K20tomcat6
/etc/rc1.d/K20tomcat6
/etc/rc2.d/K80tomcat6
/etc/rc3.d/K80tomcat6
/etc/rc4.d/K80tomcat6
/etc/rc5.d/K80tomcat6
/etc/rc6.d/K20tomcat6
Adding system startup for /etc/init.d/tomcat6 ...
/etc/rc0.d/K20tomcat6 -> ../init.d/tomcat6
/etc/rc1.d/K20tomcat6 -> ../init.d/tomcat6
/etc/rc6.d/K20tomcat6 -> ../init.d/tomcat6
/etc/rc2.d/S20tomcat6 -> ../init.d/tomcat6
/etc/rc3.d/S20tomcat6 -> ../init.d/tomcat6
/etc/rc4.d/S20tomcat6 -> ../init.d/tomcat6
/etc/rc5.d/S20tomcat6 -> ../init.d/tomcat6

To disable the running service without having to reboot:

sudo /etc/init.d/tomcat6 stop

* Stopping Tomcat servlet engine tomcat6 [ OK ]

After that, Grails applications will be happy to run:

grails run-app

Welcome to Grails 1.1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /usr/local/lib/grails-1.1.1

Base Directory: /home/kuriqoo/eclipse/workspace/hubbub
Running script /usr/local/lib/grails-1.1.1/scripts/RunApp.groovy
Environment set to development
Running Grails application..
Server running. Browse to http://localhost:8080/hubbub

Tomcat can be manually started using :

sudo /etc/init.d/tomcat6 start

* Starting Tomcat servlet engine tomcat6
Using CATALINA_BASE: /var/lib/tomcat6
Using CATALINA_HOME: /usr/share/tomcat6
Using CATALINA_TMPDIR: /tmp/tomcat6-tmp
Using JRE_HOME: /usr/lib/jvm/java-6-openjdk
Using CLASSPATH: /usr/share/tomcat6/bin/bootstrap.jar [ OK ]

Thursday, July 8, 2010

Oracle updating the Sun Java Certifications

Oracle is starting to change the Sun Certifications. There are already four exams in Beta stage :

* Sun Certified JPA Developer for the Java EE6 Platform
* Sun Certified Developer for the Java Web Services for the Java EE6 Platform
* Sun Certified JSP and Servlet Developer for the Java EE6 Platform
* Sun Certified EJB Developer for the Java EE6 Platform

SCBCD5.0 included JPA1.0 in it. Now JPA has its own exam, so if you want to be a Business Component Developer, you'll have to pay two exams. Beta exams were free in the past. Oracle has decided to get a few bucks out of them. You pay $50 to attend the Sun Certified JSP and Servlet Developer for the Java EE6 Platform beta exam, and spend 3 to 5 hours answering 215 questions ! Good luck. The exam objectives are still very evasive, contrary to the old ones which were very detailed. I mean, in the JPA certification, what is "Optimize database access" and "Use advanced JPA features" supposed to include ? If I decide to upgrade one day, I'll wait for the official one. No beta for me.

JavaRanch and the Big Moose Saloon

JavaRanch and its Big Moose Saloon is a great place to go for anybody interested in Java. If you have a Java problem, go there. If you want to pass a Sun (Oracle) certification like SCJP, SCWCD, SCBCD..., go there. There are also forums for Groovy, Scala, Javascript...

Some of the top reasons why you should be a member :

1. It's a very friendly place. No insults. No "you don't even know that ??" kind of mockery. When you sign there, the first thing you are told is to "Be Nice". It's the number one JavaRanch policy. It's a nice place.
2. The place is kept clean by a bunch of bartenders and sheriffs (ranchy names for moderators), whose first rule is also to "Be Nice". There's no exception to the rule. We are all here to help each other.
3. You'll find people answering your problems relatively quickly. I rarely see questions left unanswered.
4. Answers are usually checked by moderators, leading into constructive arguments or more elaborate answers.
5. You'll find great materials and advices to pass the Sun certifications. Advices given by other members who actually passed the exam.
6. You'll meet book authors, some of them being regual members.
7. One of the original goal of the forum was to help people. So insteading of giving away code snippets for coding problems, we tend to lead people toward the answer, to make them think by themselves. This may take some time, but it's really worth it.
8. The ranch listens to you, and you can help it change. If you have any request concerning the forums, people will listen to you, and debate whether or not your ideas could be applied.
9. You'll have a chance to win free books ! A book promotion is conducted almost every week, where book or software authors spend a week answering members' questions about their product. Don't miss it.

I love being there, helping others solving their problems. I learned a lot thanks to the ranch. Not only about Java, but also about dealing with problems. It's also a great motivation to be there, being surrounded by software experts. It's sometimes challenging to "Be Nice". I think things would easily get out of hands in other forums. But not at JavaRanch. You'll be in good hands.

So, what are you waiting for ? Join this great community.

Sunday, July 4, 2010

Book review : Beginning Oracle Database 11g Administration: From Novice to Professional

I have finished reading the book "Beginning Oracle Database 11g Administration: From Novice to Professional (APress)", by Iggy Fernandez. First of all, I am not a DBA. I'm using Oracle at work, but, most of the time, I'm only using basic SQL. I have nothing to do with database administration, but recently I wanted to know more about Oracle, and this book is just what I needed. The author doesn't go deeply into details, which that is not the purpose of the book. He introduces the most important topics (installation, monitoring, backups, recoveries, tuning...) in a very understandable manner. I don't think that this book will turn anyone into an Oracle Professional, as the title suggests, but it does cover enough material to make you more than a novice. I recommend it highly to anyone who wants to know the basic notions of the Oracle architecture and administration.

I plan to buy "Expert Oracle Database Architecture: Oracle Database Programming 9i, 10g, and 11g Techniques and Solutions" by Thomas Kyte, which is planned to be published this month. For the moment, I'll start reading the Oracle Concepts PDF file, which is available online.

Thursday, June 24, 2010

Eclipse Marketplace in Eclipse Helios

Eclipse Helios is out, it's time to check some of the new features. Helios comes with a new system to manage plugins even more easily than before : the Eclipse Marketplace. Gathering softwares, third-party tools, plugins, etc... and making them easily accessible is becoming a trend these recent years. Android Market, iPhone App Store, you name it.

Until Eclipse Galileo, the easiest way to install plugins was to :
1. Search for the plugin on Internet (by using the Eclipse Plugin Central for example)
2. Get the Update Site URL to be used in Eclipse's Update Manager
3. Go to Eclipse Update Manager, register the plugin host using the Update Site URL
4. Follow the instructions to install the plugin

Now, with the Eclipse Marketplace, no need to leave Eclipse :

1. Access the Eclipse Marketplace via the Help menu
2. Search for the plugin by entering some relevant keywords
3. Click the Install button of the plugin
4. Follow the instructions to install the plugin

I needed to use SubVersion on my freshly installed Helios. Let's see what the Eclipse Marketplace looks like and how easy it is to install plugins.

1. Access the Eclipse Marketplace via the Help menu.


2. Search for the plugin by entering some relevant keywords.


3. Click the Install button of the plugin (I chose Subversive).


4. Follow the instructions to install the plugin, and restart Eclipse. The Subversive plugin is now listed in the Installed tab of the Eclipse Marketplace.


Friday, May 21, 2010

Griffon ShutdownHandler sample

Here is a simple ShutdownHandler (available since 0.3.1) sample. For simplicity, I just made the main controller implement the new ShutdownHandler interface. All it does is to print a message during shutdown, but we can imagine that it could do much more clever things. The most interesting method is canShutdown. In this sample, it always returns true, so the application will normally shutdown. Depending on some conditions, we could make it return false, to prevent the application to shutdown.

import griffon.core.*

class GriffonsampleController implements ShutdownHandler {
 def model
 def view

 void mvcGroupInit(Map args) {
  app.addShutdownHandler(this)
  }
 
 boolean canShutdown(GriffonApplication app) {
  return true;
 }
 void onShutdown(GriffonApplication app) {
  println "Shutting down..."
 }
}

GRIFFON-176

According to one of the author of Griffon, the problem I encountered on Griffon with spaces in directories (GRIFFON-176) seems to be related to GRIFFON-156. The good news is that the bug level has been raised to critical. I hope this is going to be fixed as soon as possible. Until then, I'll use Griffon with the command line on Ubuntu only.

Thursday, May 20, 2010

Griffon run-app error at Windows prompt

I've been using Griffon on Windows with IntelliJ, and on Ubuntu with Eclipse. In order to check the changes of Griffon 0.3.1, I tried to use it on Windows command line for the first time. "griffon create-app" ended successfully, but "griffon run-app" didn't.


D:\temp\java\griffonsample>griffon run-app
Welcome to Griffon 0.3.1 - http://griffon.codehaus.org/
Licensed under Apache Standard License 2.0
Griffon home is set to: D:\jar\griffon-0.3.1

Base Directory: D:\temp\java\griffonsample
Running script D:\jar\griffon-0.3.1\scripts\RunApp.groovy
Environment set to development
Warning, target causing name overwriting of name default
java.lang.NoClassDefFoundError: and
Caused by: java.lang.ClassNotFoundException: and
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
Could not find the main class: and. Program will exit.


I guess it's because of my home directory being in C:\Documents and Settings\. I found a similar bug related to using space in directories, GRIFFON-156. But it's not quite the same problem, because I don't think it's related to the java.library.path variable. I think I'll report the problem.

UPDATE : I have posted the problem. It is reported as GRIFFON-176.

Wednesday, May 19, 2010

Griffon 0.3.1 is out

Griffon 0.3.1 is out. Shutdown handlers were added, to allow to do something during the shutdown process, or to allow to abort it. Another new feature is the ability to know the running mode of the application : STANDALONE, WEBSTART or APPLET. Apart from that, the good news is that the downloadable package now contains the Griffon Guide.

Sunday, May 9, 2010

Ubuntu 10.04 breaking old habits

I updated Ubuntu to the latest 10.04 and the first thing I noticed is that the minimize/maximize/close window buttons were moved from the upper right corner, to the upper left corner. At first, I thought this was not a big deal. But after a few hours, it happens to be really annoying. How can I suddenly break a more than 10 years old habit ? No matter what, I keep looking for these buttons in the upper right corner. I definitely had to put them back to where they belong. How do we do that ?
  1. Open the gconf-editor (Alt+F2 and type gconf-editor)
  2. Search for the apps/metacity/general/button_layout key
  3. Double click it and change it to menu:maximize,minimize,close
  4. Click Ok, and the buttons should be back to the upper right
Another change in the default layout is that the maximize button comes before the minimize button. I didn't even notice it, so I'm fine with the current order.

Thursday, April 22, 2010

IntelliJ IDEA 9.0.2

IntelliJ IDEA 9.0.2 is out. The list of improvements is here. Things I'm going to have a look at are the database access improvements and the UML-like diff tool. Well unless that annoying bug is still there... After some research, that bug was already reported as bug IDEA-23472.

I tried the database console, using a locale PostgreSQL database.
I wonder if we can copy/paste the result of the SQL query, including the column names.

Tuesday, April 20, 2010

SyntaxHighlighter in Blogger

As I plan to post code in my blog, I searched for a way to use the SyntaxHighlighter library. There are some good installation explanations here.
System.out.println("Great!");

Monday, April 19, 2010

IDE under Ubuntu

I had Ubuntu 9.4 for a while on my laptop, but I was not using it much. I can't tell why. Recently, after spending some time trying to remember which password I was using, I decided to go back to it. I upgraded to 9.10, installed Compix Fusion and Awn, and start playing with all sorts of configurations. Compix is crazy ! If you decide to install Ubuntu, you have to try it. Ubuntu is a lot of fun, and it's fast ! Booting is fast, launching applications is fast. I can't come back to Windows without getting frustrated by the time I have to wait until I can launch an application.

Until now, I was using both IntelliJ and Eclipse on Windows. The first thing I did was to install both on Ubuntu. After setting a few environment variables, I started IntelliJ. It worked. It worked very well. I made a new Griffon project, and started some coding. I like IntellJ's Griffon view, with the Model, View and Controller folders. It was fun... until the focus cursor went wild. No more focus. No matter where I clicked, the window was not responding to the keyboard anymore. After restarting IntelliJ, everything was back to normal. But then the focus cursor went wild again. I searched the web for similar problems, and it seems that many people have this problem on Ubuntu. After wasting some time trying some of the suggestions I read, I gave up, and turned back to Eclipse.

Eclipse Gallileo works like a charm. CTRL+Space was already mapped to the Input Method Editor(IME), so I just had to change the IME settings and remove CTRL+Space from the hook list. Apart from that, I haven't encountered any particular inconvenience yet.

Friday, April 16, 2010

Discovering Griffon



 According to Griffon's homepage,

Griffon is a Grails like application framework for developing desktop applications in Groovy. Inspired by Grails, Griffon follows the Convention over Configuration paradigm, paired with an intuitive MVC architecture and a command line interface. Griffon also follows the spirit of the Swing Application Framework (JSR 296), it defines a simple yet powerful application life cycle and event publishing mechanism.

Why should I be interested in Griffon ? First of all, the project I've been working on for several years is based on Swing. Swing's pitfalls and inconveniences are no secret anymore, so I was curious to know how Griffon could help in developing Swing applications. Another reason is that I have never used Groovy yet, so I found this was a good opportunity to hit two birds with one stone, learning both Groovy by using Griffon.

I heard about the book Griffon In Action at JavaRanch, and decided to give it a try. The book, edited by Manning, is still in its MEAP phase, so only a few chapters are available. The chapters I have read so far are very interesting, and I was amazed by the way we could use Groovy and Griffon to develop Swing applications in a breeze.

I like the way the Model, View, Controller can access each other via implicit injections, and the way the Model gets bound to the View's components. Much easier than trying to access Swing's JFrame components. I also like the way the View is constructed with Groovy, although I wonder how messy this might become if we try to make screens made of a lot of components. I will have to spend some time trying to use Abeille Forms to make more complex screens.

Swing's Event Dispatcher Thread (EDT) is something we have to be particularly aware of, and this is no exception when using Griffon. But making things run in or out of the EDT is made somewhat simple via the SwingBuilder and its "edt" related methods.

I doubt that I will ever use Griffon at work, but I think it's still worth studying. I will try to illustrate some of Griffon's features in other posts.