Project

General

Profile

Vaadin Add-on » History » Version 6

Henning Blohm, 01.07.2013 11:09

1 1 Henning Blohm
h1. The Vaadin Add-on
2
3
The Vaadin add-on provides the Vaadin libraries and some minimal supporting functionality:
4
5 2 Henning Blohm
* The *ContextClassLoader* ("source":https://redmine.z2-environment.net/projects/z2-addons/repository/z2-addons-vaadin/revisions/master/entry/com.vaadin/java/src.api/com/zfabrik/vaadin/ContextClassLoader.java, "javadoc":http://www.z2-environment.net/javadoc/com.vaadin!2Fjava/api/com/zfabrik/vaadin/ContextClassLoader.html) utility helps loading your Vaadin application class from the right context.
6 4 Henning Blohm
* An extensibility utility. The *ExtensionComponentsUtil* ("source":https://redmine.z2-environment.net/projects/z2-addons/repository/z2-addons-vaadin/revisions/master/entry/com.zfabrik.vaadin/java/src.api/com/zfabrik/vaadin/ExtensionComponentsUtil.java, "javadoc":http://www.z2-environment.net/javadoc/com.zfabrik.vaadin!2Fjava/api/com/zfabrik/vaadin/ExtensionComponentsUtil.html) help you to split a Vaadin web application across modules.
7 1 Henning Blohm
8
h2. More details on the ContextClassLoader
9
10 4 Henning Blohm
In non-modular application environments like the typical Java Web Application Server, you will typically use a build tool like ANT or Maven to package all libraries and resources that are required to run your Web application into one Web application archive (WAR). At runtime, a Web container like Apache Tomcat serves all code-like resources of the Web app from one classloading scope. 
11
12
Toolkits like Vaadin that need to load user classes by name now need to decide what class loader to refer to for loading of user-defined classes, such as the actual application class in the Vaadin case. The right and de-facto standard choice is to use the context class loader associated with the current thread. Unfortunately Vaadin uses the class loader that loaded the Vaadin classes however. 
13
14
In modular environments, such as Z2 but also OSGi, the Vaadin implementation will typically be shared among many Web applications. In that case, the application may see the Vaadin types but not vice versa.
15
16
In order to make Vaadin work as expected, add the following init parameter to the Vaadin servlet config in the @web.xml@ file of your Web app:
17
18
<pre><code class="xml">
19
<init-param>
20
	<param-name>ClassLoader</param-name>
21
	<param-value>com.my.package.ContextClassLoader</param-value>
22
</init-param>
23
</code></pre>
24
25
Read on here:
26
* "web.xml":https://redmine.z2-environment.net/projects/z2-samples/repository/z2-samples-vaadin-spring-hibernate/revisions/master/entry/com.zfabrik.samples.vaadin-spring-hibernate.web/web/WebContent/WEB-INF/web.xml of Vaadin sample app
27
* "Ticket":http://dev.vaadin.com/ticket/9809 with Vaadin
28
* A "blog article":http://www.z2-environment.net/blog/2012/07/for-techies-protecting-java-in-a-modular-world-context-classloaders/ on class loader topics
29 1 Henning Blohm
30
h2. More details on the ExtensionComponentsUtil
31 5 Henning Blohm
32
While the context class loader from above is a necessity to use Vaadin, the extension components util (ECU) is a great but not strictly required addition. It implements the following formula
33
34 6 Henning Blohm
(Vaadin is all Java) + (Z2 for modular Java applications) => Modular Vaadin user interfaces on Z2
35 5 Henning Blohm
36 1 Henning Blohm
More specifically, when applications get bigger, user interface implementations, like other parts of your implementation, have a tendency to become too big to maintain as single, monolithic modules. Using the ECU you can rather easily break your user interface implementation into modules that may have their completely private set of dependencies. This does not only allow to split the code base into well-managable pieces, it does also allow to cleanly separate concerns and to implement general user interface extensibility.
37 6 Henning Blohm
38
h3. Doing it
39
40
The extension component, that will be retrieved by the to-be-extended Vaadin UI must declare the extension point it belongs to and some priority, e.g. like this:
41
42
<pre><code class="bash">
43
com.zfabrik.vaadin.extension.point=com.acme.sample.admin.mainTab
44
com.zfabrik.vaadin.extension.order=100
45
</code></pre>
46
47
The extension point id used to find it (see below), the order is used to sort extensions. The latter can be useful, for example, to define the order of tab panels in a tab layout.
48
49
Now the component defined, after lookup, must implement the interface *IExtensionComponentFactory* ("source":https://redmine.z2-environment.net/projects/z2-addons/repository/z2-addons-vaadin/revisions/master/entry/com.zfabrik.vaadin/java/src.api/com/zfabrik/vaadin/IExtensionComponentFactory.java, "javadoc":http://www.z2-environment.net/javadoc/com.zfabrik.vaadin!2Fjava/api/com/zfabrik/vaadin/IExtensionComponentFactory.html). This is so that a new component instance can be bound to a consuming Vaadin application. Also, it allows Z2 to bind the using application's life cycle to the extension component, so that an invalidation of the extension component also stops the using application.
50
51
One convenient way of implementing *IExtensionComponentFactory* is to declare a component of type *com.vaadin.ui.Component* with a custom *component.className".
52
53
On the consuming side, retrieving extension components for an extension point is as easy as running
54
55
<pre><code class="java">
56
// retrieve all Vaadin components for extension point "com.acme.sample.admin.mainTab"
57
for (Component c : ExtensionComponentsUtil.getComponentyByExtensionForApplication(application,"com.acme.sample.admin.mainTab")) {
58
   // and add them to this.
59
   addComponent(c);
60
}
61
</code></pre>