Kontakt

4
Mai

I’m pleased to announce the Tapestry Tools project, which aims to build a Tapestry plugin based on Eclipse Web Tool Platform within the scope of Google Summer of Code 2011. The plugin will be developed by Gavin Lei, who applied as GSoC student at the Apache Software Foundation. Fortunately his project has been accepted and I’ll be mentoring him during SGoC 2011.

GSoC is a global program that offers student developers stipends to write code for various open source software projects. This year three Tapestry based projects has been accepted.

Project Student Mentor
Eclipse WTP based Tapestry visual editor project Gavin Lei Igor Drobiazko
Cross-site request forgery protection for Apache Tapestry Markus Jung Ulrich Stärk
Right Click Menu, grid enhancements and two optional components for the Apache Tapestry5 java web application framework Dragan Sahpaski Kalle Korhonen

The full list of accepted projects is available here.

Although students are expected to start coding at May 23rd, Gavin Lei is already working on delivering the Eclipse plugin for the Tapestry community.  More details on the Tapestry Tools Project are available at the project’s site.

I’m looking to forward to try out a very early version of the plugin.

8
Apr

Next Tuesday (April 12th, 2011) I’ll be giving the JavaServer Faces 2.0 vs. Tapestry 5 talk at CONFESS 2011 in Viena, Austria. CONFESS is a JEE and JSF conference organized by IRIAN and the eJUG Austria. Initially this conference was named JSFDays and was purely related to JavaServer Faces. Starting from 2009 the organizers added a JEE track. In 2011 the conference has been renamed to CONFESS (Conference For Enterprise Software Solutions).

However, if you take a look at the program, you’ll still will find a bunch of JSG talks. So I expect a lot of JSF users among the conference visitors and hope to meet them in my talk. Looking forward to have an interesting and fair comparison.

The conference program is quite interesting. I’m looking forward to attend the talks by Peter Niederwieser ( Smarter Testing With Spock and Gradle – A Better Way To Build) and Jevgeni Kabanov (Do you really get Memory?).

1
Apr

As you probably know, the Tapestry 5 in Action book is available through MEAP since March 23rd, 2011. This book has been awaited by the Tapestry community for a while and is currently the MEAP bestseller for the week ending April 1st, 2011. This is not an April Fools’ joke. See it here, here or in the following screenshot.

I know that sales figures of the first week are not very informative about the success of a book and that the other books in the list are available through MEAP for months, but this is still an awesome news for Tapestry.

30
Mrz

The Tapestry team is currently working full steam ahead on the new features for the 5.3 release like JPA 2 integration, plactic (new byte code modification library based on ASM), JavaScript abstraction layer, etc. Besides that we are glad to provide maintenance and bugfix releases.

I’m pleased to announce the Apache Tapestry 5.2.5 maintenance release. The main fix in this release is TAP5-1208, which fixes the issue with null values of mutable fields of components, when debugging applications. This bug has been introduced in 5.2.4 with the deprecation of page pooling. The official release notes can be found here.

Tapestry 5.2.5 can be downloaded in either binary or source format here. The release is also available via Maven from the Apache Mirrors, or via the central Maven repository:

<dependency>
   <groupId>org.apache.tapestry</groupId>
   <artifactId>tapestry-project</artifactId>
   <version>5.2.5</version>
</dependency>

Enjoy!

23
Mrz

I’m very pleased to announce that the Tapestry 5 in Action MEAP started just few minutes ago. Order the book here and start reading today. The MEAP (Manning Early Access Program) enables you to receive new chapters as they are being written. You can also provide feedback and errata, and help to shape the final manuscript on Manning’s forum.

The first chapter of the book is freely available for download here.

Enjoy Tapestry.

24
Feb

Yesterday I made some changes to the Tapestry’s component report which will make the report even more useful. As of version 5.3 the report will:

  1. Accept several root packages for a single library
  2. Mark deprecated components and/or parameters as we are used to from our IDE

If you used the component report plugin for your own components, you already know that before Tapestry 5.3 you needed to add the following to the reporting/plugins section of your POM:

