Embedded Jetty, Vaadin and Weld

When I develop web applications I like to be able to quickly start them from Eclipse without having to rely on all kinds of heavy-weight tomcat or glassfish plugins. So what I often do is just create a simple Java based Jetty launcher I can run directly from Eclipse. This launcher starts up within a couple of seconds so this makes developing a lot more pleasant.

However, sometimes, getting everything setup correctly is a bit hard. So in this article I’ll give you a quick overview of how you can setup Jetty together with Weld for CDI and Vaadin as the web framework.

To get everything setup correctly we’ll need to take the following steps:

  1. Setup the maven pom for the required dependencies
  2. Create a java based Jetty Launcher
  3. Setup web.xml
  4. Add Weld placeholders

Setup the maven pom for the required dependencies

I use the following pom.xml file. You might not need everything if you for instance don’t use custom components. But it should serve as a good reference of what should be in there.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>group.id</groupId>
 <artifactId>artifact.id</artifactId>
 <packaging>war</packaging>
 <version>1.0</version>
 <name>Vaadin Web Application</name>
 
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <vaadin.version>6.7.1</vaadin.version>
  <gwt.version>2.3.0</gwt.version>
  <gwt.plugin.version>2.2.0</gwt.plugin.version>
 </properties>
 
 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
     <source>1.5</source>
     <target>1.5</target>
    </configuration>
   </plugin>
   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>gwt-maven-plugin</artifactId>
    <version>${gwt.plugin.version}</version>
    <configuration>
     <webappDirectory>${project.build.directory}/${project.build.finalName}/VAADIN/widgetsets</webappDirectory>
     <extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>
     <runTarget>cvgenerator-web</runTarget>
     <hostedWebapp>${project.build.directory}/${project.build.finalName}</hostedWebapp>
     <noServer>true</noServer>
     <port>8080</port>
     <compileReport>false</compileReport>
    </configuration>
    <executions>
     <execution>
      <goals>
       <goal>resources</goal>
       <goal>compile</goal>
      </goals>
     </execution>
    </executions>
    <dependencies>
     <dependency>
      <groupId>com.google.gwt</groupId>
      <artifactId>gwt-dev</artifactId>
      <version>${gwt.version}</version>
     </dependency>
     <dependency>
      <groupId>com.google.gwt</groupId>
      <artifactId>gwt-user</artifactId>
      <version>${gwt.version}</version>
     </dependency>
    </dependencies>
   </plugin>
   <plugin>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-maven-plugin</artifactId>
    <version>1.0.2</version>
    <executions>
     <execution>
      <configuration>
      </configuration>
      <goals>
       <goal>update-widgetset</goal>
      </goals>
     </execution>
    </executions>
   </plugin>
  </plugins>
 </build>
 
       <!-- extra repositories for Vaadin extensions -->
 <repositories>
  <repository>
   <id>vaadin-snapshots</id>
   <url>http://oss.sonatype.org/content/repositories/vaadin-snapshots/</url>
   <releases>
    <enabled>false</enabled>
   </releases>
   <snapshots>
    <enabled>true</enabled>
   </snapshots>
  </repository>
  <repository>
   <id>vaadin-addons</id>
   <url>http://maven.vaadin.com/vaadin-addons</url>
  </repository>
 </repositories>
 
        <!-- repositories for the plugins -->
 <pluginRepositories>
  <pluginRepository>
   <id>codehaus-snapshots</id>
   <url>http://nexus.codehaus.org/snapshots</url>
   <snapshots>
    <enabled>true</enabled>
   </snapshots>
   <releases>
    <enabled>false</enabled>
   </releases>
  </pluginRepository>
  <pluginRepository>
   <id>vaadin-snapshots</id>
   <url>http://oss.sonatype.org/content/repositories/vaadin-snapshots/</url>
   <snapshots>
    <enabled>true</enabled>
   </snapshots>
   <releases>
    <enabled>false</enabled>
   </releases>
  </pluginRepository>
 </pluginRepositories>
 
       <!-- minimal set of dependencies -->
 <dependencies>
  <dependency>
   <groupId>com.vaadin</groupId>
   <artifactId>vaadin</artifactId>
   <version>${vaadin.version}</version>
  </dependency>
  <dependency>
   <groupId>org.vaadin.addons</groupId>
   <artifactId>stepper</artifactId>
   <version>1.1.0</version>
  </dependency>
                <!-- the jetty version we'll use -->
  <dependency>
   <groupId>org.eclipse.jetty.aggregate</groupId>
   <artifactId>jetty-all-server</artifactId>
   <version>8.0.4.v20111024</version>
   <type>jar</type>
   <scope>compile</scope>
   <exclusions>
    <exclusion>
     <artifactId>mail</artifactId>
     <groupId>javax.mail</groupId>
    </exclusion>
   </exclusions>
  </dependency>
 
 
 
               <!-- vaadin custom field addon -->
  <dependency>
   <groupId>org.vaadin.addons</groupId>
   <artifactId>customfield</artifactId>
   <version>0.9.3</version>
  </dependency>
 
               <!-- with cdi utils plugin you can use Weld -->
  <dependency>
   <groupId>org.vaadin.addons</groupId>
   <artifactId>cdi-utils</artifactId>
   <version>0.8.6</version>
  </dependency>
 
               <!-- we'll use this version of Weld -->
  <dependency>
   <groupId>org.jboss.weld.servlet</groupId>
   <artifactId>weld-servlet</artifactId>
   <version>1.1.5.Final</version>
   <type>jar</type>
   <scope>compile</scope>
  </dependency>
 
               <!-- normally following are provided, but not if you run within jetty -->
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
   <type>jar</type>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.2</version>
   <type>jar</type>
   <scope>provided</scope>
  </dependency>
 
  <dependency>
   <artifactId>el-api</artifactId>
   <groupId>javax.el</groupId>
   <version>2.2</version>
   <scope>provided</scope>
  </dependency>
 </dependencies>
 
