Hello GlassFish 3

by Petter Holmström

Introduction #

In this article, we are going to explore some of the new features of GlassFish 3, including the support for OSGi, by creating a simple Hello World application that prints a greeting to the user using the Vaadin library:

What makes this application interesting is that it consists of one Java source file only – no configuration files, no HTML files, no CSS files.

Prerequisites #

In order to fully understand this article, you should be familiar with JEE development. Any previous Vaadin experience is not required. Finally, you should have heard of OSGi, although no experience in using it is required.

If you want to try out the code in this article you should get the latest version of GlassFish 3 (build 67 was used for this article) and Apache Ant 1.7. You also need to download the source code. Note, that you have to edit the build.xml file to point to the correct location of the GlassFish installation directory before you can use it!

The Source Code #

The source code in its entirety is listed here:

#!java
package helloworld;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;

import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
import com.vaadin.ui.*;

public class HelloWorldApp extends Application {
	
	@WebServlet(urlPatterns="/*")
	public static class Servlet extends AbstractApplicationServlet {

		@Override
		protected Class<? extends Application> getApplicationClass() {
			return HelloWorldApp.class;
		}

		@Override
		protected Application getNewApplication(HttpServletRequest request) throws ServletException {
			return new HelloWorldApp();
		}
	}
	
	@Override
	public void init() {
		Window mainWindow = new Window("Hello World Application");
		Label label = new Label("Greetings, Vaadin user!");
		mainWindow.addComponent(label);
		setMainWindow(mainWindow);
	}
}

The HelloWorldApp class is the main application class and the primary entry point for all Vaadin applications. It contains a single overridden method, init(), which is called upon application startup and is responsible for setting up the main window. Note, that the UI is created entirely in Java using a Swing-like API. In many cases, that's all there is to it – we do not even need to see any HTML or CSS (unless, of course, we want to create custom themes or widgets).

The Servlet class is a boilerplate class that is responsible for firing up the application. As you can see, it uses the new Servlet 3.0 @WebServlet annotation for configuring the servlet. Thanks to this, we no longer need a web.xml descriptor file.

It is also possible to create Vaadin applications without a custom servlet class. Instead, we can use the ApplicationServlet class included in the Vaadin library and configure it in the web.xml file like so:

#!xml
<web-app id="WebApp_ID" version="2.5">
	<display-name>Hello World</display-name>
	<servlet>
		<servlet-name>HelloWorld</servlet-name>
		<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
		<init-param>
			<param-name>application</param-name>
			<param-value>helloworld.HelloWorldApp</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>HelloWorld</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
</web-app>

In this case, we replace a boilerplate class with a configuration file, so it is up to the developer to decide which approach is better. Please note, however, that if we are going to deploy Vaadin as an OSGi bundle, this approach will not work (we will return to this matter later in this article). Therefore, for the remainder of this article, we are going use the Servlet 3.0 approach only.

Classical Deployment #

Before deploying the example application, we need to package it into a WAR. The class files should reside in the WEB-INF/classes-directory and the Vaadin library in the WEB-INF/lib-directory. This can easily be achieved with the following Ant-target:

#!xml
<target name="package-with-vaadin" depends="compile">
	<mkdir dir="${dist.dir}"/>
	<war destfile="${dist.dir}/helloworld-with-vaadin.war" needxmlfile="false">
		<lib file="${vaadin.jar}"/>
		<classes dir="${build.dir}"/>
	</war>
</target>

Please note the use of the needxmlfile attribute, which was added to Ant in version 1.7. If we omit this attribute, the war task will fail as it expects a web.xml file by default.

Once the application has been packaged, it is ready to be deployed. Both Eclipse and NetBeans have options for doing this directly in the IDE, but since this article is not tied to any particular IDE, we use the asadmin tool that comes with GlassFish:

$ asadmin deploy /path/to/helloworld-with-vaadin.war 

Unless anything strange happened during deployment, we can now open an ordinary web browser, navigate to http://localhost:8080/helloworld-with-vaadin and try out the application.

