Jump to: navigation, search

Jetty/Tutorial/Jetty-OSGi SDK



Introduction

Jetty-OSGi is a packaging of jetty where jetty is run as an OSGi bundle. It supports the deployment of traditional J2EE web-applications and also web-bundles where the web application is contained in a bundle.

This tutorial introduces the development and testing of web-bundles in PDE.

Configure a Target Platform and run a simple Test Unit with PDE

We will provision a new Target Platform and develop a simple bundle that executes a Testunit. A Target Platform defines the OSGi environment in which your bundles are compiled and debugged.

Target Platform with JUnit Support

Launch Eclipse-SDK-3.6. Define a new Target Platform "EclipseRT-Tutorial" Open the Preferences and choose the node "Plugins-Development/Target Platform" Click on "Add..." and choose the option "Nothing:" start with an empty Target Platform"

Create a new OSGi Project
  • Name the Target Platform "EclipseRT Tutorial"
  • Click on Next and choose "Add..." then "Select Software Site"
Name it
  • Select the "Helios" download site as the source of the features to install in the Target Platform
  • Look for the category "Eclipse RT Target Platform" and select the PDE JUnit Support feature. Click on Finish.

(Currently use: http://download.eclipse.org/jetty/7.1.3.v20100526/repository/)

Select the JUnit Support Feature


  • Select the new Target Platform as the active platform.
Activate the Target Platform

OSGi bundle with a test unit

  • Create a new OSGI Bundle project: "New Project.../Plugin-Project"
  • Name the project "org.eclipse.jetty.rt.example.test"
  • Choose a pure OSGi bundle.
Activate the Target Platform


  • Generate a bundle activator.
  • Click on Finish.
Activate the Target Platform


  • Open the META-INF/MANIFEST.MF editor and on the tab "Overview, select the checkbox "Activate this plugin when one of its classes is loaded"
Lazy Activation policy


  • Open the META-INF/MANIFEST.MF editor and choose the tab "dependencies"
  • In the "Imported packages" section, click on "Add..." and select the package "org.junit"
Lazy Activation policy


  • Create a new class ActivatorTest
  • Make a method that will be run by JUnit to test that the activator is started:
package org.eclipse.jetty.rt.example.test;
 
import org.junit.Assert;
import org.junit.Test;
 
/**
 * Tests that the activator was indeed loaded
 */
public class ActivatorTest {
	@Test public void testActivator() throws Exception {
		Assert.assertNotNull("The activator was not started", Activator.getContext());
	}	
}
  • Right-click on the Activator-Test Class and choose "Run as .../JUnit Plugin Test"
  • The test should pass
Lazy Activation policy

Archive for this project

Setup Jetty and a first Web-bundle

Setup Jetty Target Component

  • Choose Preferences and Edit the "EclipseRT Tutorial" target platform definition
  • Select the Helios site and choose "Edit"
  • Add the "Jetty Target Component" feature to the list of features provisioned
Lazy Activation policy

Optional: install Jetty tooling

The Jetty tooling feature contains 2 templates for Pluin projects that make it easy to get started developing web-bundles.

Create a first web-bundle

Create a new OSGi bundle. Make sure it is not an eclipse plugin. Name it "org.eclipse.jetty.example.webapp"

If you have installed the Jetty tooling feature, click next until you can choose a template. Everything will be generated.

If you are creating the bundle with the jetty template you will need to add to the MANIFEST.MF:

  • The import-package:
    Import-Package: javax.servlet;version="2.5.0",
    
javax.servlet.http;version="2.5.0"
  • A new line that defines the context path for the web-application:
    Web-ContextPath: /test

It should look like this:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Webapp
Bundle-SymbolicName: org.eclipse.jetty.example.webapp
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.jetty.example.webapp.Activator
Import-Package: org.osgi.framework;version="1.3.0",
 javax.servlet;version="2.5.0",
 javax.servlet.http;version="2.5.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Web-ContextPath: /test
  • Now create a new file WEB-INF/web.xml at the root of the project.

And define a simple servlet-mapping:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
   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/web-app_2_5.xsd"
   version="2.5">
 
   <display-name>Hello Webapp</display-name>
   <servlet>
        <servlet-name>theservlet</servlet-name>
        <servlet-class>org.eclipse.jetty.example.webapp.Servlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>theservlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
 
</web-app>
  • Create a org.eclipse.jetty.example.webapp.Servlet class
package org.eclipse.jetty.example.webapp;
 
import java.io.IOException;
 
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/** A simple servlet */
public class Servlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
 
	public void init(ServletConfig config) throws ServletException {
		System.err.println("Initializing the servlet");;
	}
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		System.err.println("DO GET!");
		resp.getWriter().write("Howdy!");
	}
}