</project>

Create the java launcher

With this pom we have all the dependencies we need to run Jetty, Vaadin and Weld together. Lets look at the Jetty Launcher.

import javax.naming.InitialContext;
import javax.naming.Reference;
 
import org.eclipse.jetty.plus.jndi.Resource;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
 
/**
 * Simple jetty launcher, which launches the webapplication from the local
 * resources and reuses the projects classpath.
 * 
 * @author jos
 */
public class Launcher {
 
 /** run under root context */
 private static String contextPath = "/";
 /** location where resources should be provided from for VAADIN resources */
 private static String resourceBase = "src/main/webapp";
 /** port to listen on */
 private static int httpPort = 8081;
 
    private static String[] __dftConfigurationClasses =
    {
        "org.eclipse.jetty.webapp.WebInfConfiguration",
        "org.eclipse.jetty.webapp.WebXmlConfiguration",
        "org.eclipse.jetty.webapp.MetaInfConfiguration", 
        "org.eclipse.jetty.webapp.FragmentConfiguration",        
        "org.eclipse.jetty.plus.webapp.EnvConfiguration",
        "org.eclipse.jetty.webapp.JettyWebXmlConfiguration"
    } ;
 
 /**
  * Start the server, and keep waiting.
  */
 public static void main(String[] args) throws Exception {
 
  System.setProperty("java.naming.factory.url","org.eclipse.jetty.jndi");
  System.setProperty("java.naming.factory.initial","org.eclipse.jetty.jndi.InitialContextFactory");
 
  InitialContext ctx = new InitialContext();
  ctx.createSubcontext("java:comp");
 
  Server server = new Server(httpPort);
  WebAppContext webapp = new WebAppContext();
  webapp.setConfigurationClasses(__dftConfigurationClasses);
 
  webapp.setDescriptor("src/main/webapp/WEB-INF/web.xml");
  webapp.setContextPath(contextPath);
  webapp.setResourceBase(resourceBase);
  webapp.setClassLoader(Thread.currentThread().getContextClassLoader());
 
  server.setHandler(webapp);
  server.start();
 
  new Resource("BeanManager", new Reference("javax.enterprise.inject.spi.BeanMnanager",
    "org.jboss.weld.resources.ManagerObjectFactory", null));
 
  server.join();
 }
}

This code will start a Jetty server that uses the web.xml from the project to launch the Vaadin web-app. Take note that we explicitly use the
setConfigurationClasses
operation. This is needed to make sure we have a JNDI context we can use to register the Weld beanmanager in.

Setup the web.xml

Next we’ll look at the web.xml. The one I use in this example is shown next:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 id="WebApp_ID" version="2.5">
 <display-name>Vaadin Web Application</display-name>
 <context-param>
  <description>Vaadin production mode</description>
  <param-name>productionMode</param-name>
  <param-value>false</param-value>
 </context-param>
 <servlet>
  <servlet-name>example</servlet-name>
  <servlet-class>ServletSpecifiedByTheCDIVaadinPlugin</servlet-class>
  <init-param>
   <description>Vaadin application class to start</description>
   <param-name>application</param-name>
   <param-value>VaadinApplicationClassName</param-value>
  </init-param>
  <init-param>
   <param-name>widgetset</param-name>
   <param-value>customwidgetsetnameifyouuseit</param-value>
  </init-param>
 </servlet>
 <servlet-mapping>
  <servlet-name>example</servlet-name>
  <url-pattern>/example/*</url-pattern>
 </servlet-mapping>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
 </welcome-file-list>
 <listener>
  <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
 </listener>
 <resource-env-ref>
  <description>Object factory for the CDI Bean Manager</description>
  <resource-env-ref-name>BeanManager</resource-env-ref-name>
  <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
 </resource-env-ref>
</web-app>

At the bottom of the web.xml you can see the resource-env we define for Weld and the required listener to make sure Weld is started and our beans are injected. You can also see that we specified a different servlet name instead of the normal Vaadin servlet. For the details on this see the CDI plugin page: https://vaadin.com/directory#addon/cdi-utils

The main steps are (taken from that page):

  1. Add empty beans.xml -file (CDI marker file) to your project under WEB-INF dir
  2. Add cdiutils*.jar to your project under WEB-INF/lib
  3. Create your Application class by extending AbstractCdiApplication
  4. Extend AbstractCdiApplicationServlet and annotate it with @WebServlet(urlPatterns = “/*”)
  5. Deploy to JavaEE/Web profile -compatible container (CDI apps can also be run on servlet containers etc. but some further configuration is required)

Add weld placeholder

At this point we have all the dependencies, we created a launcher that can be directly used from Eclipse, and we made sure Weld is loaded on startup. We’ve also configured the CDI plugin for Vaadin. At this point we’re almost done. We only need to add empty beans.xml files in the location we want to be included by the beans discovery of Weld.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

I had to add these to the
src/main/java/META-INF
library and to the
WEB-INF
directory for Weld to pickup all the annotated beans. And that’s it. You can now start the launcher and you should see all kind of Weld and Vaadin logging appearing.

Reference: Embedded Jetty, Vaadin and Weld from our JCG partner Jos Dirksen  at the Smart Java blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


7 − = six



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books