Kontakt

Archive for November, 2010

Call For Reviewers

Mittwoch, November 24th, 2010

As you probably know currently I’m writing a “Tapestry 5 in Action” book to be published by Manning Publications Co.

Yesterday I had a chat with my contact at Manning. We discussed the further steps which needs to be done before MEAP. Among other things we need 5-10 technical reviewers on a voluntary basis. If you want to participate on the project, just drop me a line. Unless I know you from the Tapestry’s community, please describe your experience with Tapestry. Note that not only experts but also Tapestry newbies are needed. So, feel free to contact me. We will choose the best combination of beginners, advanced users and experts.

Response to Matt Raible’s Presentation at Devoxx 2010

Sonntag, November 21st, 2010

This week I was attending Matt Raible’s talk Comparing JVM Web Frameworks at Devoxx 2010. Matt came up with a matrix containing grades for a chosen set of features in various frameworks. The top 5 frameworks in the matrix has been presented in details. Unfortunately Tapestry got 13.5 points, only 1 point behind Wicket/Struts 2 (both 14.5 points).

I have no problems with being behind any framework if the comparison is made accurate. But in this case I feel like I need to defend Tapestry because I disagree with some of the grades given by Matt. The problem is that Matt is very famous and a lot of Java developers believe him blindly. Matt, you should be aware of it and be very careful by making any statements.

I talked to Matt after his presentation and promised him to send some links which will hopefully improve Tapestry’s grades. But Matt’s comparison caused a lot of discussions over the world, so I decided to write a public answer.

Here are some few grades I disagree with:

Developer productivity

I cannot understand why Tapestry didn’t get 1 point for developer productivity. C’mon Matt, did you ever hear about Tapestry’s Live Class Reloading feature which allows you to change your code and see the results immediately? You have mentioned that JRebel can boost developer productivity but forgot to mention that Tapestry has a similar functionality which is built-in.

Do you really believe that GWT, which requires an additional Java-to-JavaScript compile step, offers a better developer productivity? Sorry, but even GWT users I know don’t believe it.

Is Spring MVC really more productive than Tapestry? Is it because JSPs are better to read and to debug than Tapestry’ HTML templates? Or is it XML-based configuration that outweighs Tapestry’s annotation and convention-over-configuration approach?

Developer perception

Uh? Zero? Is it really that bad? Matt, your last mail on Tapestry’s user list was on 11th November 2009. One year is a long time. You should read the comments of new users who are enjoying learning Tapestry.

Indeed, the Tapestry team have been very bad in marketing but it will change. The new web site has been launched yesterday. The documentation has been improved. A German book on Tapestry 5 has been published. Currently I’m working on a translation of this book for Manning Publications Co. I’m pretty sure the “Tapestry 5 in Action” will make Tapestry more successful.

I’m talking on Tapestry very often and get a lot of feedback from Java developers. My impression is that the developer perception is better than zero. Much better.

Project Health

The first stable release of Tapestry 5, namely version 5.0.18, was released on 12th December, 2008. Since that time we successfully released 5.1.0.5 and 5.2.4 without to break any backward compatibility. Two major releases with various innovations and without any backward compatibility issues in two years. Isn’t it a healthy project? Shouldn’t you all forget the Tapestry’s bad reputation of backward compatibility? It is history now.

Scalability

One of Tapesry’s goals is scalability. Tapestry was built with scalability in mind and that’s why has a lean session usage. Tapestry claims to be scalable and you should read it in Tapestry’s documentation. Again, why not the best grade for this feature? Why do Struts 2 or GWT scale better? Did you try to scale a Tapestry application? I guess not.

Testing

C’mon Matt. Are you kidding? Tapestry is built for testability and provides a very nice testing functionality. I guess this coverage report tells everything.

Moral of the story

There are even more points which are better in Tapestry than they appear to be. If only the mentioned points have been rated accurately, Tapestry would easily make it to the top 5 frameworks in Matt’s presentation.

The moral of the story is: even though Matt Raible is a very respected person, you should not blindly rely on everything he tells you. Some frameworks are much better than some people speak about them. Give them a try and decide if they fit your needs.

Find Your Elements

Donnerstag, November 18th, 2010

In the last post I described the enhancements on PageTester which will improve the testability of your Tapestry applications. In this post I would like to show you a further improvement which will make your life easier when writing tests. In the following example you can see a simple example on how to render a page named SimplePage. The markup of the page contains a link that you want to click inside the test. So, the returned Document instance can be used to find the link by its client id. This can be done by passing the id of the link to th getElementById() method. The result of the method is an Element, if found, which represents the link.

public class SimplePageTest {

   private PageTester tester;

   @Test
   public void click() {
      Document doc = tester.renderPage("SimplePage");

      Element link = doc.getElementById("myLink");

      doc = tester.clickLink(link);

      assertTrue(doc.toString().contains(
         "Tapestry 5 Test"));
   }

   ...
}

Frequently it is easier to find an element inside a document by its name or any arbitrary attribute than by the client id, but unfortunately this was not possible with Tapestry till now. So last week I committed some changes which will be available in the upcoming 5.2.4 release.

In the following example you can see an example how to find an element which has class attribute set to value fancy.

public class SimplePageTest {

   private PageTester tester;