Bringing in OSGi #

In the previous section, we deployed the application in the classical JEE way. However, if we want to deploy multiple Vaadin applications to the same server, we have to either deploy the Vaadin library together with each application, or place it in the application server's global classpath. The former alternative always works, but slows down the deployment process and wastes disk space. The latter alternative only works if all Vaadin applications use the same version of the Vaadin library.

However, with GlassFish 3, there is a third alternative. As GlassFish 3 is OSGi-based, and OSGi supports multiple versions of the same bundle, we can deploy the Vaadin library as an OSGi bundle. OSGi-support is planned for Vaadin 6.2 and a preliminary manifest is already in the nightly builds as of October 21, 2009. The Vaadin library included in the source code archive also has an OSGi manifest and can be deployed by copying it into the {glassfish-installation-dir}/glassfish/domains/domain1/autodeploy/bundles directory.

If all our Vaadin applications use the same version of the Vaadin library, we can still deploy them in the classical way. We have to package them into WARs, but we can leave out the Vaadin library as it is already deployed. In the case of our Hello World example, we can easily do this with the following Ant-target:

#!xml
<target name="package-without-vaadin" depends="compile">
	<mkdir dir="${dist.dir}"/>
	<war destfile="${dist.dir}/helloworld-without-vaadin.war" needxmlfile="false">
		<classes dir="${build.dir}"/>
	</war>	
</target>

There is a potential pitfall we have to look out for when the Vaadin library is deployed as an OSGi bundle. As we mentioned in earlier in this article, using the ApplicationServlet class is not going to work. The reason for this is the way OSGi handles class loading. An OSGi bundle can only see the classes it explicitly imports. As ApplicationServlet is configured with the class name only and tries to load the class instance upon initialization, it will not be able to find it. Currently, the only way around this is to subclass AbstractApplicationServlet and provide the class instances directly, as we have done in this article.

Once the application is packaged, we can deploy and test it using the same procedure as in the previous section.

However, if we need to use multiple versions of the Vaadin library, things get a little more complicated. We will discuss this problem in the next section.

Full OSGi Deployment #

If there are multiple versions of the Vaadin library, only the latest version will be on the classpath for JEE web applications. This may be a problem if we want to deploy applications requiring different versions of the Vaadin library to the same server. To resolve this problem, we have to deploy our applications as OSGi bundles as well.

In practice, this means we have to add some information to the WAR manifest and deploy the application as an OSGi bundle instead of a web application archive. The manifest can be either created manually, or generated by the Ant script like so:

#!xml
<target name="package-as-osgi" depends="compile">
	<mkdir dir="${dist.dir}"/>
	<war destfile="${dist.dir}/helloworld-osgi.war" needxmlfile="false">
		<classes dir="${build.dir}"/>
		<manifest>
			<attribute name="Bundle-ManifestVersion" value="2"/>
			<attribute name="Bundle-Name" value="Hello World OSGi"/>
			<attribute name="Bundle-SymbolicName" value="helloworld"/>
			<attribute name="Bundle-Version" value="1.0.0"/>
			<attribute name="Bundle-Vendor" value="IT Mill Ltd"/>
			<attribute name="Require-Bundle" value="com.vaadin;bundle-version=&quot;6.1.0&quot;"/>
			<attribute name="Web-ContextPath" value="/HelloWorldOSGi"/>
			<attribute name="Export-Package" value="helloworld"/>
			<attribute name="Import-Package" value="javax.servlet,javax.servlet.annotation,javax.servlet.http"/>
			<attribute name="Bundle-ClassPath" value="WEB-INF/classes/"/>			
		</manifest>
	</war>
</target>

In short, this manifest tells the OSGi container that the bundle exports the package helloworld, imports the packages javax.servlet, javax.servlet.annotation and javax.servlet.http, and requires at least version 6.1.0 of the com.vaadin bundle (thus, newer versions are also valid). As no version restrictions have been imposed on the imported packages, the latest available versions will be used.

