Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


{
Div
Wiki Markup
style
float:right
titleRelated Articles
classaui-label
Content by Label
showLabelsfalse
showSpacefalse
titleRelated Articles
cqllabel = "new-users" and space = currentSpace()
|background=#eee} {contentbylabel:title=Related Articles|showLabels=false|showSpace=false|labels=new-users} {float}

What is Apache Tapestry?

Apache Tapestry is an open-source framework for creating dynamic, robust, highly scalable web applications in Java. Tapestry complements and builds upon the standard Java Servlet API, and so it works in any servlet container or application server.

...

It's more than what you can do with Tapestry ... it's also how you do it! Tapestry is a vastly productive environment. Java developers love it because they can make Java code changes and see them immediately ... no redeploy, no restart! And it's blazingly fast to boot (even when files changehave changed). Designers love it because Tapestry templates are so close to ordinary HTML, without all the cruft and confusion seen in JavaServer Pages. Managers love it because it makes it easy for large teams to work together productively, and because they know important features (including localization) are baked right in. Once you work in Tapestry there's no going back!

Tapestry is released under the Apache Software Licence License 2.0.

New And Of Note

Main Article: Release Notes

...

.

...

Roadmap

The 5.1 release is out and available now, work is finished on the imminent 5.2 release, and developers are beginning to focus on 5.3.

The goal is to produce such releases on a regular schedule, every 4 - 6 months.

High priorities for upcoming releases include Spring Web Flow integration, support for developing Tapestry applications as Portlets, a Javascript abstraction layer, removal of Javassist, IoC improvements, more add-on libraries and components, and improvements to documentation.

Third Party Libraries, Tutorials and Resources

A number of Third Party Libraries, Tutorials and Resources third party libraries, tutorials and resources are listed on the Tapestry Home Pagethe Modules page.

Adaptive API

A key feature of Tapestry 5 is its adaptive API.

In traditional Java frameworks, including Tapestry 4, user code is expected to conform to the framework. You create classes that extend from framework-provided base classes, or implement framework-provided interfaces.

This works well until you upgrade to the next release of the framework: with the new features of the upgrade, you will more often than not experience breaks in backwards compatibility. Interfaces or base classes will have changed and your existing code will need to be changed to match.

In Tapestry 5, the framework adapts to your code. You have control over the names of the methods, the parameters they take, and the value that is returned. This is driven by annotations, which tell Tapestry under what circumstances your methods are to be invoked.

For example, you may have a login form and have a method that gets invoked when the form is submitted:

...


public class Login
{
    @Persist
    @Property
    private String userId;

    @Property
    private String password;

    @Component
    private Form form;

    @Inject
    private LoginAuthenticator authenticator;

    void onValidateForm()
    {
        if (! authenticator.isValidLogin(userId, password))
        {
            form.recordError("Invalid user name or password.");
        }
    }

    Object onSuccess()
    {
        return PostLogin.class;
    }
}

About Releases and Snapshots

You can also pull down Tapestry modules in the form of binary and source JARs from the Maven Central repository.

Tapestry itself is built using Gradle

This short snippet demonstrates a bit about how Tapestry operates. Pages and services within the application are injected with the @Inject annotation. The method names, onValidateForm() and onSuccess(), inform Tapestry about when the method is to be invoked. The two events validateForm and success occur when a form is submitted; "validateForm" is triggered to perform cross-field validations, and "success" is only triggered when there are no validation errors. The onSuccess() method's return value directs Tapestry on what to do next: jump to another page within the application (here identified as the class for the page, but many other options exist). When there are exceptions, the page will be redisplayed to the user.

This also represents a distinct change from Tapestry 4. In earlier versions of Tapestry, the Form component's listener parameter would be bound to the method to invoke, by name. Further, the listener method had to be public. This new approach not only supports multiple listeners, but provides an improved separation of view concerns (inside the page's HTML template) and logic concerns (inside the Java class).

In many cases, additional information about the event is available, and it can be passed into the method by adding parameters to the method. Again, Tapestry will adapt to your parameters, in whatever order you supply them.

Tapestry also saves you effort: the @Property annotation marks a field as readable and writable; Tapestry will provide the accessor methods automatically.

Finally, Tapestry 5 explicitly separates actions (requests that change things) and rendering (requests that render pages) into two separate requests. Performing an action, such as clicking a link or submitting a form, results in a client side redirect to the new page. This approach, called "redirect after post", helps ensure that URLs in the browser are book-markable – but it also requires that a bit more information be stored in the session between requests (using the @Persist annotation).

About Snapshots and Releases

Tapestry is built using Maven, which makes it really easy to download the source and build it yourself, either the whole project, or just one single module.Better yet, you can pull down Tapestry modules from the central Maven repository.

The use of Maven and Gradle has let us move with great speed, providing preview releases and snapshots.

