Kirk is a software developer who has filled most roles on the software developer team. He is the author of Java Design: Objects, UML, and Process (Addison-Wesley, 2002) and he contributed to No Fluff Just Stuff 2006 Anthology (Pragmatic Bookshelf, 2006). His most recent book, Java Application Architecture: Modularity Patterns with Examples Using OSGi was published in 2012. Kirk is a DZone Zone Leader and has posted 77 posts at DZone. You can read more from them at their website. View Full User Profile

OSGi and Embedded Jetty

02.03.2009
| 21207 views |
  • submit to reddit

There are two approaches to working with OSGi when developing web applications : embedding OSGi into the application server, or embedding the application server into an OSGi runtime. In this post, I’m going to embed Jetty, the application server, into Felix, the OSGi runtime.

As with my previous posts (Simple OSGi Service, OSGi & Modularity, and OSGi & Spring), I’m trying to use the simplest tools for the job to maximize the experience. That means Ant, Felix, Subversion, a simple text editor, and a terminal window. The code can be found in my Google code repository. Look for the project called HelloWorldWebJSP.

As the project name suggests, not only am I going to embed Jetty in Felix, I’m also going to make sure I can serve JSP pages, which requires a bit of extra trickery. If you need additional details, leave a comment or contact me. Let’s go!

Get Felix

I used Felix 1.4.1 for this exercise. I also tested it with 1.4.0, so either of those two versions should be fine. If you don’t have Felix, get it.

Checkout HelloWorldWebJSP

Next thing to do is to checkout the project from the google code repository. If you want to use the scripts included with the project to startup Felix, you should checkout the project in a directory right alongside Felix. To checkout the project, you’ll need subversion. Then, navigate to the directory containing Felix and do the following:

svn checkout
http://kcode.googlecode.com/svn/trunk/osgi/HelloWorldWebJSP

For convenience, I checked in the Felix bundle cache, so you don’t need to install all the necessary bundles. The environment is already configured. However, if you’d like to setup the environment yourself, you should be able to delete the felix-cache directory, and after starting Felix, go through the steps of installing the necessary bundles. I’d wait to do this until after you’ve had a chance to step through the rest of the example. But it’s up to you. If something gets messed up, you can always start over with a clean checkout. The bundles you’ll need to install can be found in the /web/lib directory. They are

jetty-6.1.7.jar
jetty-util-6.1.7.jar
pax-web-service-0.5.1.jar
osgi.cmpn.jar
pax-web-jsp-0.5.1.jar

Start Felix

Next step is to start Felix. Open a terminal window and navigate to the HelloWorldWebJSP directory. You can use the pre-written scripts (assuming your directory structure is correct), or you can invoke it from command-line like the following, replacing the path to felix with the location of felix:

java -Dfelix.config.properties=file:./config.properties
-jar path to felix/felix-1.4.1/bin/felix.jar

Note that you should use the config.properties included with the project, and not the default Felix config.properties. This is because we need to specify an additional package import to make things work (javax.security.cert). Also, if the HelloWorldWebJSP and Felix directories aren’t side-by-side, you’ll have to change the file paths to the Felix bundles in config.properties.

Try it out

At this point, Jetty should be running inside Felix, and you can navigate to the homepage in your browser. To do this, simply point your browser to http://localhost:8380/. Click hello. Click goodbye. To see the JSP, click the link that serves a JSP.

Explore the Configuration

There isn’t a lot of magic here, but it did take some time to find all the bundles necessary to make it happen, especially to get JSP pages working. All in all, there are a total of 10 bundles, and that includes the four Felix bundles, and the bundle we developed as part of the web application (web.jar in ./web/bin directory). To see a list of all the bundles installed, type the following in the terminal window.

ps

