Tynamo is model-driven, full-stack web framework based on Apache Tapestry 5

Tynamo's mission is to provide implementations for different aspects of a full web application stack that offer reasonable out-of-the-box functionality and are easy to customize. We are intent on proving that web applications based on Java can simultaneously be high performing, easy to implement and fun to develop. We leverage existing technologies where possible and provide integrations with proven, clean and compact libraries rather than limit ourselves only to standard Java (JSRs). Tynamo is both comprehensive and modular so you are free to choose the parts you like from our full stack. And finally, we like Tapestry and our modules use Tapestry IoC extensively.

Latest news

tapestry-security 0.6.4 release addresses a serious vulnerability

While the Apache Shiro team (me included) are still mulling over how to best fix a serious security vulnerability with Shiro’s default rememberMe cookies and object deserialization SHIRO-550, I went ahead and implemented a fix for the vulnerability in tapestry-security, following a similar approach I had proposed for Shiro as well. In essence, an attacker can potentially gain access to the server using a deserialization vulnerability (see more at https://www.contrastsecurity.com/security-influencers/java-serialization-vulnerability-threatens-millions-of-applications ). It’s a bit more convoluted for Shiro in general, but once again, service contributions make this a simple matter to handle in Tapestry. In 0.6.4 of tapestry-security, only known principal types can be deserialized. Long, Integer and String (which likely cover 99% of the use cases) are sanctioned by default and users can easily contribute additional principal types to the org.apache.shiro.io.Serializer service, for example:

public static void addSafePrincipalTypes(Configuration<Class> configuration) {

You are advised to update immediately. Currently the fix is only available for Tapestry 5.4 but I’ll make other releases available as requested. You can also easily copy the relevant classes from the source tree and override services as needed in your application.

Release notes

  • Upgrade Shiro to 1.2.5 #26
  • Safely deserialize principals from rememberMe cookie #27
  • Update to Tapestry 5.4.1 #28

tapestry-conversations 0.2.0 released!

We aim to serve. A user asked for a T5.4 compatible version of conversations module and we delivered. Upgrading the module was pure joy and it is a testament to the outstanding backwards compatibility record T5 has had throughout its existence. Note that I had written the original version for Tapestry 5.0 while we were still called the Trails framework! Checkout the tapestry-conversations guide for more info.

Release notes

  • Update to tapestry 5.4 #1

tapestry-security 0.6.3 released!

While working on securing an Ember frontend with Tapestry backend, I noticed that tynamo-resteasy didn’t want to play well with security. I’m fairly surprised this issue surfaced only now because tapestry-security is fairly well battle tested. Anyhow, if you’ve ever had a problem with T5.4 and tapestry-security not being able obtain assigned roles or user identity from the request, it’s time to upgrade.

Release notes

  • Update to T5.4-rc-1 #25
  • Store ShiroHttpServletRequest to RequestGlobals before processing #24

tapestry-model 0.6.0 released!

Finally, we have an officially compatible release tapestry-model for T5.4 available. We had one long running issue with the changes in tapestry core and it wasn’t until T5.4-rc1 before it was all sorted out. The official release note is short but there’s been lots of great functional changes to the core.

Release notes

  • Fix the test suite to use changed form element names #4
  • 0.5.2 has a dependency on eclipselink #2

Here’s a few screenshots of the brand spanking new tapestry-model in action (just to put down any potential qualms abouts us doing nothing but smoking weed all day long here). Also notice the search options. gol admin home gol admin filteringoptions

Back in business

Sorry, fans of Tynamo.org (both of you, just wanted to say hi :), we’ve been gone for a few weeks. Tynamo.org was another casualty of Codehaus’ demise. We were running on top of Codehaus’ Confluence-based infrastructure and after they went bust, we had to figure out a different platform. Luckily we had already moved the code over to Github over a year ago, so now we “only” need to rebuild the documentation and transform it to Markdown powered by Jekyll. Currently, we have just a rudimentary site, we’ll be adding more content in the coming weeks. Thanks for patience!

tapestry-routing 0.1.1 released!

Bada bing bada boom! New year, new releases - and just like that tapestry-routing 0.1.1 is ready for consumption with the latest T5 beta. There were some minor API adjustments made, otherwise it’s the same, trustworthy routing module. See the tapestry-routing guide for more info!

Release notes

  • Update routing to T5.4 beta-26 #3
  • Update routing to T5.4 beta-22 #2

tynamo-federatedaccounts 0.5.0 for T5.4

Thanks to the enthusiastic, borderline pestering community :), yet another tynamo module, this time tynamo-federatedaccounts 0.5.0, gets an upgrade to T5.4! Use it before the code expires, see tynamo-federatedaccounts guide and tynamo-federatedaccounts source code.

Release notes

  • Upgrade to T5.4 #1
  • Rewrite the CollapsiblePanel component as a requirejs module #2

Tynamo goes Github!

GitHub is cool and we so desperately want to be cool too that we decided Tynamo needs to be there as well. In all seriousness, Dragan Sahpaski wrote up a whizbang script to import all of the Tynamo’s SVN history, branches etc. to a Git repo so it made the move a no-brainer. Thanks Dragan. We still love Codehaus though and they’ll continue providing a lot of the infrastructure support, like CI builds and Confluence space but we are going to moving issue management over to Github as well so we can be ready for your pull requests instead of writing the code ourselves :) Also because we are good Git citizens, each Tynamo module now has its own Git repo. Checkout the Tynamo’s organization page at Github and navigate from there to your preferred module and start forking away!

RememberMe with rolling tokens

Why is it that I cannot find a definition of a rolling authentication token anywhere? Let me provide my own then: a rolling token is a security (authentication) token that can only be used for a single successful authentication. After a successful authentication, the used token is always replaced by a new one, therefore the token is said to be rolling. There, now we can talk. I’ve always disliked typical rememberMe implementations for the weak security they provide and I still admire this eight year old blog post by Charles Miller. Let me quote from “Persistent Login Cookie Best Practice”:

Persistent login cookies are the cookies that are stored with your browser when you click the “remember me” button on the login form. I would like to be able to say that such cookies are obselete, and we have a better way of handling user logins, but they aren’t, and we don’t.

The following recipe for persistent cookies requires no crypto more powerful than a good random number generator.


  1. Cookies are vulnerable. Between common browser cookie-theft vulnerabilities and cross-site scripting attacks, we must accept that cookies are not safe
  2. Persistent login cookies are on their own sufficient authentication to access a website. They are the equivalent of both a valid username and password rolled into one
  3. Users reuse passwords. Hence, any login cookie from which you can recover the user’s password holds significantly more potential for harm than one from which you can not
  4. Binding persistent cookies to a particular IP address makes them not particularly persistent in many common cases
  5. A user may wish to have persistent cookies on multiple web browsers on different machines simultaneously

With all this in mind, I’ve always implemented rememberMe based on rolling tokens in the various web applications I’ve worked on. However, I’ve never attempted to provide it as a reusable module until one day a few months ago while I was working on federatedaccounts it hit me: rolling tokens can be thought of as just another “remote” authentication provider that can be federated with the main account. For some months now, we’ve happily been using tynamo-federatedaccounts-rollingtokens in production. I added some quick documentation for it at the end of the generic tynamo-federatedaccounts guide, have (secure) fun with it!

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!