Kontakt

14
Jun

Tapestry claims to be performant and scalable. You want a proof? Than read this great post. The author compares the performance of Rails, Wicket, Grails, Play, Tapestry, Lift, JSP, Context. It is not a surprise that Tapestry outperformed the most of the competitors. Here are the results:

For more details on the benchmark please read the original article.

Two years ago Peter Thomas made a similar comparison and the result was not that good for Tapestry. It seems like two year ago Wicket was ahead of ¬†Tapestry and Grails. But the recent comparison shows that Wicket’s performance is the worst. What could be the reason for such different results? First of all, I believe that Peter Thomas’ comparison was not accurate. Peter is known to be a Wicket lover. When the comparison is made by an unbiased person, then the results look completely different.¬†Another possible reason could be that Tapestry improved in the last two years a lot. Removal of page pooling and other important changes might be the reason for that. However, seeing that Tapestry’s performance just rocks is a satisfaction.

26
Mai

In the last post I gave you a short preview of the Tapestry/JPA integration library in the upcoming 5.3 release. In this post I’m going to show a new feature that I added yesterday. You will see that configuring JPA with Tapestry is much more simple than defined in the JPA specification.

The persistence.xml file is the standard configuration file in JPA used to define the persistence units. Let’s explore the following persistence descriptor using a non-JTA data source.

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             version="2.0">
   <persistence-unit name="Blue"
                     transaction-type="RESOURCE_LOCAL">

      <non-jta-data-source>
         jdbc/JPATest
      </non-jta-data-source>

      <properties>
         <property name="eclipselink.ddl-generation"
                   value="create-tables"/>
         <property name="eclipselink.logging.level"
                   value="fine"/>
      </properties>
   </persistence-unit>

</persistence>

Now let’s see how to provide an equivalent JPA configuration without using any XML descriptors. This can be accomplished by making a contribution to the EntityManagerSource service.

public class AppModule {

   @Contribute(EntityManagerSource.class)
   public static void configurePersistenceUnitInfos(
      MappedConfiguration<String,PersistenceUnitConfigurer>
      cfg) {

      PersistenceUnitConfigurer configurer
                 = new PersistenceUnitConfigurer() {

         public void configure(
                  TapestryPersistenceUnitInfo unitInfo) {

            unitInfo.nonJtaDataSource("jdbc/JPATest")
               .addProperty("eclipselink.ddl-generation",
                            "create-tables")
               .addProperty("eclipselink.logging.level",
                            "fine");
         }
     };

     cfg.add("Blue", configurer);
   }
}

The EntityManagerSource service’s configuration is a map in which the keys are persistence unit names and the values are PersistenceUnitConfigurer instances. In other words, a PersistenceUnitConfigurer instance is associated with a persistence unit to be configured. The TapestryPersistenceUnitInfo instance passed to the PersistenceUnitConfigurer holds the persistence unit metadata for use by the persistence provider. It may represent a persistence unit defined in the persistence.xml file or an empty persistence unit. Confused? Let me clarify it.

If the contribution key matches a persistence unit defined in the persistence.xml file, then the passed TapestryPersistenceUnitInfo instance is pre-filled with the metadata from persistence.xml. This metadata can be modified programmatically inside a PersistenceUnitConfigurer. If persistence.xml file is not present or the contribution key doesn’t match any persistence unit, the passed TapestryPersistenceUnitInfo instance is empty. This way Tapestry allows you to configure JPA without writing XML descriptor files.

Enjoy!

25
Mai

In this article I’m going to describe the Tapestry/JPA 2 Integration library that provides out-of-the-box support for using JPA 2 as the back end for normal CRUD style Tapestry applications. I added this library to Tapestry’s trunk some weeks ago but didn’t have any time to write an article about it. Now that we are close to a first 5.3 release, I would like to give you a preview of this library.

Configuring JPA

The persistence.xml file is the standard configuration file in JPA used to define the persistence units. By default, this file is expected to be located on the classpath in the META-INF directory. Tapestry reads this file to create the EntityManagerFactory. The following example demonstrates a persistence.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             version="2.0">
   <persistence-unit name="Red"
                     transaction-type="RESOURCE_LOCAL">
       <properties>
          <property name="javax.persistence.jdbc.driver"
                    value="org.h2.Driver" />
          <property name="javax.persistence.jdbc.url"
                    value="jdbc:h2:mem:test" />
          <property name="javax.persistence.jdbc.username"
                    value="sa" />
          <property name="eclipselink.ddl-generation"
                    value="create-tables"/>
          <property name="eclipselink.logging.level"
                    value="fine"/>
      </properties>
   </persistence-unit>

   <persistence-unit name="Blue"
                     transaction-type="RESOURCE_LOCAL">
      <non-jta-data-source>
         jdbc/JPATest
      </non-jta-data-source>
   </persistence-unit>

</persistence>

Note that you need to provide unique names for persistence units. In the example above we defined two persistence units named Red and Blue.

If you want to place the persistence.xml file in an other directory or name it arbitrarily, you can make a contribution to the SymbolProvider service, as shown in the following example. This is a quite useful feature if you want to use a different persistence descriptor for tests.

public class AppModule {

   @Contribute(SymbolProvider.class)
   @ApplicationDefaults
   public static void provideFactoryDefaults(
       MappedConfiguration<String, String> configuration) {

      configuration.add(
            JpaSymbols.PERSISTENCE_DESCRIPTOR,
            "/jndi-datasource-persistence-unit.xml");
   }
}