Snapshots are intermediate versions of releases. As of this writing, the most recent preview release is 5.0.2 and the current snapshots are for 5.0.3-SNAPSHOT. Maven keys off the , with "-SNAPSHOT" at the end of the version number. Maven notices that -SNAPSHOT suffix and handles the dependency specially. It knows that snapshot releases can change frequently, so it will keep checking (at least once a day, maybe more often) to see if there's an updated version of the snapshot.

...

Snapshots don't go in the Maven central Maven repository (that's reserved for full releases). Instead, they go into the Tapestry snapshots repository at httphttps://tapestryrepository.formos.com/maven-snapshot-repositoryImage Removedapache.org/content/groups/snapshots/org/apache/tapestry/.

To access this the snapshot repository, you may just add -DremoteRepositories=http://tapestryrepository.formosapache.com/maven-snapshot-repositoryorg/snapshots/ to the command line when running Maven.

Your best bet is to use the quickstart Maven archetype to create your initial Tapestry project; it generates a full project directory, including a POM that links to the Apache snapshots repository.

Documentation on this site usually sometimes refers to the latest snapshot ... that is, it is usually often ahead of the last official release, with version-specific differences clearly marked. In some cases, it is written as if the snapshot release is stable; . For example, if documentation refers to version 5.17.x .x and that doesnhasn't workbeen released yet, you can try 5.17.x.x-SNAPSHOT.

Principle 1 – Static Structure, Dynamic Behavior

Main article: Principles

Tapestry is designed to be extremely scalable in several dimensions:

  • Tapestry applications may contain large numbers of pages and many custom components.
  • Tapestry applications may contain very complex functionality.
  • Tapestry applications may be created by large, diverse teams.
  • Tapestry applications can service large numbers of concurrent users.

One core architecture decision in Tapestry exists to service many of the above goals (and others that are harder to describe). Static Structure, Dynamic Behavior

In Tapestry, the structure of any particular page is static. This is necessary for several reasons, most importantly because Tapestry pages are pooled (in versions 5.1 and before). Creating a Tapestry page is an involved process, because the page object is simply the root of a large tree of other objects including user provided components, many kinds of structural objects, template objects, and others. Creating a new page instance for each request is simply not scalable.

Instead, Tapestry pools pages. Once created, a page instance will be stored in a pool for that particular type of page, and reused in later requests. An incoming request, the result of a user clicking a link or submitting a form, will be processed by some server within a cluster, and will use some page instance within the page pool. Because page instances are static and uniform across instances and servers, Tapestry can use any available page instance, or create a new one as needed.

Tapestry does not need to store page instances inside the HttpSession. At most, it stores a smattering of persistent field values from the page, but not the entire page instance. This lean use of the HttpSession is key to Tapestry's very high scalability, especially in a clustered configuration.

In some Tapestry-like frameworks, such as Faces and Wicket, the page structure is more dynamic, at the cost of storing much, much more data in the HttpSession.

This static structure is not so limiting as you might think. With different kinds of conditional and looping components, and the ability to "jump out of the flow" and render components in an arbitrary order, you will not find Tapestry to be rigid ... anything but!

Public vs. Internal

An issue plaguing older versions of Tapestry (version 4 and earlier) was the lack of a clear delineator between private, internal APIs and public, external APIs. The fact that your code would extend from base objects but that many of the methods on those base objects were "off limits" further confused the issue. This has been identified as a key factor in the "steep learning curve of Tapestry" meme.

With the clean slate of Tapestry 5, the developers have been much more rigorous about distinguishing internal vs. external API's.

First of all, anything inside the org.apache.tapestry5.internal package is internal. It is part of the implementation of Tapestry. It is the man behind the curtain. You should not ever need to directly use this code. It is a bad idea to do so, because internal code may change from one release to the next without concern for backwards compatibility.

Backwards Compatibility

Older versions of Tapestry (4 and earlier) were plagued by backwards compatibility problems with every major release. Tapestry 5 does not even attempt to be backwards compatible to Tapestry 4. Instead, it lays the ground work for true backwards compatibility going forwards.

Tapestry 5's API is based almost entirely on naming conventions and annotations. Your components are just ordinary Java classes; you will annotate fields to allow Tapestry to maintain their state or to allow Tapestry to inject resources, and you will name (or annotate) methods to tell Tapestry under what circumstances a method should be invoked.

Tapestry will adapt to your classes. It will call your methods, passing in values via method parameters. Instead of the rigidness of a fixed interface to implement, Tapestry will simply adapt to your classes, using the hints provided by annotations and simple naming conventions.

Because of this, Tapestry will be able to change internally to a great degree without it affecting any of the application code you write. This finally cracks the backwards compatibility nut, allowing you to have great assurance that you can upgrade to future releases of Tapestry without breaking your existing applications.

This is already evident in Tapestry 5.1, where many new features and improvements have occurred, but is still 100% backwards compatible to Tapestry 5.0, as long as you've avoided the temptation to make use of internal APIs.