Launch configuration

slf4j/logback are bundled by default. Some extra steps are necessary to prevent all logs from appearing on the console.

Create a new file logback.xml at the root of the web-bundle project and paste this configuration:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%-4relative [%thread] %-5level %class - %msg%n</pattern>
		</encoder>
	</appender>
	<root>
		<level value="error" />
		<appender-ref ref="STDOUT" />
	</root>
</configuration>

Now Create a new OSGi launch configuration: Select the menu "Run/Run Configuration..." and choose the node "OSGi". Create a new configuration; choose the "Arguments" tab and add to the VM arguments area:

 -Dlogback.configurationFile=${workspace_loc:org.eclipse.jetty.example.webapp}/logback.xml
Lazy Activation policy


Now click on "Run".

Open a browser and navigate to http://localhost:8080/test It will display "Howdy"

Notes: where is the jetty server configured

jetty-osgi looks for ${jetty.home}/etc/jetty.xml for its configuration. When it can't find it defaults to the one embedded inside itself. For example: /rt-tutorial-workspace/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool/plugins/org.eclipse.jetty.osgi.boot_7.1.3.v20100526/jettyhome

It is possible to set the system property jetty.home and point it to a different setup or to edit the jetty.xml file located there.

Automated test for the servlet

Add to the test bundle the following imports:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Test
Bundle-SymbolicName: org.eclipse.jetty.rt.example.test
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.jetty.rt.example.test.Activator
Import-Package: org.eclipse.jetty,
 org.eclipse.jetty.client,
 org.eclipse.jetty.http,
 org.eclipse.jetty.util,
 org.eclipse.jetty.util.component,
 org.junit;version="4.8.1",
 org.osgi.framework;version="1.3.0"
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy


Create the ServletTest class:

package org.eclipse.jetty.rt.example.test;
 
import org.eclipse.jetty.client.*;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.http.HttpBuffers;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.HttpStatus;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkUtil;
 
/**
 * 
 */
public class ServletTest {
 
	private HttpClient _client;
 
    protected void startClient() throws Exception {
	    _client = new HttpClient();
	    _client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
	    _client.start();
    }
 
	protected void stopClient() throws Exception {
		if (_client != null) {
			_client.stop();
			_client = null;
		}
	}
 
	/**
	 * Make sure the webapp is started before this test is run.
	 * Could be done via the Launch Configuration
	 */
	@Before public void setup() {
		Bundle testBundle = FrameworkUtil.getBundle(ServletTest.class);
		for (Bundle b : testBundle.getBundleContext().getBundles()) {
			if (b.getSymbolicName().equals("org.eclipse.jetty.osgi.boot")
					|| b.getSymbolicName().equals("org.eclipse.jetty.example.webapp")) {
				try {
					System.err.println("Found " + b.getSymbolicName());
					b.start();
				} catch (BundleException e) {
					Assert.fail("Unable to start the necessary bundles");
				}
			}
		}
		//TODO: put in a lifecycle listener
		synchronized (Thread.currentThread()) {
			try {
				Thread.currentThread().wait(1000);
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
	}
 
	@Test public void testGet() throws Exception {
		startClient();
 
		ContentExchange getExchange = new ContentExchange();
		getExchange.setURL("http://localhost:8080/test/");
		getExchange.setMethod(HttpMethods.GET);
 
		_client.send(getExchange);
		int state = getExchange.waitForDone();
 
		String content = "";
		int responseStatus = getExchange.getResponseStatus();
		if (responseStatus == HttpStatus.OK_200) {
			content = getExchange.getResponseContent();
		}
		System.err.println("Got the content: " + content);
		stopClient();
 
		Assert.assertEquals(HttpStatus.OK_200, responseStatus);
		Assert.assertEquals("Howdy!", content);
	}
 
}


EclipseRT Jetty Starter Kit

Additional Resources

Jetty-OSGi, RFC66, PDE We are working on migrating all building an update site and executing the build on eclipse with the rest of the jetty@eclipse project. In the mean time, the latest code is here: [http://github.com/intalio/hightide-on-osgi

Retrieved from "http://wiki.eclipse.org/index.php?title=Jetty/Tutorial/Jetty-OSGi_SDK&oldid=204888"