Blog

Blog

Here comes yet another beautiful little module called tapestry-routing.

In a nutshell, tapestry-routing allows you to provide your own custom mapping between Tapestry pages and URLs.

Did you ever wanted to change the order of the path params in an URL? now you can!

Let's say you have a page: pages.projects.Members which have 2 parameters in its activation context: (Long projectId, Long memberId) and you want the URL for that page to look like /projects/1/members/1 Just add the @At annotation to you page, like this:

That's it!
tapestry-routing Dispatcher will take care of recognizing incoming requests and dispatching the proper render request
tapestry-routing PageRenderLinkTransformer will do the rest of the work, it will transform every Link for a page render request formatting it according to your route rule.

We really need some feedback, so please give it a try:http://tynamo.org/tapestry-routing+guide

Enjoy!

Whoops, almost forgot to announce the release of our latest module here: 0.0.1 version of tynamo-federatedaccounts with Facebook Oauth is now out! Additional openID & Oauth providers to follow. More at tynamo-federatedaccounts guide. Also see the previous blog entry for more information.

Release notes:

Improvement

TYNAMO-74 - Support inline Facebook oauth permission screen

New Feature

TYNAMO-72 - Initial implementation of Facebook Oauth
TYNAMO-73 - Initial implementation of federatedaccounts sample
running on GAE
TYNAMO-80 - Implement different windowmodes for Facebook oauth

Here's what Alejandro (the co-founder of Tynamo) had to say about the module:
I don't know if we should release this module, It's so easy to use that's not fair for people that suffered the Facebook nightmare. I want people to suffer as I DID!!! Damn it Kalle!! Excellent work! (smile)

Also check out the live example of federatedaccounts. Enjoy!

