Kontakt

Archive for März, 2010

Jazoon 2010 Talk: JavaServer Faces 2.0 vs. Tapestry 5

Dienstag, März 30th, 2010

I will be speaking at Jazoon’10 in Zurich, Switzerland. The program committee informed me that my talk JavaServer Faces 2.0 vs. Tapestry 5: A Head-to-Head Comparison has been accepted. The international conference on Java technology will take place 1-3 June 2010, in Zurich, Switzerland.

The speaking slot for this presentation will be announced soon at http://jazoon.com/. To give you some impression of the presentation I provide you the abstract which I sent to the program committee.

JSR-314 (JavaServer Faces 2.0) has passed its final approval ballot. The JSF 2.0 Expert Group standardized some of the best features and innovations from open source projects like Facelets, Seam and Ajax4jsf. The recent version of JSF improves a lot of things which JSF 1.2 didn’t get right. Some examples are configuration, composite components, GET support, navigation, etc.

The Apache Tapestry web framework has been making a name for itself in terms of innovative features and ease of use. Tapestry 5 features concise templates, minimal amounts of Java code, high performance, and important productivity features such as live class reloading. Despite the fact that there is a similarity between JSF 2 and Tapestry 5, their implementation is quite different.

In this session, I’ll make a head-to-head comparison of JSF 2.0 and Tapestry 5. I’m going to show the strength and weakness of both frameworks. Even though the speaker is biased (he is Apache Tapestry Committer), the comparison is going to be fair. I’ll rate the two projects on critical aspects of their design, learning curve, easiness of use and productivity.

More information about the presentation will be available soon.

I hope to see some Tapestry folks in Zurich. If you will be at the conference, just drop me a line.

See you in Zurich.

Contribution Methods: Naming Conventions vs Annotations

Freitag, März 5th, 2010

One of the most powerful concepts of Tapestry IoC is distributed configuration. Every service can have a configuration which can be created across several IoC modules of an application. When a service instance is created all modules are scanned for contribution methods. A contribution method is a module method whose name consists of the prefix contribute and a service id. The service id is used to identify the service to contribute into. There are three different styles of configurations:

  • Unordered Configuration of type java.util.Collection
  • Ordered Configuration of type java.util.List
  • Mapped Configuration of type java.util.Map

When creating a service instance the registry creates an empty configuration and passes it to all the available contribution methods for the service. In the following example you can see a contribution method for the service with the id ApplicationDefaults.

public class AppModule {

   public static void contributeApplicationDefaults(
         MappedConfiguration<String, String> config) {

      config.add(SymbolConstants.PRODUCTION_MODE, "false");
   }
}

This approach works fine because a service id is unique inside the service registry. But identifying services by string ids is often error prone. First if you want to contribute to a configuration of a service you need to know the id of the service. For this purpose you have to look into Tapestry sources or call the ServiceStatus page. Second if you refactor your application and rename an id of a service, your contribution won’t work anymore.

As of version 5.2 (I committed the code today) the annotation @Contribute can be used as an alternative for naming convention for contribution methods. The annotation may be placed on an arbitrary named method of a module to identify this method as a contribution method. The value of the annotation is the type of the service to contribute into. The following example is an alternative for the contribution method above. Note that service with id ApplicationDefaults is of type SymbolProvider.

public class AppModule {

   @Contribute(SymbolProvider.class)
   public static void arbitraryName(
         MappedConfiguration<String, String> config) {

      config.add(SymbolConstants.PRODUCTION_MODE, "false");
   }
}

What if you have several implementations of a service interface? For example Tapestry provides several instance of the service SymbolProvider. In this case you have to disambiguate the service instances with marker annotations. In Tapestry the services ApplicationDefaults and FactoryDefaults are marked with annotations @ApplicationDefaults and @FactoryDefaults. We need to modify our contribution method a little bit in order to identify the service to contribute into. For this purpose the @Marker annotation should be placed on the contributor method. The value of the annotation is the class of a marker annotation which was used to disambiguate the service instance. The following contribution method is meant for the instance of SymbolProvider service marked with the annotation @ApplicationDefaults.

public class AppModule {

   @Contribute(SymbolProvider.class)
   @Marker(ApplicationDefaults.class)
   public static void arbitraryName(
         MappedConfiguration<String, String> config) {

      config.add(SymbolConstants.PRODUCTION_MODE, "false");
   }
}

Enjoy!

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