<plugin>
    <groupId>org.apache.tapestry</groupId>
    <artifactId>tapestry-component-report</artifactId>
    <version>5.2.4</version>
    <configuration>
       <rootPackage>org.example.lib</rootPackage>
    </configuration>
</plugin>

As of Tapestry 5.3 the plugin is able to generate a component reference for a library with several root packages. So, the report configuration requires a new rootPackages element which may contain several rootPackage elements.

  <plugin>
    <groupId>org.apache.tapestry</groupId>
    <artifactId>tapestry-component-report</artifactId>
    <version>5.3.0-SNAPSHOT</version>
    <configuration>
       <rootPackages>
          <rootPackage>org.example.lib</rootPackage>
          <rootPackage>com.acme.library</rootPackage>
       </rootPackages>
   </configuration>
</plugin>

Now let’s see an example how the component report for a library with multiple root package will look like.

The screenshot above demonstrates that for each provided root package the component report generates an individual component reference. Furthermore you can see that deprecated components are canceled so that you immediately know which components will be removed in the upcoming releases.

The detail page for a deprecated component is shown below.

Also deprecated component parameters are now highlighted, as shown in the following screenshot.

As you know the component report is a Maven plugin and so can’t be used by non-Maven users. We are planing to untie the report from Maven, so that you can generate the component reference with any build tool you like.

9
Feb

Brussels JUGMy first Tapestry talk in 2011 will take place in Brussels. On February 17th I’ll be speaking on Tapestry at Brussels JUG. This talk is special as it will take 3 hours, from 7 pm to 10 pm. I would say it is more a workshop than a talk. So, if you are located in central Europe and want to learn Tapestry, don’t miss this event.

However, what I’m going to cover in this talk? We will start with an introduction into Tapestry. Having so much time for a talk gives me the possibility for live coding, so you can expect a lot of demos. I will show a lot of source code and will demonstrate the new demo application that I’m currently writing for my Tapestry 5 in Action book.

After the introduction we’ll move forward with a JSF 2.0 vs. Tapestry comparison. This is basically the same talk I was giving at Jazoon 2010.

More details on the Tapestry night are available here. Don’t forget to reserve you seat here. The entry is free.

See you there.

17
Jan

Last week I made some changes to Tapestry IoC which provide the support for the JSR-330. Beginning with version 5.3 it will be possible to use JSR-330 annotations for injection. Let’s see the overlappings between JSR-330 and Tapestry IoC before we dive in into the details.

JSR-330
javax.inject
Tapestry
org.apache.tapestry5.ioc.annotations
@Inject @Inject
@Inject
@Named
@InjectService
@Scope @Scope
@Qualifier Tapestry marker annotations don’t need any qualifier annotations
@Singleton By default all Tapestry services are singletons

In the table above you can see that most of annotations are interchangeable. However, there are few differences in semantics.

Field Injection

Let’s start with field injection. In Tapestry the injection into fields is triggered by @Inject or @InjectService annotations. When @Inject annotation is present on a field, Tapestry tries to resolve the object to inject by the type of the field. If several implementations of the same service interface are available in the registry, you have to disambiguate which implementation you want to be injected. This can be done by placing the @InjectService annotation on the injection point.

package com.tapestry5inaction.services.impl;

import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.InjectService;

...

public class AuthenticationFilter implements ComponentRequestFilter {

   @InjectService("HttpBasic")
   private AuthenticationService basicAuthService;

   @InjectService("HttpDigest")
   private AuthenticationService digestAuthService;

   @Inject
   private Response response;

   ...

}

Now let’s see the JSR-330 equivalent of the same service. As you can see the @Inject annotations are interchangeable. The difference is how to get a service by its unique id. For this purpose JSR-330 provides the @Named annotation which accompanies the @Inject annotation.

package com.tapestry5inaction.services.impl;

import javax.inject.Inject;
import javax.inject.Named;

...

public class AuthenticationFilter implements ComponentRequestFilter {

   @Inject @Named("HttpBasic")
   private AuthenticationService basicAuthService;

   @Inject @Named("HttpDigest")
   private AuthenticationService digestAuthService;

   @Inject
   private Response response;

   ...

}

Constructor Injection

For constructor injection the @Inject annotations are interchangeable. You can use either JSR-330 or Tapestry annotation to mark a constructor for injection. Note that at most one constructor per class may be marked as injection point.