Last week, I was working on improving the initial implementation for federatedaccounts. Some of you might have preferred that I spend my time implementing more OAuth providers or a generic OpenId provider but since I have the itch to scratch, I instead decided on implementing a configurable window mode for the existing Facebook Oauth integration, in order to improve its usability and customizability. Now, the window mode refers to how the (the response to the) callback URL is presented to the user. Three basic choices is either self, blank or inline. See our federatedaccounts demo if you don't know what these mean. Self and blank should be straight-forwarded, but by attempting to implement inline (just to see how far I'd get with it...), i.e. an (i)frame-based window mode, I of course landed right in the middle of the whole clickjacking or UI redressing attack controversy. The core problem is that browsers and the html standards don't provide any good, end-user friendly means for verifying the origins of an iframe content. Therefore, the security conscious Oauth folks (see e.g. http://simonwillison.net/2009/Jul/16/responsibility/) say (rightly so) that you should never ever allow processing an Oauth request in an iframe since the URL is not shown to the user and it's simple to fake the dialog UI. In contrast, the user experience experts argue that popping out windows or suddenly transferring the user to a different site makes the user feel more confused and insecure (see e.g. http://drstarcat.com/archives/133), and that the frame busters are meaningless as the majority of users won't pay any attention to the URL anyway. I happen to agree with both sides. Relying on the user to validate the URL, especially without any additional visual clues (compare to how modern browsers display https URLs with valid SSL certifates) is way too weak as a real security measure, but if that's all you got, it's certainly better than nothing. On the usability side, launching a new browser window, or doing a full page refresh, is somewhat confusing and way slower than loading content into a pre-existing iframe. What's lost in all of this, is that Oauthis supposed to be about authorizing users, not authenticating them.

Notice how above I first blamed the browsers for not solving the problem, but then ended up sharing the blame with OAuth. That's because a) the UI redressing problem is not specific to OAuth and b) UI redressing is a super-tricky problem to solve. Simply displaying the URL of an iframe (even if browser assisted) is not nearly enough because that too can be easily redressed (see more at http://www.webmonkey.com/2008/10/a_look_at_the__clickjacking__web_attack_and_why_you_should_worry/). Browser developers do are trying to do something about the problem but they just don't agree on exactly what is the right measure (see e.g http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2008-September/016286.html).

So, while waiting for a standards-based solution to the problem is there anything that can be done to improve the user experience of (FB's) OAuth dialog flow? The inline window mode works great if a) you are already authenticated with Facebook (i.e. you have a valid Facebook cookie) and b) you've previously authorized the subject application. However, in all other cases, the inline mode isn't too useful since it's not that simple to find out if the current user is logged onto Facebook or not. You can find the status with FB.getLoginStatus() but you have to include FB's Javascript SDK to the page. The other issue is the frame busting code. Facebook doesn't allow any of its pages to be displayed in an iframe. Instead they simply display a link to "Visit Facebook" when shown in an IFrame. There's no technical or security-related reason why Facebook couldn't allow showing the Oauth authorization window in an iframe when the user is pre-authenticated via cookies. In fact, Facebook already (almost) had this working with Facebook Connect, only it had one crucial flaw: it was asking for user's Facebook username and password in the same dialog.

To improve usability without asking for user's credentials in the same Oauth authorization dialog, Facebook could potentially allow passing a one-time valid user authentication token with the Oauth request, but in some ways that would only shift the responsibility somewhere else. There's an open standard for that as well, called OpenID, and you can by all means use OpenID together with OAuth as demonstrated by Google . Unfortunately though, the window redressing attack is just as big of a problem for OpenID as it is for OAuth. Since OpenID was originally meant for authentication only (though the attribute extensions make it partly an authorization technique) you cannot shift the responsibility any further. I'm not advocating the use of hybrid OpenID+Oauth model either - it may just increase complexity without improving user experience. However, we may be throwing the baby out with the bath water by never allowing Oauth dialogs to be shown in iframes. Certainly the authorization server has to be able to authenticate the end user one way or another, but handling an Oauth callback in an iframe is perfectly secure if you never ask the user's password in the same dialog. Anyhow, with the current standards there's no way out without major security implications, so browsers and ultimately, newer standards need to provide a better, more secure solution.

This is a patch release to fix:

Bug

  • TYNAMO-75 - Security module does not protect urls correctly

Separately, I've also added several improvements to the tapestry-security documentation and added links to examples to showcase the capabilities of the module.

With 600 million users and counting, it's the new Internet. Yes, I'm talking about Facebook. Whether you love it or hate it, these days you have to have a Facebook strategy. Every other site is doing Facebook, Twitter and Google integrations and why not, your fledgling little website wouldn't need more than 1/1000th of their users to make it a success. So why is that everybody needs to suffer on their own through implementing various versions of Oauth & other open authorization standards? With that suffering in mind, tynamo-federatedaccounts, a module for supporting remote authentication and merged (federated) authorization, was born.

I've been using various versions of more specialized implementations of the same concept before, but tynamo-federatedaccounts is the first attempt at generalizing Oauth & similar work flows to an easy-to-use package. The module is based on Tynamo's tapestry-security, a stable and well-maintained security package based on Apache Shiro for Tapestry5 applications. At this point, I'm looking for early user feedback for the current implementation and APIs. I've put together a simple, live demonstration to showcase it. Also check out the documentation for tynamo-federatedaccounts.

I'm happy to announce that Pierce T. Wetter has joined the ranks of Tynamo. Of course, as one of the original contributors to tapestry-jpa, he's not really a new committer, but hey we'll take it, so welcome on board Pierce! In regards to JPA, I believe we have some quite exciting stuff to introduce in the coming months.

Why Tapestry?

Lately, I've had noticeably more people asking me about Tapestry and why one should choose it over the other (Java) web frameworks. To me, Tapestry is a good compromise, just like Java is. Linus Torvalds, my fellow country man, has famously said "performance almost always matters". There are so many aspects to web development, and performance is often seen as one of the smallest of your problems because in the end "it always comes down to the database". However, a high performing framework solves many other problems. Today, a typical, reasonably well-implemented Java web application on a modest hardware can serve hundreds of concurrent requests, thousands of concurrent users and tens of thousands of users a day from a single server. Most start-ups never need to worry about the scaling out problem until they actually have the money to pay for it. Unfortunately, you can also easily make the implementation horribly slow, suffering from scalability problems from the get-go and even more unfortunately, it's easier to go wrong with some Java frameworks than with others. For what Tapestry offers, the performance of the framework itself, both in terms of cpu and memory consumption is simply phenomenal. Performance matters.

However, I really don't want to make this post about Tapestry's performance. As soon as you mention one thing about a particular framework, people tend to place it in that category and forget about everything else. What I really like to give as an answer to people who ask why one should use Tapestry is this: because it is well-balanced and comprehensive. There are a lot of other web frameworks that are optimized with a certain thing in mind and in that narrow field, they typically beat the competition. It's difficult though to be a good all-around contender but that's exactly what Tapestry is all about. Tapestry doesn't force you to a certain development model - such as using sessions, always post, single url, ajax-only, thick RIA etc. If you just need to handle a specific case, such as building a single-page, desktop-like application for web, you could pick GWT, Flex or Vaadin, but if you are a building a generic, mixed static/dynamic content site with multiple pages you'd undoubtedly pick entirely different set of tools. Tapestry though, is an "enabling" technology - you could use it together with all three aforementioned RIA frameworks. You could also use and people have used Tapestry-IoC alone in non-web desktop applications. Not a whole lot of other "web" frameworks can claim suitability for such diverse use cases. Sadly, comprehensiveness of a framework can be a somewhat difficult area to objectively compare so each framework usually resorts to toting their best features to prove their superiority over others.

One criteria I personally use a lot in comparing effectiveness of competing solutions is their expressiveness and succinctness. Now, everybody knows that Java is a butt-ugly language (though it makes up on other departments, like performance and comprehensiveness). Today's Java is far from your grandfather's Java a few years back and Tapestry makes the best use of the more advanced, modern JVM techniques available today, such as bytecode manipulation, annotation-based meta programming and introspection without reflection. Tapestry code is purposefully remarkably succinct. Minimal effort required for creating Tapestry components makes it easy to refactor your application logic into reusable elements, rather than having to repeat yourself. Patterns in object-oriented languages are a well studied and accepted principle, but only a few (IoC) frameworks besides Tapestry IoC manages to have a framework level support for implementing common ones, such as chain of command, strategy and pipelines.

For Tynamo, I've said it before but I just don't think we could have achieved the same CRUD functionality with any other framework. Certainly anything can be done, but the cost of it would have both been far higher and we would have needed to build much more infrastructure. When we moved from Tapestry 4 to Tapestry 5 (and from Trails to Tynamo), it was amazing to see how we were able to simplify our implementation and remove huge amounts of code while keeping the concept unchanged and making it all more modular at the same time. Using a different stack, you could probably get closest to what tapestry-model is with a combination of Wicket and Spring, but allowing the same level of extensibility would undoubtedly be more cumbersome. Back in Trails, we actually had one person working on a pure Spring (MVC + core) implementation of the same concept but it died a slow death. As the documentation states, tapestry-model produced "default model is highly customizable, you can change pretty much anything you need, and make the changes specific to type, page or instance - a feature that very few other CRUD frameworks offer". The big difference is that when you need to customize the model, you don't have to rewrite it all, you'll be just customizing the pages and overriding components as needed.

Perhaps we've gone a bit overboard with modularity, but since it's just that simple with Tapestry, most of our modules are independently usable but seamlessly work together in the same web application as soon as you add them to the classpath. Today, Tynamo is much more than just tapestry-model, the CRUD framework. Tapestry-security, tapestry-conversations and tapestry-resteasy are all steadily gaining popularity and based on the page views, it seems that tapestry-security is poised to become our most popular module offering at some point. On that note, I have a few new supplemental modules for tapestry-security coming up which should be of interest to others as well, but more on that in a separate post. For now, I hope I've been able to give some answers to why at Tynamo, we think we've made the right choice with Tapestry and I'm confident that 2011 will be the best year yet both for Tapestry and Tynamo!

What's that? Did the little Tynamo elf just leave an early Christmas gift for all the Tapestry people who have been so good boys and girls the whole year? Indeed, Tynamo is announcing one more module, tynamo-archetype 0.1.0 this year before focusing on our own wish list. It seems fitting that we released our very first Tynamo archetype just a year ago and now, 0.1.0 is all ready to go with tynamo-model 0.1.0, T5.2.x and other bells and whistles. Read more from Quick start.

Enjoy! We'll take a little break from announcements now, see you again around T5.3 (smile)

Hey, wouldn't it be great if you could just reload your RESTful service classes live while developing them? Oh that's right, that's exactly what tapestry-resteasy 0.2.1 allows you to do! This is T5.2.x specific maintenance release, updating the JAX-RS dependency to JBoss' resteasy GA release 2.0.1. Read more at tapestry-resteasy guide.

Release notes:

Improvement

  • TYNAMO-64 - Live Class Reloading for REST services

Ta daa! This time we are announcing a dual release of tapestry-security, versions 0.2.1 for T5.1.x and 0.3.0 for T5.2.x! Probably not much of a surprise anymore as I've hinted at numerous occasions about the new releases but announcing still has its place since major dependencies changed. Most importantly, these versions pull in and integrate with Apache Shiro 1.1.0, the first Shiro release as a top level Apache project. I'm also happy to report that some of Tynamo-born annotations made their way to Shiro core so tapestry-security doesn't need to supplement Shiro annotations with our own extensions anymore. If you were using previous tapestry-security releases, you are advised to upgrade immediately as there were some security vulnerabilities in Shiro 1.0.0-incubating (which don't directly affect tapestry-security but you should still upgrade).

Tapestry-security 0.3.0 uses the brand new T5.2.4, the best Tapestry release yet. 0.2.1 and 0.3.0 are functionally equivalent, the only difference is that 0.3.0 moved onto newer APIs (thanks Massimo) and we started using some T5.2 features in the tests ourselves. Testament to the backwards compatibility of Tapestry 5.x, tapestry-security 0.2.1 will work for T5.2 just the same but it pulls in T5.1.0.5 and is tested against that version. Both versions will be maintained going forward but 0.3.x will start using more of T5.2 features in the future. Read more at tapestry-security guide. Release notes are for both versions except for TYNAMO-66:

Bug

  • TYNAMO-56 - tapestry-security sources missing from central repo

Improvement

  • TYNAMO-61 - tynamo-security: bypass security check during application start
  • TYNAMO-66 - Update tapestry-security to use T5.2.x APIs
  • TYNAMO-55 - Rewrite ShiroExceptionHandler for T5.2

Task

  • TYNAMO-62 - Update tapestry-security to use Shiro 1.1.0 APIs

Tynamo project is at it again, this time bringing you tapestry-model 0.1.0 release! If you've followed the development of tapestry-model or even (gasp!) using it, you already know that this release marks a major step forward, laying the groundwork for making the module even more customizable and flexible in a variety of use cases. This release is tested with T5.2.2 and going forward, development of tapestry-model will focus mostly on supporting and utilizing features of T5.2.x. Read more at http://tynamo.org/tapestry-model+guide

Release notes

Bug

  • TYNAMO-12 - The Composition component creates duplicates if
    the parent/child relationship is implemented following the Hibernate
    docs recommendations.
  • TYNAMO-13 - Can't use more than one Composition component per page.
  • TYNAMO-16 - Enums annotated with @NotNull are showing the blank option.
  • TYNAMO-27 - EditComposition component doesn't know know how to
    deal with enum types
  • TYNAMO-32 - byte-blobs are not working
  • TYNAMO-45 - The Blob component throws an exception when
    rendering the Show page

Improvement

  • TYNAMO-6 - Create a Tapestry annotation DescriptorDecorator
  • TYNAMO-17 - Implement our own BeanModelSource
  • TYNAMO-20 - The archetype should work out of the box with any
    IDE and without any mvn commandos.
  • TYNAMO-21 - Document how to remove the "tapestry-model-web" dependency
  • TYNAMO-26 - The palette for @OneToMany should show only
    non-assigned objects.

To celebrate Tapestry 5.2.4 release - the best T5 release is yet - the folks behind Tapestry have finally, after many months of hard work, published the new Confluence-powered website. Besides just the eye candy, the documentation is vastly improved! If you've ever at least been curious about Tapestry, you owe it to yourself to take another look at Tapestry right now.

Hello all, we'll start Tynamo project's "onslaught of announcements" by announcing tapestry-conversations 0.1.2 release (stay tuned, other announcements to follow in the coming days). Testament to backwards compatibility of Tapestry 5, conversations 0.1.2 is tested to work with T5.1.0.5 and T5.2.1, T5.2.2 and even the not-yet-finalized T5.2.3. This is mostly a maintenance release so we can start working on T5.2.x specific enhancements to the conversations api. Read more at tapestry-conversations guide

Issues fixed:
Bug

  • TYNAMO-59 - conversation.moderator seem like doesn't work with IE7.
    Task
  • TYNAMO-60 - Upgrade conversations module to T5.2

The most well-known web integration testing suite around is probably Selenium, but I must say that I'm more and more happy with HtmlUnit-based tests only. Why? The big difference is that I can run all of my HtmlUnit-based tests within my IDE without extra configuration and they run an order of magnitude faster than the multi-process Selenium tests. Another major benefit is that I can directly access the embedded database and Tapestry registry and do everything within a single JVM, which is extremely useful for setting up the test fixtures and the system state before the test and then cleaning up everything afterwards. Finally, maintainability is way better. While it may take longer to write the first HtmlUnit test than recoding a Selenium test, writing the next ones and maintaining the test suite as your applications evolves is far, far easier. JMHO of course.

I just finished writing the following test for integration testing a referral system: I start up the embedded Jetty, write a new Referral entity to the database, browse the site as a (guest) user as if he was referred by the Referral, sign up via an Ajax control, receive an email sent by the system, verify the new user activation by clicking on the url in the email, fill in the user details and finally verify that the referral is credited for by doing a database query. It covers a lot of ground, but it's all executed in less than 8 seconds on my development laptop. All together 24 lines of code, most of it used for setting up the test fixtures. Now, PHP guys, let me see you do that! (Sorry that was unfair, but ah, it felt good (smile) ).

For those interested in the details, the big three libraries in play are Jetty, Hibernate and Tapestry (naturally). I'm also using a version of Tynamo's own AbstractContainerTest, Wiser (for email integration testing, note that I moved away from Dumbster) and H2 (don't I love that database!).

Selenium makes a lot of sense if you really are executing the tests against multiple browsers and your tests are mostly focused on browser compatibility. From what I've seen though, most of the time people are using Selenium with a single web driver and they are simply using it for integration testing the application workflow. HtmlUnit's browser doesn't seem to have any problem parsing the webpages I feed to it or executing the Javascript embedded on them, so in practice if my HtmlUnit-based integration test fails, I can be pretty sure the same doesn't work on any "real" browser either.

As an Apache Shiro committer and a strong proponent of Tapestry, I'm proud to announce the 0.2.0 release of tapestry-security module, which represents the best and most comprehensive security framework integration for Tapestry 5 applications. I can say that since it's largely written by others (smile) Tapestry-security is based on the great work by Valentin Yerastov, the original author of tapestry-jsecurity. Later on, JSecurity became an Apache project and was renamed to Apache Shiro, the first official release of which (as an Apache project) was recently made. Alejandro Scandroli, who else, updated the code to use the latest Shiro APIs and finally, we added a few other bells and whistles on top of it all. Pierce Wetter gets an honorable mention for being a guinea pig and starting to use tapestry-security all without documentation (so it can't be that bad). Now both tapestry-security and Shiro even have proper documentation, read more from our tapestry-security guide. Hope you find the module as useful as we have!