   @Test
   public void click() {
      Document doc = tester.renderPage("SimplePage");

      Element root = doc.getRootElement();

      Element link = root.getElementByAttributeValue(
                          "class", "fancy");

      doc = tester.clickLink(link);

      assertTrue(doc.toString().contains(
            "Tapestry 5 Test"));
   }

   ...
}

If you want more flexibility when finding your elements, you may provide a Predicate which is responsible to accept or decline an Element. This predicate will be used when Tapestry iterrates over all elements inside a Document. The first accepted Element is returned. Note that widht-first search is performed.

public class SimplePageTest {

   private PageTester tester;

   @Test
   public void click() {
      Document doc = tester.renderPage("SimplePage");

      Element root = doc.getRootElement();

      Element link = root.getElement(
         new Predicate<Element>(){
            public boolean accept(Element e) {
                return "a".equals(e.getName());
            }
        });

     doc = tester.clickLink(link);

      assertTrue(doc.toString().contains(
            "Tapestry 5 Test"));
   }

   ...
}

Hope this helps you to improve the tests of your Tapestry applications.

Improved Testing Facilities

Dienstag, November 16th, 2010

Tapestry provides a very nice functionality which allows you to test your applications without any servlet container. The PageTester class is used to run a Tapestry application inside a test and render certain pages of the application. As shown in the following example, you can initialize a PageTester instance by providing:

  • the root package of the application. This is the same value you would specify using the tapestry.app-package context parameter inside web.xml.
  • Application name. This is the same value you would specify as the filter name inside web.xml.

The initialized PageTester instance may be used to render a page by its name. The return value of the renderPage() method is an instance of Document. A Document represents the root node of the DOM of the rendered page and may be used to perform asserts.

public class SimplePageTest {
   private PageTester tester;

   @BeforeClass
   public void setup() {
      tester = new PageTester(
            "org.example.testapp", "app");
    }

   @Test
   public void simple_test() {
      Document document = tester.renderPage("SimplePage");

      String markup = document.toString();

      assertTrue(markup.contains("Tapestry 5 Test"));
   }
}

This functionality allows you to test your pages with minimal effort but has a limitation: there is now way to test pages which don’t have a template. For example it is not possible to test the following page as there is no markup to assert against. So, PageTester fails to create an instance of Document and your tests fails.

public class SimplePage {

   Object onActivate() {
      return new HttpError(
         HttpServletResponse.SC_MOVED_TEMPORARILY,
         "Oups! Resource moved. Try again later.");
   }
}

Last week I committed some improvements on PageTester which provide you the full access to the response generated when the page was rendered. Instead of renderPage() method you can use the renderPageAndReturnResponse() method which returns an instance of TestableResponse. A TestableResponse is a testable extension of Response to perform asserts against. In the following example you can see how to assert the HTTP error sent by the page above.

public class SimplePageTest {

   @Test
   public void http_error) {
      TestableResponse response = tester
                .renderPageAndReturnResponse("SimplePage");

      assertEquals(
         response.getStatus(),
         HttpServletResponse.SC_MOVED_TEMPORARILY);

      assertEquals(
         response.getErrorMessage(),
         "Oups! Resource moved. Try again later.");
   }
}

You can also access the HTTP headers set during rendering the page or read the data written into ServletOutputStream.

public class SimplePageTest {

   @Test
   public void http_error() {
      TestableResponse response = tester
                .renderPageAndReturnResponse("AnotherPage");

      assertEquals(
         response.getHeader("my-header"),
         "foo");

      assertEquals(
         response.getOutput(),
         "<html><body>Bla bla</body></html>");
   }
}

For further details check out the classes PageTester and TestableResponse. There is more new stuff which will simplify testing of Tapestry applications.

Happy testing.

Summary: Tapestry Talk at eJUG

Samstag, November 6th, 2010

As posted earlier, I was giving a Tapestry talk at Enterprise Java User Group (eJUG) Austria on November 2nd. This presentation was quite different than most of my Tapestry talks as almost the half of the attendees (around 35 ) had already experience with Tapestry. Quite many attendees have already read my book. I’ve got some feedback from them and even some praise.

I also had a chance to meet some interesting people like Juergen Hoeller and Peter Niederwieser. Before the presentation me, Juergen Hoeller and Martin Ahrer had a lunch. We had a small talk on programming, open source and other stuff. I was quite happy that Juergen attended my Tapestry talk as I wanted to show him Tapestry IoC. Peter Niederwieser is the creator of the spock framework and Groovy committer. He is using Tapestry at his company and had already provided some interesting patches. I’m very happy to have met him. We talked a lot about his framework and I’m very enthusiastic about trying it out (there is a Tapestry integration). I also met Christian Köberl and Kristian Marinkovic, who are working for Porsche Informatic. I know these two guys from the Tapestry community, but never met them in person before.

Meeting a lot of Tapestry folks was a pleasure for me. I enjoyed it very much so that I start thinking about organizing a Tapestry meet-up in 2011. If you are reading this blog and like the idea, just drop me a line.

Many thanks to Martin Ahrer and Juergen Hoeller for inviting me to eJUG. I would love to come again.

Tapestry 5 Blog - Copyright © 2009 - Eclectic Theme by Your Inspiration Web - Powered by WordPress