Skip to end of metadata
Go to start of metadata

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.

Quick status update

Latest news

Oops, we did it again! We cleaned the security component issue list and cut a new release with a few nice little improvements. 0.5.0 was released a few months before but never announced. 0.5.1 is the new stable release for T5.3.x. Unfortunately though, 0.5.1 will not work with the upcoming T5.4. It does compile and about half of the tests succeed but the ajax interfaces are changed enough that there will likely be some issues. Well, at least we have something to do for the next release.

Bug

  • [TYNAMO-176] - Incorrect redirect to login page in case of ajax request

Improvement

  • [TYNAMO-125] - Else block for the security components
  • [TYNAMO-193] - Allow temporarily disabling security for an invocation of Callable
  • [TYNAMO-195] - Make LoginForm error messages localizable
  • [TYNAMO-183] - Improve support for Instance-Level Access Control

Enjoy,

Tynamo Team

Today, Mark Reinhold proposed the new new schedule for JDK 8 after the last slippage of Lamba merge. I'm pretty hopeful that this time the schedule will hold. I'm quite excited myself about Lambda expressions, too many times I've been writing code and just thinking that if I only could write this as a closure it'd be that much simpler. However, there is much more to look forward to and the "Everything about Java 8" article does a good job show case all the new features.
Fire the marketing department.

Yes, we just might have forgotten to announce "a few" releases we've made. We got busy, what can you say? Besides our marketing dudes never do anything anyway. Let's start the year with a bang and correct the situation right now (after taking the marketing department behind the shed). Here's a recap of the previously unannounced releases we've made in the last four months:

tapestry-model 0.5.0

We finally implemented a built-in full text search. The Hibernate version is using HibernateSearch because it's ah so automatic and nice. Only thing is that it's local only. For the JPA version, we fully integrated ElasticSearch, the best thing since full-text bread. I dare say our integration is better than the one that Play framework has to offer. It seamlessly integrates with SQL-based search and is easy to extend. tapestry-model continues to be better suited only for the more experienced Tapestry users. One day we'll write proper documentation for it and surprise you all.

tapestry-security 0.5.0

A fix for TYNAMO-183 forced our hand because of some dependencies on 5.3 so we decided to push out 0.5.0 a bit early. We'll get the rest of the improvements in later. We are also dropping support for T5.0/5.1 but hey it's open source. If you find a bug in the earlier releases, send it to us and we'll patch it.

tynamo-federatedaccounts 0.2.0

TYNAMO-129, or rememberMe with rollingtokens made it as a new submodule of federatedaccounts. There's just no reason to use those puny, insecure and ordinary remember me cookies anymore. More at my blog post on RememberMe with rolling tokens.

jpa-seedentity 0.1.5

First, the younger JPA version of the well battle-tested seedentity library pulled next to the hibernate-seedentity, turned her head and waved, then sprinted ahead laughing, leaving the hibernate guy sobbing in dust (in terms of features).

editablecontent 0.0.3

I still think it's the coolest little library out there and just wouldn't be possible to implement without the lovely distributed configuration of Tapestry. You aren't still modifying your html text content in an offline text editor, are you? Now I just need to integrate conversation and inline image support.

security-jpa 0.0.4

Want to secure your data instances? This one works so well it's annoying.

From time to time you get new users on the Tapestry mailing list asking people to compare Tapestry to some other frameworks. While sometimes these discussions degenerate to the level of "my framework is best", Alex Kotchnev, Tynamo.org's very own JDO guy, provides this level-headed and well reasoned reply:

In the past five years, I worked on a number of greenfield projects. In three out of four, we ended up choosing Grails - it is very hard to deny the market & mindshare , the expansive documentation, the big name company behind the project, the large community, a massive number of plugins (for pretty much anything that you'd want), the end-to-end stack (so, you don't have to choose your ORM, DI, etc) and the ease of getting started with a Grails project.

However, after working on a couple of these Grails projects for a few years, the latest project I got involved with , I chose Tapestry. In some cases, I've missed some of the niceties that Grails brings out of the box, but without too much effort I've been able to replicate them fairly easily.

