Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Embedded Jetty and Spring: The Lightweight Antidote for Java EE Complexity : Page 3

Enterprise Java development does not need to be heavyweight and Ant-driven; with embedded Jetty and Spring, it can be lean, mean, fast, and—above all—productive.


WEBINAR: On-Demand

Unleash Your DevOps Strategy by Synchronizing Application and Database Changes REGISTER >

Setting Up the Application

To configure Jetty to serve an application at a particular context path, you will set up a separate application project in Eclipse.

Begin by adding a new Java project to your workspace, called simply MyApp. Besides the default src folder for Java classes, also add a new folder called web, which will contain all the web content (e.g., JSPs, web config files, and so on). Because this is a regular Java project and not an Eclipse WTP dynamic web project, no special plugins are required. This makes the whole approach easy to reproduce in other IDEs such as NetBeans or IntelliJ.

Under the web folder, create the WEB-INF folder. In it, you will add the following standard web.xml file, which registers Spring:

<web-app> <context-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/beans.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> </web-app>

Next, add a Spring beans.xml file in the WEB-INF folder. To avoid excessive XML configuration, configure it to use annotations for business components:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:annotation-config /> <context:component-scan base-package="com.devx.myapp" /> </beans>

Obviously, replace the base package com.devx.myapp with one that is specific to your application.

Last but not least, go back to your server project and explicitly configure your web application:

Server jetty = new Server(); String[] configFiles = {"etc/jetty.xml"}; for(String configFile : configFiles) { XmlConfiguration configuration = new XmlConfiguration(new File(configFile).toURI().toURL()); configuration.configure(jetty); } //configure your web application WebAppContext appContext = new WebAppContext(); appContext.setContextPath("/myapp"); File rd = new File("./"); File warPath = new File(rd,"../MyApp/web"); appContext.setWar(warPath.getAbsolutePath()); HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[]{ appContext, new DefaultHandler()}); jetty.setHandler(handlers); jetty.start();

The section starting with WebAppContext configures MyApp under the /myapp context. When you run the main server class, you should see output like this in the console:

2009-06-21 07:47:13.585::INFO: Logging to STDERR via org.mortbay.log.StdErrLog 2009-06-21 07:47:13.672::INFO: Statistics on = false for SelectChannelConnector @ 2009-06-21 07:47:13.756::INFO: jetty-6.1.3 2009-06-21 07:47:13.962:/myapp:INFO: Initializing Spring root WebApplicationContext 21-Jun-2009 7:47:13 AM org.springframework.web.context.ContextLoader initWebApplicationContext INFO: Root WebApplicationContext: initialization started 21-Jun-2009 7:47:14 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.web.context.support.XmlWebApplicationContext@1950198:
display name [Root WebApplicationContext]; startup date [Sun Jun 21 07:47:13 EDT 2009]; root of context hierarchy 21-Jun-2009 7:47:14 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/beans.xml] 21-Jun-2009 7:47:14 AM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory INFO: Bean factory for application context [org.springframework.web.context.support.XmlWebApplicationContext@1950198]:
org.springframework.beans.factory.support.DefaultListableBeanFactory@5d391d 21-Jun-2009 7:47:14 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5d391d:
defining beans [org.springframework.context.annotation.internalCommonAnnotationProcessor,
org.springframework.context.annotation.internalRequiredAnnotationProcessor]; root of factory hierarchy 21-Jun-2009 7:47:14 AM org.springframework.web.context.ContextLoader initWebApplicationContext INFO: Root WebApplicationContext: initialization completed in 384 ms 2009-06-21 07:47:14.419::INFO: Started SelectChannelConnector @

Even with a configured, Spring-enabled web application now being served, start-up time is still extremely fast, as this line indicates:

INFO: Root WebApplicationContext: initialization completed in 384 ms

With this in place, your daily productivity will not suffer from the constant overhead of re-deploying your WAR and EARs when your web or business logic changes. Also, unlike the often buggy hot-deploy features of Eclipse WTP, this approach works 100 percent of the time.

Bear in mind one small gotcha: You must remember to add the MainServer project as a dependency to your application (see Figure 3) so that it can access all the Spring classes it exports. When configured, your application project should look like the one in Figure 4.

Figure 3. Adding a Dependency on the Server Project: Add the MainServer project as a dependency to your application.
Figure 4. A Configured Web Application Project: When configured, your application project should look like this.

Annotation-Enabled Business Components

To avoid the traditional verbose Spring XML configuration, the example used the new annotation-based approach instead, meaning that to create a Spring-managed component you simply need to annotate it with @Component, for example:

import org.springframework.stereotype.Component; @Component public class MyComponent { }

In order to use the component in a service using dependency injection, all you need is the @Autowired annotation:

@Service public class MyService { @Autowired(required=true) private MyComponent myComponent; }

The only entries in the Spring beans.xml file are those that usually require external configuration anyway (e.g., JDBC entries for datasources), but you can configure all the business logic using annotations, which is much easier.

However, as stated previously, Spring's benefits go far beyond its dependency injection features. Its extremely useful template classes (e.g., JdbcTemplate) are what really give you that extra boost in day-to-day productivity. If you're new to Spring, you certainly should explore them.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date