RSS 2.0 New Entries Syndication Feed Atom 0.3 New Entries Syndication Feed

Show blog menu v



Use it



Sibling projects

RIFE powered

Valid XHTML 1.0 Transitional

Valid CSS!

Blogs : Latest entries

< Previous page 
Reviving RIFE, starting work on version 2

Hi everyone,

I'm not sure at all who's still active in the server-side web development world, but it seemed best to reach out through the old channels in case some people are interested in reviving RIFE.

I've personally been busy with a lot of other projects during the last 7 years, ranging for high-performance clustered data tools to real-time musical instruments.

I'm now working at ZeroTurnaround on the LiveRebel product and am being confronted with the state of web development nowadays. To my surprise, in many ways the approaches in RIFE are still relevant and even the Play framework is lacking quite a lot of RIFE's simplicity and power.

So, a few months ago I started work to analyze what I want to keep from RIFE version 1 to build a fresh version 2: I took a little break to work on another quick pet-project in the meantime ( but that's now all ready for launch.

The idea is to basically put a lot of things in question about RIFE and trim it down, throw away a lot of the junk that was accumulated and make the features very opinionated and targeted.

My initial plan of action is this:

  • focus on pure Java and byte-code instrumentation, no scripting languages
  • leverage the upcoming features of Java 8
  • rebuild the template engine with largely the same ideas in place, but clearer and more focused
  • properly finish the isolation of the continuations engine and bring it up to date
  • rethink the infrastructure with IoC as a starting point, instead of having it as an afterthought
  • totally rewrite the web engine, with similar principles but much more conventions and less configuration
  • trim out the database abstraction layer for only certain relevant databases

I've started mocking up the new version of the template engine and took an initial stab at creating an Antlr 4 grammar. That sadly is really not working out so I've started work on a new custom parser.

One of my mistakes with RIFE v1 was that I didn't involve the community much during the development process, so I want to change that.

If you're interested in shaping what RIFE version 2 is going to become, please hop on the developers mailing list and say hi:!forum/rife-dev

Hope to hear from some of you!

posted by Geert Bevin in RIFE on Jun 23, 2013 9:32 PM : 0 comments [permalink]
Gotcha: using RIFE's bean-centric validation with Terracotta (or any entity container/cache)

RIFE has a unique approach towards validation which is centralized around bean instances and not bean classes.

Instead of having an external validation service, each bean instance publishes meta data about its constraints. Every part of the system (validation, form generation, database structure creation, ...) will inspect the meta data and peruse it. Validation is an exception in that after inspecting the meta data, the results of the validation are contributed back for each specific bean instance as ValidationErrors. This again allows every part of the system to easily access the validation results and act accordingly.

Instead of implementing a container that keeps track of all the mappings between bean instances, their meta data and the validation errors, I decided that each bean instance will actually hold this data into fields. However, since people generally dont want to pollute their bean classes with framework-specific constructs, I created the meta-data merging facility. This automatically looks for a class with the MetaData suffix when a bean class is loaded. Through byte code instrumentation, the capabilities of the MetaData class are merged into the original class and you can safely cast each instance of the original class to any of the interfaces that the MetaData class implements. (you can find more details about this feature in the RIFE wiki)

All this is very intuitive when you use it in practice and develop a database-backed website. RIFE's database layer doesn't use an entity container either but rather creates and populates new bean instances each time an entity is fetched from the database. This has the benefit of each thread having a dedicated version of the entity which can be manipulated without risking data races. Only when all the operations are finished, the entity is stored back into the database through an explicit save call.

The code could be like this when editing an existing User entity:

User user = database.restore(userId);
if (((Validated)user).validate()) {;
    template.setBlock("content", "success");
} else {
    generateForm(template, user);

However, when using Terracotta (or something else, like a cache), you typically don't want every entity to go back to the database. Instead, you want to keep them in memory and only store certain parts into the database. So instead of having a database manager, you have some kind of in-memory service that is able to find and store entities.

Intuitively and naively you would replace the code above with the following broken code:

// this code is broken, read below to know why
User user = service.findById(userId);
if (((Validated)user).validate()) {;
    template.setBlock("content", "success");
} else {
    generateForm(template, user);

The problem relies in the fact that each and every thread will be working with the same instance of the User. Your initial reaction might be to just synchronize the accesses to this instance, but hang on, think about what's happening. You actually don't want every thread to have the same instance. You want the instances to be different and isolated, they all have to contain the data that was submitted through their respective web forms, and you all want them to have their own validation errors. This is exactly the same as what happens when you get a new instance from the database.

So, instead of retrieving the user from the service to modify it with possibly invalid data, you want to create a new instance of the entity that will be in local scope until the validation has succeeded. Only then you want to store it back into the service. This guarantees that your data is always correct and also allows perfectly concurrent access on users with the same identifier.

The correct code would thus be:

User user = getSubmissionBean(User.class);
if (((Validated)user).validate()) {;
    template.setBlock("content", "success");
} else {
    generateForm(template, user);

This had me scratching my head when I was bitten by the broken code above. However, if you think about it, it's perfectly logical. Working with in-memory containers is fundamentally different from working with relational database, where your data is stored independently from the actual objects that you're using. You have to remember that an in-memory container is a store too, and you don't want invalid or intermediate results to end up in there. However, this is what you risk to happen when you directly manipulate the fields of the instances that are already in the in-memory container ... but it's oh so tempting to do!

posted by Geert Bevin in RIFE on Jul 16, 2008 9:37 AM : 1 comment [permalink]
Custom constraints and validation in RIFE

Joshua Hansen wrote a nice example of how to create custom meta data constraints and display dedicated validation error messages with RIFE. He also shows how easy it is to make RIFE/Crud display your validation errors for beans that use your custom constraints.

Read the article in the RIFE wiki.

posted by Geert Bevin in RIFE on Jan 29, 2008 5:52 PM : 0 comments [permalink]
RIFE BOF tonight at QCon conference in San-Francisco
In case you want to learn more about RIFE, ask questions, chat a bit about what you've done, share experiences, etc., feel free to come the the BOF tonight that I'm organizing during the QCon conference in San Francisco. You can find all the details here:

The address is:
Westin San Francisco Market Street
50 Third Street
San Francisco
California 94103

The BOF will be from 8:30pm - 9:30pm in the 'City' room.

We are also organizing a Terracotta BOF right before it, so if you're interested in that, you can come from 7:30pm - 8:30pm to the 'Stanford' room.

See you there!
posted by Geert Bevin in RIFE on Nov 8, 2007 10:40 PM : 0 comments [permalink]
Speaking at NFJS Europe : "Cutting-edge productivity with RIFE and Web Continuations"

I'm speaking at NFJS in London at the end of this month about RIFE and Terracotta. You can find the abstract of my session quoted below. The schedule looks very interesting and I'm excited that NFJS is finally taking place in Europe too.

If you're interested in going, you might want to click on the banner to the right or to use the promotion code NFJS-RIF660. This will give you a free Nintendo Wii with your registration (woohooo, I love my Wii!).

See you at NFJS Europe.

I also have another session about Terracotta in the real-world.

Cutting-edge productivity with RIFE and Web Continuations

RIFE is a full-stack, open-source Java web application framework, offering fast results with the promise of maintainability and code clarity. This session will review the novel ideas in Java web application development that RIFE has introduced to the development community.

Through a real-world demonstration of the development process with RIFE, learn how RIFE makes developing easier with features such as: instant reloads and centralized declarations, meta programming through constraints and meta data merging, run-time POJO-driven CRUD generation, bi-directional logic-less templates, automatic context-aware components, and the integration of a content management framework.

The second part will focus on state management, which has always been a complex and tricky part of web application development. Native Java web continuations simplify this and automatically allow you to create a one-to-one conversation between users and a web application. State preservation and flow control no longer need to be handled manually, bringing you back to the simplicity of single user console applications. Remember 'scanf()'?

Continuations will be introduced from general principles, followed by practical examples that explain how they benefit web application development and their frequent usage patterns. Finally, automatic and non-intrusive fail-over and scalability will be demonstrated through the integration with Terracotta.

posted by Geert Bevin in RIFE on Aug 9, 2007 8:46 PM : 1 comment [permalink]

< Previous page 
Google web