However, the semantics of constructor injection are different in JSR-330 and Tapestry IoC. In JSR-330 a constructor is injectable only if the @Inject annotation is present.

public class Car {

   public Car() { ... }

   @Inject
   public Car(Engine engine) { ... }
}

In Tapestry the @Inject annotation for constructors is optional. All available constructors are candidates for injection: the constructor with the most parameters will be invoked.

public class Car {

   public Car() { ... }

   public Car(Engine engine) { ... }

}

When several constructors are available and you don’t want the constructor with most  parameters to be injectable, you need to place the @Inject annotation.

public class Car {

   public Car() { ... }

   @Inject
   public Car(Engine engine) { ... }

   public Car(Engine engine, Logger logger) { ... }

}

Injection Into Pages and Components

Inside Tapestry components, injection occurs exclusively on fields. So far the injection was triggered by the @Inject or @InjectService annotations. As of version 5.3 the injection points can also be marked with JSR-330 annotations. The following example demonstrates that.

public class Index {

   @Inject
   private Request request;

   @javax.inject.Inject
   private ComponentResources resources;

   @javax.inject.Inject
   @Named("FrenchGreeter")
   private Greeter greeter;

   @javax.inject.Inject
   @Symbol(SymbolConstants.PRODUCTION_MODE)
   private boolean productionMode;

   void onActivate() { ... }

}

Method Injection

Injectable methods is a next slight difference. In JSR-330 a method is injectable if the @Inject annotation is present. In Tapestry the @Inject annotation is optional. An ordinary setter method is a candidate to perform injection.

public class Car {

   private Engine engine;

   public void setEngine(Engine engine) {
      this.engine = engine;
   }

}

When building a Car instance, Tapestry IoC will try to resolve a service of type Engine. If available, Tapestry will perform injection by invoking the setter method.

Besides that, module methods are injectable. Again, there is no need to mark the methods with @Inject annotation as Tapestry explicitly knows which module methods to invoke. In the following example you can see how to use @Named annotation to inject a service by id into a contribute method.

public class TapestryModule {

   @Contribute(BindingSource.class)
   public static void provideBindings(
         MappedConfiguration<String, BindingFactory> cfg,

         @Named("PropBindingFactory")
         BindingFactory propBindingFactory, 

         @Named("MessageBindingFactory")
         BindingFactory messageBindingFactor ) {

      cfg.add(BindingConstants.PROP,
               propBindingFactory);
      cfg.add(BindingConstants.MESSAGE,
               messageBindingFactory);

   }

   ...
}

Marker Annotations

Both JSR-330 and Tapestry IoC allow you to disambiguate services by marker or qualifier annotations, as shown in the following example.

public class Index {

   @Inject
   @French
   private Greeter greeter;

}

Again, there is a slight difference. In JSR-330 a qualifier annotation like @French in the example above needs to be annotated by the @Qualifier annotation.

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@javax.inject.Qualifier
public @interface French {
}

In Tapestry any annotation can be a marker annotation. You don’t need to place something like the @Qualifier annotation on your marker annotation.

Scopes

Now let’s talks about service scopes.

By default, a JSR-330 injector creates an instance, uses the instance for one injection, and then forgets it. By placing the @Scope annotation you can tell the injector to retain the instance for possible reuse in a later injection. If you want a service to be a singleton, you need to use the @Singleton annotation.

In Tapestry, it is exactly the other way around. By default a service is a singleton. Once an instance is created, it is reused for injection. Another available scope is perthread, which exists primarily to help multi-threaded servlet applications. If a service has perthread scope, it is recreated for every incoming request.

Summary

As you have seen the most annotations in JSR-330 and Tapestry IoC are interchangeable, but there are few differences in semantics. These differences might be a blocker to pass the TCK. There are also some other challenges which make it difficult to provide a 100% portability: for example the TCK expects that a service interface can be downcasted to a service implementation (honestly I’m wondering why the TCK expects such a behavior). This just doesn’t work in Tapestry as the implementation is a proxy which delegates to the real implementation instance.