Also note the Web-ContextPath attribute. We use this to instruct GlassFish that the bundle we are deploying contains a web application.

Once the application has been packaged into a bundle, we deploy it by copying it into the {glassfish-installation-dir}/glassfish/domains/domain1/autodeploy/bundles directory.

We should now be able to test the application by pointing our web browser to http://localhost:8080/HelloWorldOSGi. We can also confirm that the application is in fact deployed as an OSGi bundle by opening the OSGi console and listing all the installed bundles:

$ telnet localhost 6666

The ps command lists all installed bundles. At the end of the list, you should see our application bundle:

Summary #

In this article, we have created a simple Hello World application using the Vaadin framework. We then deployed the application in three different ways: as an ordinary JEE web application with the Vaadin library included, as a JEE web application with the Vaadin library deployed as an OSGi bundle, and as a pure OSGi bundle.

Further Reading #

If you thought this article was interesting, you should also read Creating a Modular Vaadin Application with OSGi.

More information about GlassFish's OSGi-capabilities can be found in the following blog posts:

The documentation of Apache Felix – the OSGi container used by GlassFish – can be found here. This is a good place to start if you want to learn how to use OSGi.

3 Attachments
20897 Views
Average (4 Votes)
Comments
Nice article.

Can someone please check if the source code link works because to me it says it is corrupt.

Thank you

Posted on 5/31/11 10:55 AM.

Top
Thank you for this great article.

@Sopot The source code link works fine for me

I was going trough the tutorial and when I was trying to deploy war or bundle without OSGI I get a loading page and next this error :

Failed to load the widgetset: /helloworld-without-vaadin/VAADIN/widgetsets/com.vaadin.terminal.gwt.DefaultWidgetSet/com.vaadin.terminal.gwt.DefaultWidgetSet.nocache.js?1307610197568

I have deployed vaadin-6.6.1.jar into autodeploy/bundles repository in glassfish.

Thanks for idea.

Posted on 6/9/11 9:05 AM.

Top
Thank you for this helpful article.

I Had the same problem of @Sopot to open the helloworld.tar.gz file. I Can download the file, but when i open the file it says is corrupt.

Thanks

Posted on 9/5/11 7:22 PM.

Top
I had to untar the source archive with two steps with Cygwin otherwise I get an error:

$ tar tzvf Downloads/helloworld.tar.gz
tar: This does not look like a tar archive
tar: Skipping to next header
tar: Exiting with failure status due to previous errors

But the following works fine:

$ gzip -d helloworld.tar.gz
$ tar xvf helloworld.tar

I'm having the same problem as Thomas below with /VAADIN/* resources not working. I'm an OSGi noob but from what I gathered it has something to do with the classloader not being able to see the resources.

See the following hint about using OSGi fragements to alias loading /VAADIN/* resources
https://vaadin.com/forum/-/message_boards/view_message/740311 (Vaadin-OSGi-staticres which is included with the Vaadin OSGi add-on)

I'm still confused why it doesn't work since the Vaadin 6.7.4.jar DOES export VADDIN:

i.e. Export-Package: VAADIN.themes, VAADIN.themes.base, VAADIN.themes.base. <snip>

Maybe someone who understands OSGi better than I could explain why it fails.

Thanks!

Posted on 1/27/12 10:26 PM.

Top
Oops. I should have been more careful in my response. It looks like widgetsets are NOT exported but VAADIN themes ARE being served.

Works:
http://localhost:8080/HelloWorldVaadinOSGi/VAADIN/themes/reindeer/styles.css
http://localhost:8080/HelloWorldVaadinOSGi/VAADIN/themes/base/common/img/loading-indicator.gif

404 error:

http://localhost:8080/HelloWorldVaadinOSGi/VAADIN/widgetsets/com.vaadin.terminal.gwt.DefaultWidgetSet/com.vaadin.terminal.gwt.DefaultWidgetSet.nocache.js?1327697660913

Posted on 1/27/12 10:30 PM in reply to Kirk Rasmussen.

Top