Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Since
since5.2

Service Implementation Reloading

Tapestry's ability to live reload page and component classes is a huge boon to development productivity, but what about reloading services ?

...

As of release 5.2, you can change your service implementation, and Tapestry picks up the change immediately. A service can even change its dependencies when being reloaded ... but it can't change its interface.

Limitations

  • Reloading only works for services, and only for services with the default service scope (i.e., global singletons). Live reloading does not apply to modules, service interfaces, contributions, or anything but just the service implementation.
  • Reloading is limited to proxyable services: services with an interface and an implementation of that interface.
  • Reloading requires that the underlying class files be simple, local, filesystem files (not, for example, files inside a JAR).
  • If a service has internal state of any kind, that state is lost when the class is reloaded and the service re-instantiated. However, if a service has a configuration, the configuration will be reconstructed and injected into the service.
  • Services are decorated only once, so any decorations or advice applies to the initially loaded version of the class, and will not be recalculated when the class changes.

Class Loader Issues

Tapestry creates a new class loader for <each service implementation>. When the underlying .class file changes, the class loader is discarded along with the instance, and a new class loader is created.

...

The JVM should be able to eventually garbage collect the class loader. However, if the class publishes itself to some other service (for example,n adding itself as a listener to an event published by some other service), then the instance and the garbage collector will be leaked.

Note

Be careful about publishing any instances of a reloadable class.

Update Checks

Update checks are normally driven by tapestry-core, which periodically checks for changed templates, message catalogs, and component classes. Checks for changed service implementation classes occur at the same time.

In an application that is not driven by the web tier, you will need to periodically invoke the fireCheckForUpdates() method of the UpdateListenerHub service (which was moved from tapestry-core to tapestry-ioc for this purpose).