Right now you can use JSR-330 annotations in Tapestry IoC with respect to Tapestry semantics. In the next weeks I’ll be working on the portability issues. Stay tuned.

24
Nov

As you probably know currently I’m writing a “Tapestry 5 in Action” book to be published by Manning Publications Co.

Yesterday I had a chat with my contact at Manning. We discussed the further steps which needs to be done before MEAP. Among other things we need 5-10 technical reviewers on a voluntary basis. If you want to participate on the project, just drop me a line. Unless I know you from the Tapestry’s community, please describe your experience with Tapestry. Note that not only experts but also Tapestry newbies are needed. So, feel free to contact me. We will choose the best combination of beginners, advanced users and experts.

21
Nov

This week I was attending Matt Raible’s talk Comparing JVM Web Frameworks at Devoxx 2010. Matt came up with a matrix containing grades for a chosen set of features in various frameworks. The top 5 frameworks in the matrix has been presented in details. Unfortunately Tapestry got 13.5 points, only 1 point behind Wicket/Struts 2 (both 14.5 points).

I have no problems with being behind any framework if the comparison is made accurate. But in this case I feel like I need to defend Tapestry because I disagree with some of the grades given by Matt. The problem is that Matt is very famous and a lot of Java developers believe him blindly. Matt, you should be aware of it and be very careful by making any statements.

I talked to Matt after his presentation and promised him to send some links which will hopefully improve Tapestry’s grades. But Matt’s comparison caused a lot of discussions over the world, so I decided to write a public answer.

Here are some few grades I disagree with:

Developer productivity

I cannot understand why Tapestry didn’t get 1 point for developer productivity. C’mon Matt, did you ever hear about Tapestry’s Live Class Reloading feature which allows you to change your code and see the results immediately? You have mentioned that JRebel can boost developer productivity but forgot to mention that Tapestry has a similar functionality which is built-in.

Do you really believe that GWT, which requires an additional Java-to-JavaScript compile step, offers a better developer productivity? Sorry, but even GWT users I know don’t believe it.

Is Spring MVC really more productive than Tapestry? Is it because JSPs are better to read and to debug than Tapestry’ HTML templates? Or is it XML-based configuration that outweighs Tapestry’s annotation and convention-over-configuration approach?

Developer perception

Uh? Zero? Is it really that bad? Matt, your last mail on Tapestry’s user list was on 11th November 2009. One year is a long time. You should read the comments of new users who are enjoying learning Tapestry.

Indeed, the Tapestry team have been very bad in marketing but it will change. The new web site has been launched yesterday. The documentation has been improved. A German book on Tapestry 5 has been published. Currently I’m working on a translation of this book for Manning Publications Co. I’m pretty sure the “Tapestry 5 in Action” will make Tapestry more successful.

I’m talking on Tapestry very often and get a lot of feedback from Java developers. My impression is that the developer perception is better than zero. Much better.

Project Health

The first stable release of Tapestry 5, namely version 5.0.18, was released on 12th December, 2008. Since that time we successfully released 5.1.0.5 and 5.2.4 without to break any backward compatibility. Two major releases with various innovations and without any backward compatibility issues in two years. Isn’t it a healthy project? Shouldn’t you all forget the Tapestry’s bad reputation of backward compatibility? It is history now.

Scalability

One of Tapesry’s goals is scalability. Tapestry was built with scalability in mind and that’s why has a lean session usage. Tapestry claims to be scalable and you should read it in Tapestry’s documentation. Again, why not the best grade for this feature? Why do Struts 2 or GWT scale better? Did you try to scale a Tapestry application? I guess not.

Testing

C’mon Matt. Are you kidding? Tapestry is built for testability and provides a very nice testing functionality. I guess this coverage report tells everything.

Moral of the story

There are even more points which are better in Tapestry than they appear to be. If only the mentioned points have been rated accurately, Tapestry would easily make it to the top 5 frameworks in Matt’s presentation.

The moral of the story is: even though Matt Raible is a very respected person, you should not blindly rely on everything he tells you. Some frameworks are much better than some people speak about them. Give them a try and decide if they fit your needs.

Tapestry 5 Blog - Copyright © 2009 - Eclectic Theme by Your Inspiration Web - Powered by WordPress