Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: restore

Live Class and Template Reloading

Div
stylefloat:right
titleRelated Articles
classaui-label
Content by Label
showLabelsfalse
showSpacefalse
titleRelated Articles
cqllabel = "class-reloading" and space = currentSpace()

One of the best features of Tapestry is automatic reloading of changed classes and templates. Page and component classes will automatically reload when changed. Likewise, changes to component templates and other related resources will also be picked up immediately. In addition, starting in version 5.2, your service classes will also be reloaded automatically after changes (if you're using Tapestry IoC).

Template Reloading

When a template changes, all page instances (as well as the hierarchy of components below them) are discarded and reconstructed with the new template. However, classes are not reloaded in this case.

...

On a change to any loaded class from inside a controlled package (or any sub-package of a controlled package), Tapestry will discard all page instances, and discard the class loader.

Persistent field data on the pages will usually not be affected (as it is stored separately, usually in the session). This allows you to make fairly significant changes to a component class even while the application continues to run.

...

Only certain classes are subject to reload. Reloading is based on package name; the packages that are reloaded are derived from the application configuration.

If your root package is org.example.myapp, then only classes in the following packages (and their sub-packages) will be scanned for automatic reloads:

...

For example, your service may be in the business of creating new classes based on component classes, and keep a cache of those classes:

Code Block
java
java
public class MyServiceImpl implements MyService, InvalidationEventListener
{
  public final Map<String,Class> cache = new ConcurrentHashMap<String,Class>();

  . . .

  public void objectWasInvalidated() { cache.clear(); }
}

Here, the service implementation implements the InvalidationEventListener interface, as well as its service interface. The question is: how does it register for notifications?

In your module, you will want to use a service builder method, such as:

Code Block
java
java
public static MyService buildMyService(@Autobuild MyServiceImpl service, @ComponentClasses InvalidationEventHub hub)
{
  hub.addInvalidationListener(service);

  return service;
}

This is the intent of service builder methods; to do more than just injecting dependencies.

...

Starting with Tapestry 5.3, Live Class Reloading only works when not in "Production Mode". Check your application module (usually AppModule.java) to be sure you have:

Code Block
langjava
configuration.add(SymbolConstants.PRODUCTION_MODE, "false");

and that this isn't being overridden to "true" on your application's startup command line.

...

  • Be sure your project source files (your workspace in Eclipse, for example), are on a local drive, NOT a network location. Network drives are always slower, and the file system scanning needed for LCR can add a noticable lag if I/O is slow. If you use Maven, be sure to put your local repository (e.g. ~/.m2/repository) on a local drive for similar reasons.
  • Since LCR adds classes to your PermGen space, you may be running low on PermGen memory (and may eventually get a "java.lang.OutOfMemoryError: PermGen space" error). Try increasing PermGen size with a JVM argument of something like -XX:MaxPermSize=400m

Wiki Markup
{scrollbar}