The biggest reasons for picking Tapestry over Grails on this latest project have been:

  1. The inability to aggressively refactor your code - the dynamic nature of the language is nice when you want to knock something out quickly, and saves you a few lines of code here and there. However, after the codebase gets to a certain size, the inability to reliably refactor the codebase made the codebase difficult to evolve. Sure, IntelliJ & NetBeans has some support for refactorings in Groovy; however, it is not even close to the level of depth and ease of what you get with Java. I love Groovy to death, have been using it for many years (since it was in jsr-1 version) but ... the tool support is just not there yet (and likely will never be) and for a team of developers Java just ends up being a better choice (at least in the context of my team)
  2. The importance of Tapestry components cannot be overstated. In a fairly modern web app, the functionality of each page depends on a bunch of markup, some CSS from a stylesheet, and some javascript from a javascript file. Tapestry makes putting everything together and using the results extremely easy and logical. In the late days of the last Grails project I was involved in, it was a massive PITA to build a page that really should have looked like 'that other one' - even when you used tag libraries to encapsulate the markup generation, you still had to hunt down all the css and js files that needed to be there.

On the first issue, if you will be using Groovy for your pages, you will be in the same boat as Grails. Personally, I wouldn't recommend it - Tapestry already pushes the envelope on Java quite a bit, so your Java code ends up being very short and sweet already. In the past, I had attempted to use Scala in a tapestry app, and ended up having to just deal w/ some of the mismatches between the language and the framework and my pages ended up looking up like the same old java pages I would have had but with a different syntax.

On the second issue, there is the grails resources plugin that tries to pull resources kinda like Tapestry, but using it requires this artificial separation into resource bundles which seems to be a PITA and somewhat mind bending.

On the abundance of Grails plugins - after using a bunch for the projects I was working on, it turned out that many were not well maintained so we hadto take over and maintain them ourselves. Sometimes, they're a good starting point, but in the end ended up less of a factor than I initially thought.

I originally very much enjoyed the Grails build system (running on top of Gradle); however, with a pretty simple project setup, Maven seems to bejust as straightforward. If you wanted Gradle, you could use that for your Tapestry app, and be on-par w/ Grails.

On the latest project that I chose Tapestry for , I have been very happy with my choice. On a few occasions I've run into some frustrations (e.g. for rendering emails, I ended up having to use Freemarker, whereas with Grails the template rendering for emails comes for 'free' ; I had to build my own equivalent of the Grails "console" plugin where you can run Groovy commands inside of your running application); however, in all cases, the solution has turned out to be more elegant than I had expected (albeit, it required deeper tweaks in the framework than I had expected).

Cheers,

Alex Kochnev

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.

Premises

  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!

If you've missed localization support with your routing rules, don't you worry - just go grab tapestry-routing 0.0.4 and your path-encoded locale is merrily honored.

Release notes, concisely:

Improvement

Read more at tapestry-routing guide and enjoy!

I don't mean to pick on New Relic but if you are running a fledgling little start-up with some traffic, commercial monitoring of your servers can cost an arm and leg. As always, there's an open source alternative: Javamelody. Since Javamelody is implemented as a single servlet filter, I figured it was a good sample for showcasing integration of third-party libraries into your Tapestry application secured with Tapestry-security module. See the examples section in our tapestry-security guide for more information!
More people using tapestry-security means more improvements, feature requests. We are still staying on top of it and keep our backlog clean with the following issues fixed in 0.4.6, the best ever tapestry-security release yet:

Bug

  • [TYNAMO-155] - Authorization cache is not cleared at logout

Improvement

  • [TYNAMO-143] - Create a marker annotation for SecurityConfiguration
  • [TYNAMO-154] - add FirstExceptionStrategy as the default AuthenticationStrategy for projects with multiple realms
  • [TYNAMO-159] - Add a NotFoundFilter
  • [TYNAMO-160] - Handle no-context, no ending slash with the same wildcard rule
  • [TYNAMO-161] - add a PatternMatcher field to SecurityFilterChain
  • [TYNAMO-163] - Rename PageService to an internal LoginContextService

New Feature

  • [TYNAMO-150] - Implement the CasFilter (new in Shiro 1.2) as a tapestry-security filter
  • [TYNAMO-162] - provide a configuration to block access to assets (like the AssetProtectionDispatcher)

Read more at tapestry-security guide and enjoy,

Tynamo Team

 

Ever wished that there was a simple way for you to declare that each user can only access his own profile, just as easily as you can declare that only users with admin role can edit certain type of data? Well too bad since such a thing has never existed so you've just resorted to making programmatic checks and building the queries in your service to enforce data instance security. Until now of course: meet ERBAC (Entity-Relationship Based Access Control), the long lost cousin of RBAC (Role Based Access Control)!
Would it not be great if you could write something like:

And be assured that EntityManager.merge() would fail even if somebody manually replaced the entity id somewhere along the way? Wouldn't it be equally cool if you could just do EntityManager.find(Account.class, null) to fetch the right Account for the currently logged-in user? If securing data instances have been causing gray hair for you before and you happen to be using JPA, you should definitely checkout Tynamo's latest module, tapestry-security-jpa.
On a related note, if you happen to live in SF Bay Area, I'll be talking about ERBAC, federated accounts, tapestry-security and using Shiro in modern Java web applications in an upcoming Shiro JUG meet-up this Wednesday, graciously sponsored by Stormpath, Inc.!