Of particular interest, you’ll see two PAX Web bundles. The OPS4J Pax Web - Service (0.5.1) is the bundle that provides Jetty integration (and actually starts Jetty), while OPS4J Pax Web - Jsp Support (0.5.1) provides JSP compilation via Jasper. Note that most of the examples on the PAX Web website use Maven. Since I didn’t want to use Maven, I installed these bundles manually through the Felix console.

Explore the Code

The key element of the web application is the Activator. This registers the servlet, html pages, and JSP page so that Jetty can serve them up. This is where PAX Web makes the job much easier, because it encapsulates integration with Jasper.

Further Experimentation

There are a few interesting things you can do to experiment a bit further.

First, try setting up the environment yourself. Doing this isn’t that difficult since all of the bundles are included with the project when you checked it out. To do this, close down the existing Felix instance by typing the following in the terminal window.

shutdown

Next, delete the felix-cache directory. This gives you a clean Felix instance with none of the bundles installed. Startup Felix and then, one-by-one, install the appropriate bundles (listed above) from within felix using the install command, as follows:

install file:./path to bundle

Note that if HelloWorldWebJSP and Felix aren’t sitting side-by-side in the file system, you’ll need to change config.properties to point to the location of the Felix bundles. They are found in the bundle directory under felix. Also, don’t forget to install web.jar from the bin directory (you may have to run the build script), since that’s the JAR that contains our application classes. Then, start the bundles using the following command at the Felix command line in the terminal, where the bundle id is the id of the bundle obtained using the ps command.

start bundle id

Second, make a change to the JSP, html, or servlet. There is an Ant build script in the web directory that allows you to recompile. Depending on what you changed or added, you may have to modify the build script to make sure any new files are included in the JAR file created. Once compiled, redeploy the web.jar to Felix from within the console. You shouldn’t need to restart Felix when doing this. Just do the following, where bundle id is the id of the Hello World Web bundle (ie. the web application):

stop bundle id
update bundle id
refresh bundle id
start bundle id

Third, try deploying another servlet after registering it in the Activator. Or create and deploy another JSP. Or Add some images and additional resources. You can modify the build script to include them in the web.jar that’s already been deployed to Felix, or you can create your own JAR file and deploy it alongside web.jar. You can deploy these changes without interrupting what’s already running within Felix, providing a great feel for the flexibility of OSGi and the adaptable environments possible. Whatever you do, this base install should give you a foundation for experimenting with web applications using OSGi.

Soon I hope, I’ll be experimenting with the alternative configuration - embedding OSGi into the application server.

Update: While the example above uses Felix, I have also tested this example with Equinox. You can follow the same steps and the result is the same. Except the default port for the Equinox solution is 8080, and if you want that changed, you’ll have to do it yourself. Also, when using Equinox, replace the ps command with ss to see the bundle listing.

From http://techdistrict.kirkk.com/

Published at DZone with permission of its author, Kirk Knoernschild.

Comments

Peter Huber replied on Tue, 2009/02/03 - 9:58am

Thanks for your post. Looks very easy to include and embedded jetty into OSGi. Or is it just at a first glance it looks so easy?

What about these questions:

1.) How would I want to deal with security? If an bundle deploys a WAR would I map the Realm name in the web.xml to any JAAS-Context? Where do JAAS Contexts come from? Maybe they are provided by other bundles. Or would I choose to have security-interceptors that are deployed through the Deployer-Interface per Web-App (for instance to check a certain custom Client SSL-Certificate Extension...)?

2.) How would I manage Classloading? It's not so easy to simply say jetty.run(), test a simple Test-Web-App and all is done. OSGi is complicated in terms of classloading and most of the servlet-containers have their own way to deal with classloading. And with an embedded jetty I would want to write web-apps that use other bundles services...

3.) How would I manage Servlet-Container Ressources? With Embedded Tomcat you're able to configure HTTP(S)-Connectors programmatically for instance.

BTW: At least Question 2 should trouble you when you do it the other way round - embedding OSGi in Jetty. I'm eager to learn the answer.

Cheers

Peter

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.