For each of the persistence units defined in the persistence.xml file Tapestry creates a TapestryPersistenceUnitInfo. The interface TapestryPersistenceUnitInfo is mutable extension of the PersistenceUnitInfo interface which allows you to configure a persistence unit programmatically. This can be accomplished by making a contribution to the EntityManagerSource service, as shown in the following example.

public class AppModule {

   @Contribute(EntityManagerSource.class)
   public static void configurePersistenceUnitInfos(
            MappedConfiguration<String,PersistenceUnitConfigurer>
            cfg) {

      PersistenceUnitConfigurer configurer
                 = new PersistenceUnitConfigurer() {

         public void configure(
                  TapestryPersistenceUnitInfo unitInfo) {
            unitInfo.addManagedClass(User.class);
         }
      };

      cfg.add("Blue", configurer);
   }
}

The EntityManagerSource service’s configuration is a map in which a persistence unit name is associated with a PersistenceUnitConfigurer instance. A PersistenceUnitConfigurer is used to configure a TapestryPersistenceUnitInfo that has been read from the persistence.xml file.

Automatically adding managed classes

If only a single persistence unit is defined, Tapestry scans the  application-root-package.entities package. The classes in that package are automatically added as managed classes to the defined persistence unit.

If you have additional packages containing entities, you may contribute them to the JpaEntityPackageManager service configuration.

public class AppModule {

   @Contribute(JpaEntityPackageManager.class)
   public static void providePackages(
            Configuration<String> configuration) {
      configuration.add("org.example.myapp.domain");
   }
}

You may add as many packages as you wish.

Injecting the EntityManager into page and component classes

The created entity managers can be injected into page and component classes.  Depending on whether more than one persistence unit has been defined, the way to inject EntityManager varies slightly.

Let’s start with a simple scenario, where only a single persistence unit is defined. In this case, an EntityManager can be injected using the @Inject annotation.

public class CreateAddress {

   @Inject
   private EntityManager entityManager;

   @Property
   private Address address;

   @CommitAfter
   void onSuccess() {
      entityManager.persist(address);
   }
}

Alternatively, you can use the @PersistenceContext annotation to get the EntityManager injected into a page or component.

public class CreateAddress {

   @PersistenceContext
   private EntityManager entityManager;

   @Property
   private Address address;

   @CommitAfter
   void onSuccess() {
      entityManager.persist(address);
   }
}

If you have multiple instances of persistence-unit defined in the same application, you need to explicitly tell Tapestry which persistence unit you want to get injected. So,  just placing @Inject annotation on the injection place is not sufficient.

public class CreateAddress {

   @PersistenceContext(unitName = "Blue")
   private EntityManager entityManager;

   @Property
   private Address address;

   @CommitAfter
   @PersistenceContext(unitName = "Blue")
   void onSuccess() {
      entityManager.persist(address);
   }
}

In the example above, the @PersistenceContext annotation’ s name attribute is used to explicitly define the name of the unit to inject.

Injecting EntityManager into services

While component injection occurs only on fields, the injection in the IoC layer may be triggered by a  field or a constructor. The following example demonstrates field injection, when a single persistence unit is defined in the persistence descriptor.

public class UserDAOImpl implements UserDAO {
   @Inject
   private EntityManager entityManager;

   ...
}

The constructor injection is demonstrated in the following example.

public class UserDAOImpl implements UserDAO {

   private EntityManager entityManager;

   public UserDAOImpl(EntityManager entityManager) {
      this.entityManager = entityManager;
   }

   ...
}

Because @PersistenceContext annotation must not be placed on constructor parameters, you can’t use constructor injection if multiple persistence units are defined in the same application. In such a case, only field injection is supported, as shown in the following example.

public class UserDAOImpl implements UserDAO {
   @Inject
   @PersistenceContext(unitName = "Blue")
   private EntityManager entityManager;

   ...
}

Transaction management

As you already know from the Hibernate integration library, Tapestry automatically manages transactions for you. The JPA integration library defines the @CommitAfter annotation, which acts as the correspondent annotation from the Hibernate integration library. Let’s explore the UserDAO interface to see the annotation in action.

public interface UserDAO {

   @CommitAfter
   @PersistenceContext(unitName = "Blue")
   void add(User user);

   List<User> findAll();

   @CommitAfter
   @PersistenceContext(unitName = "Blue")
   void delete(User... users);
}

As you can see, the annotation may be placed on service method in order to mark that method as transactional. Any method marked with @CommitAfter annotation will have a transaction started before, and committed after it is called. Runtime exceptions thrown by by a transactional method will abort the transaction. Checked exceptions are ignored and the transaction will be committed anyway.

Note that EntityTransaction interface does not support two phase commit. Committing transactions of multiple EntityManagers in the same request might result in data consistency issues. That’s why @CommitAfter annotation must be accompanied by the @PersistenceContext annotation if multiple persistence unit are defined in an application. This way you can only commit the transaction of a single persistence unit. You should be very carefully, if you are committing multiple transactions manually in the same request.

After placing the @CommitAfter annotation on methods, you need to tell Tapestry to advise those methods. This is accomplished by adding the transaction advice, as shown in the following example.

public class AppModule {

   @Match("*DAO")
   public static void adviseTransactionally(
         JpaTransactionAdvisor advisor,
         MethodAdviceReceiver receiver) {

      advisor.addTransactionCommitAdvice(receiver);
   }
}

That’s it for the first part of the article on JPA 2 support in Tapestry. In the next article I’ll cover some further interesting features of the JPA integration library like providing ValueEncoder for managed classes, using @Persist and @SessionState annotations with entities and JPA-enabled Grid component.

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.

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