I had the tingling feeling with the previous release of tapestry-security but since we have such a blind faith in our functional testing suite, and the tests all passed, we went ahead and managed to cause some headache for all of our users deploying their secure applications to non-root contexts. At least I'm happy the library is popular enough that I get immediate feedback when I screw up (thanks Lenny!). Anyway to restore our crisis of faith, we responded by writing even more tests and here we go again, upgrade to tapestry-security 0.4.4, it's all fixed. There's also some updates to the documentation, check out tapestry-security guide!

Release notes:

Sub-task

  • [TYNAMO-144] - This patch broke fallbackURL functionality
  • [TYNAMO-145] - TYNAMO-133 breaks SecurityUtils.logout() from within Tapestry onEvent methods

Bug

  • [TYNAMO-124] - Context path duplicated when redirecting to saved request
The Tynamo team never rests and is at it again, bringing you a new Tapestry module: tapestry-activiti. This module allows you to integrate Activiti into your Tapestry application. Activiti is a workflow and Business Process Management (BPM) platform. Its core is a super-fast and rock-solid BPMN 2 process engine for Java. We are very excited about this new module and can't wait to hear your thoughts, suggestions and how you put it to use. Go check out tapestry-activiti!

Cheers,
Tynamo Team

PS: We'd like to thank Omar Carvajal for all the work he has put into this.
I rarely find it good use of my time to read random blog posts, but every once and a while you hit a gem. The following is not written by me but I agree with it word for word, and is one of the reasons I left the enterprise world:

"Today I found myself thinking again of what I see as two distinct cultures in the development world: Hackers and Enterprise Developers. This really isn’t any kind of a rant just an observation that I’ve been thinking over lately.
Hackers are really bleeding edge. They have no problem using the commandline, using multiple languages, or contributing back to open source. They’ll find and fix bugs in the opensource software they use and issue pull requests frequently. They’ll always be willing to use new tools that help them produce better software when there might not even be any good IDE support. Finally, they’re always constantly investigating new technologies and techniques to give them a competitive edge in the world.
Now when I say hacker I don’t mean someone who just hacks lots of random shit together and calls it a day (that kind of developer isn’t good for anyone). Just someone who isn’t afraid to shake up the status quo, isn’t afraid to be a bit different and go against the grain. They’re the polar opposite of enterprise developers.
Enterprise Developers on the other hand are fairly conservative with their software development methodology. I’m not saying that a lack of standards is a good thing, but enterprise developers want standards for doing everything and they want it standardized across the company. If there isn’t IDE support for a tool they’ll refuse to use it. Want to use mongodb, riak, etc? Not unless there’s a fancy GUI client for interacting with it. If they find a bug they’ll back away from the framework they’re using and simply declare that the company shouldn’t use the framework until the bug is fixed externally. I find this group prefers to play it safe and work on solidifying their existing practices rather than explore new ideas.
Now don’t get me wrong, this isn’t another rant on IDEs or developers who don’t use the command line. But give me a couple days in any organization and I can quickly point out who the Hackers and Enterprise Developers are."

It's also noteworthy to point out that at least from my experience, the average enterprise developer typically makes much more than the average hacker. So who's really the smart one, eh? Read the whole post at: http://www.javacodegeeks.com/2012/03/tale-of-two-cultures-hackers-and.html

I swear, I thought tapestry-security already implemented anything you need for security. But turns out I was wrong. So, we quickly put together another, even more awesome release of tapestry-security for Apache Tapestry 5 from tynamo.org, with the following enhancements in the newly baked 0.4.3:

Bug

  • [TYNAMO-124] - Context path duplicated when redirecting to saved request
  • [TYNAMO-133] - ShiroHttpServletRequest isn't used if there's no chain associated with the request

Improvement

  • [TYNAMO-121] - Ability to plug into ExceptionPage for the same exception type
  • [TYNAMO-127] - Make SubjectFactory and RememberMeManager their own services for better flexiblity

New Feature

  • [TYNAMO-128] - Make Authenticator its own service to allow registering authenticationlisteners

Check out the tapestry-security guide for more information and enjoy!

Oh and btw, we had also previously released but hadn't announced a bug-fix release 0.1.2 for the exceptionpage module, that tapestry-security uses for exception handling. The lone issue was:

Bug

  • [TYNAMO-126] - Exceptionpage doesn't work for page contributions

Read more about the exceptionpage module from tapestry-exceptionpage guide

Welcome Dragan!
Tynamo's ranks are growing yet again! Please join me welcoming Dragan Sahpaski to the project. Dragan is a highly skilled individual whom I had a privilege to work with last summer when I was mentoring him for a GSoC project. I've had this idea for a light in-place content editing component for Tapestry5 and when I was looking for a reasonable rich text editor to integrate with, of course I found tapestry5-ckeditor, a brilliant CKEditor integration for T5 that Dragan had put together. At the same time, he was looking for a solid home to publish the component. Fits like a Huggies diaper, right? This marks the first foray into UI components for Tynamo.org though, but hey what's life without risks? (smile)
On technological choices
The following is an unedited reply to an email from a good friend of mine who is desperate to run his own startup. Thought it might be an interesting read to other non-engineers who find themselves in a similar situation.

Hey XXX, somehow our conversation from the other day got stuck in my head. First, I have to say that it looks to me you are putting too much emphasis on technologies. You should let your engineers and the business needs guide your technological choices, not the other way around. It's going to be expensive to rewrite your application later if you need to, but so what, it's going to be much more expensive to change the business if your current one doesn't work, and yet you are still doing it. Unless you want to make it your core competency to implement the solutions using the chosen technologies, you have to trust and rely on your engineers to make the right choices for the given problems. What you primarily need from your engineers is motivation and experience with one of the reasonably good technological choices and leave it at that. It's difficult to predict the future so whether you pick RoR, Django, Play or some other hot technology today, you don't know if it'll be a success anymore a few years down the road.

On the popularity of Tapestry, you asked "so how come nobody uses it?" By many measures, Java is the most popular language in the world but very few think of it as cool or hype it. The hyped Java is today pronounced "Android" or "Scala". Tapestry is a good example of what's left after the hype has deflated. Ruby on Rails is a fairly successful and popular framework, yet it was much, much more popular six years ago than it is today. In the world of Java, Tapestry, Play or Lift are still newcomers compared to such behemoths as Struts (one of the original web frameworks in Java). Java is just popular and old enough that the space is fragmented. The good news is that beyond "just" the web layer, you have libraries implemented in Java for almost any imaginable purpose you can simply take into use. Tapestry, or Java are not always good choices for web applications, because the needs for most of the websites are simple, so a simpler language and a simpler framework will not only suffice, but work better because more people are more productive with it and there may be less room for grave mistakes. For lots of applications you simply don't need all of the power Java or the JVM has to offer, but when you do, you really need it. The classic example for this is a highly threaded back-end application - if you have a need for it, a typical RoR or Python-based architecture implements the web layer in the given language, but the back-end architecture with a different language. Few other languages and platforms besides Java are comprehensive enough to implement everything from web to the database with the the same language (although certain Microsoft language comes to mind as an alternative). With RoR, Python or PHP, you pair it with MongoDB (implemented in C++) or perhaps MySQL (in C++ as well). A Java web framework, you pair with Cassandra, Hadoop, hsqldb or any of the other strong alternatives based on need, all implemented in Java. It makes it all more complex, which is also reflected in the pay grade between a typical Java developer and a php developer, or any of the other languages in between. What makes this even more interesting to you, is that as a business owner you have to consider the costs so the best solution for you might be finding the most inexpensive developers that are highly productive with their language of choice.

*** UPDATE ***: A bit after my email, my friend sent me a link to this great blog post by the Tumblr guys, to which I just had to reply. Again, I've re-posted the unedited follow-up below. Keep in mind that I'm purposefully making some simplifications to make my point clear (after all, I'm talking to a business dude). Anybody who's battled with scalability issues knows that while theoretical numbers might justify more modest hardware, it's all about building for the worst-case scenario with plenty of reserve capacity.

Nicely proves my point, no? :) Anyway, it's a surprisingly honest read about their architecture, and shows how most of the time it's all organically grown. They are getting reasonable results with their infrastructure, but still, paying a heavy penalty for the suboptimally performing web layer - 500 web servers versus 200 database servers, where most of the latter are used for stand-by high availability. In a typical scenario, the bottleneck should almost always be the database layer, not the web layer. Sharding is a way to get scalability out of MySQL, but it's far, far away from the highest performing SQL databases. Now, imagine if you could serve the whole database layer with 20 servers instead of 200.

For an all Java implementation with an embedded database, it's not uncommon to require 90th percentile response time within 10ms with at least 1 million page views a day from a single server. Performance matters (http://docs.codehaus.org/pages/viewpage.action?pageId=190316696).

Labels
  • None