<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gridshore &#187; jetty</title>
	<atom:link href="http://www.gridshore.nl/tag/jetty/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gridshore.nl</link>
	<description>A weblog about software engineering, Architecture, Technology an other things we like.</description>
	<lastBuildDate>Tue, 13 Dec 2011 15:36:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>My first steps with Gradle: creating a multi module java web project and running it with jetty.</title>
		<link>http://www.gridshore.nl/2010/09/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/</link>
		<comments>http://www.gridshore.nl/2010/09/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 09:34:06 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[gradle]]></category>
		<category><![CDATA[intellij]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[wrapper]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1077</guid>
		<description><![CDATA[<p>I am a experienced maven user. Sometime I love it, sometimes I hate it. I like it a lot better than ant, but in some situation you would like maven to be easier and more descriptive. The past year there was a lot of fuzz about Gradle. This would give you the best of [...]]]></description>
			<content:encoded><![CDATA[<p>I am a experienced maven user. Sometime I love it, sometimes I hate it. I like it a lot better than ant, but in some situation you would like maven to be easier and more descriptive. The past year there was a lot of fuzz about Gradle. This would give you the best of ant as well as the best of maven, and even more. My first encounter was not very positive, but I kept it in my mind to try it later with a more serious project. This blogpost is about that second more serious try. It will not teach the gradle experts anything, but it will be an easy introduction in to what gradle has to bring for people that are just interested in gradle.</p>
<p><span id="more-1077"></span><br />
<h2>Project structure</h2>
<p>The structure of the project is fairly straightforward, but big enough to demonstrate some of the features that gradle has to offer. It consists of two modules:</p>
<ul>
<li>App</li>
<li>Web-ui</li>
</ul>
<p>We are creating an <a href="http://www.axonframework.org">Axonframework</a> sample, the app contains the command handling and for now the query part as well. The web-ui contains the spring mvc app with the controllers and the authentication using the spring-security framework. For now we make use of an in memory database and we want to be able to start the application without a lot of hassle. Using jetty in this case.</p>
<p>The modules have some shared dependencies for testing and logging. We also want to centralize the definition of some dependency versions.</p>
<h2>Multi module gradle build</h2>
<p>Gradle was build with multi module support from the start. So what do you need to create a multi-module build. We need a settings.gradle that defines the available modules. Next to that we need the main build.gradle as well as the modules build.gradle. Oke you can do without the per module configuration, but in my case that was not the intention. Let us focus first on the main build.gradle.</p>
<h3>Main build.gradle</h3>
<p>The main build.gradle is used to define some of the versions of the dependencies. The following code block shows the complete script.</p>
<pre class="brush: groovy; title: ; notranslate">
axonVersion = &quot;0.6&quot;
springVersion = &quot;3.0.4.RELEASE&quot;
springSecurityVersion = &quot;3.0.3.RELEASE&quot;
slf4jVersion = &quot;1.5.8&quot;
sourceCompatibility = 1.6

subprojects {
    apply plugin: 'java'

    configurations {
        all*.exclude group: &quot;commons-logging&quot;, module: &quot;commons-logging&quot;
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        compile &quot;org.slf4j:jcl-over-slf4j:$slf4jVersion&quot;,
                &quot;org.slf4j:jul-to-slf4j:$slf4jVersion&quot;
        runtime &quot;org.slf4j:slf4j-log4j12:$slf4jVersion&quot;

        compile(&quot;log4j:log4j:1.2.15&quot;) {
            exclude group: &quot;com.sun.jdmk&quot;, module: &quot;jmxtools&quot;
            exclude group: &quot;com.sun.jmx&quot;, module: &quot;jmxri&quot;
            exclude group: &quot;javax.mail&quot;, module: &quot;mail&quot;
            exclude group: &quot;javax.jms&quot;, module: &quot;jms&quot;
        }

        testCompile 'junit:junit:4.7'
    }

    group = 'org.axonframework.samples.trader'
    version = '1.0-SNAPSHOT'
    sourceCompatibility = 1.6
}
</pre>
<p>As you can see, the script starts with the definition of the versions of dependencies. Than the script contains information for all the subprojects. You see we define the java plugin for all subprojects. Next to that the repositories and the dependencies are defined. Have a look at the mechanism to exclude transitive dependencies. For log4j we explicitly exclude some transitive dependencies. We also use a mechanism to exclude commons-logging from the complete build. Using the configurations hook we exclude it for all phases.</p>
<p>Finally we also define the group, version and source compatibility in the build configuration.</p>
<p>That is it, the following code block shows the required settings.gradle and after that we move on with the build.gradle of the app and web-ui subprojects.</p>
<pre class="brush: groovy; title: ; notranslate">
include &quot;app&quot;, &quot;web-ui&quot;
</pre>
<h3>Subprojects build.gradle</h3>
<p>The build.gradle for the app project is almost to easy to show. But I promised I would, so here we go:</p>
<pre class="brush: groovy; title: ; notranslate">
dependencies {
    compile &quot;org.axonframework:axon-core:$axonVersion&quot;

    compile &quot;org.hibernate:hibernate-entitymanager:3.4.0.GA&quot;,
            &quot;c3p0:c3p0:0.9.1&quot;,
            &quot;org.hsqldb:hsqldb:1.8.0.10&quot;

    compile &quot;org.springframework:spring-tx:$springVersion&quot;,
            &quot;org.springframework:spring-orm:$springVersion&quot;,
            &quot;org.springframework:spring-jdbc:$springVersion&quot;

    compile &quot;com.thoughtworks.xstream:xstream:1.3.1&quot;

    testCompile &quot;org.axonframework:axon-test:$axonVersion&quot;
}
</pre>
<p>The configuration only contains dependencies. I would like to be able to simplify the dependencies on the spring projects. Would be nice if I could group them somehow, like:</p>
<p>compile group:&#8221;org.springframework&#8221;, version:&#8221;$springVersion&#8221;, module:["spring-webmvc", "spring-aop"]</p>
<p>But the build config looks pretty clean. Now we move on to the creation of the war for the web project.</p>
<pre class="brush: groovy; title: ; notranslate">
apply plugin: 'war'

dependencies {
    compile project(':app')

    compile &quot;org.springframework:spring-webmvc:$springVersion&quot;,
            &quot;org.springframework:spring-aop:$springVersion&quot;

    compile &quot;org.springframework.security:spring-security-web:$springSecurityVersion&quot;,
            &quot;org.springframework.security:spring-security-config:$springSecurityVersion&quot;

    compile &quot;javax.validation:validation-api:1.0.0.GA&quot;,
            &quot;org.hibernate:hibernate-validator:4.0.2.GA&quot;

    runtime &quot;javax.servlet:jstl:1.1.2&quot;,
            &quot;taglibs:standard:1.1.2&quot;,
            &quot;opensymphony:sitemesh:2.4.2&quot;

    providedCompile &quot;javax.servlet:servlet-api:2.5&quot;
}
</pre>
<p>Again a pretty straightforward config. We use more types of dependencies. We now introduce the providedCompile. Jars that need not be included in the war should have this config for the dependency. Do mark that we have an apply plugin line at the top for creating the war. Finally have a look at the mechanism to show we have a dependency on another module of the project. We use the <strong>compile project (&#8216;:app&#8217;) </strong>to make the war include this created jar as well.</p>
<h2>Running with Jetty</h2>
<p>You think the jetty plugin for maven is easy, well check this out. We have to change only one word in the web project config. Look for the first line with <strong>apply plugin</strong>. Change the word war into jetty and you are done. Now you can run jetty with the following command from the root of the project:</p>
<p><em>gradle :web-ui:jettyRun</em></p>
<h2>The wrapper</h2>
<p>People that have gradle installed on their system can easily build the project and run jetty. But some people might not have gradle installed. You can help them to make it very easy. Gradle comes with a wrapper that downloads gradle and makes sure it&#8217;s on your path etc. The only thing the user needs to do is the following in the root of the project:</p>
<p><em>gradlew build</em></p>
<p>Pay attention to the &#8216;w&#8217; at the end of the gradle command. Next step is to start jetty. This is done with the same command as before with one change, the w at the end. To help your users with this, you need to do one thing. You have to add the following task to the main build.gradle. Than run gradle wrapper, checkin the generated files into your source control system. The gradlew script can be used by the people to build the project. Good stuff or not?</p>
<pre class="brush: groovy; title: ; notranslate">
task wrapper(type: Wrapper) {
    gradleVersion = '0.9-rc-1'
    jarPath = 'wrapper'
}
</pre>
<h2>Intellij integration</h2>
<p>Oke, this kinda hurts to say, but intellij support is not at a level that you would like to. At least that is what I could find out. You can easily run gradle builds from intellij. That is all nice. But I am really missing the dependency management part. Would be great to have support like for maven to setup your complete project. Wouldn&#8217;t it be great to have the import from external model feature for gradle as well? For now let us all vote for this issue, it might help:</p>
<p><a href="http://youtrack.jetbrains.net/issue/IDEA-57755">﻿http://youtrack.jetbrains.net/issue/IDEA-57755</a></p>
<p>I hope someone from jetbrains reeds this at thinks I am important enough to start creating this plugin <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Performance</h2>
<p>The last remarks I want to make are about the performance of gradle. At the moment I have this build for maven as well as gradle and maven2 is twice as fast as gradle. I know work is being done on this. Gradle 0.9.1 will support a new feature that at least will speed up building the project of you have to do it a lot during the day. It will do something with a running gradle service that you can call each time you start a build. There are some items on the mailing list about this specific topic if you are interested.</p>
<p><a href="http://gradle.markmail.org/thread/xbqna6lowvsmm4ve">http://gradle.markmail.org/thread/xbqna6lowvsmm4ve</a></p>
<h2>Concluding</h2>
<p>Well that was part one of the experiment. I have not touched everything by a long run. Still I found out I like the configuration of gradle a lot better than I like maven. It is a lot cleaner and let&#8217;s you focus on the things that are important. I prefer groovy for this kind of work over xml. Still gradle has some ground to cover. For starters, tool integration. We must have something that makes working with intellij a lot better. In the future I will have a better look at plugins for release management and other stuff that I think is necessary for a good project build.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F09%2F08%2Fmy-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty%2F&amp;title=My%20first%20steps%20with%20Gradle%3A%20creating%20a%20multi%20module%20java%20web%20project%20and%20running%20it%20with%20jetty.&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/09/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Creating a jetty based OSGi HttpService for apache felix</title>
		<link>http://www.gridshore.nl/2008/02/29/creating-a-jetty-based-osgi-httpservice-for-apache-felix/</link>
		<comments>http://www.gridshore.nl/2008/02/29/creating-a-jetty-based-osgi-httpservice-for-apache-felix/#comments</comments>
		<pubDate>Fri, 29 Feb 2008 21:02:08 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[felix]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[OSGi]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2008/02/29/creating-a-jetty-based-osgi-httpservice-for-apache-felix/</guid>
		<description><![CDATA[<p>OSGi has a service spec called http.service (see Service Compendium document of the OSGi Alliance). Felix has an implementation for it that is based around jetty 4.x. Since we are at jetty 6.1.7 at the moment I thought about trying to create an implementation of my own. Not that it is really necessary, you [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/logo1.png" alt="logo.png" border="0" width="165" height="63" align="left" />OSGi has a service spec called http.service (see Service Compendium document of the OSGi Alliance). Felix has an implementation for it that is based around jetty 4.x. Since we are at jetty 6.1.7 at the moment I thought about trying to create an implementation of my own. Not that it is really necessary, you can expose resources without complying to the spec (<a href="http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/">see my other post</a>).</p>
<p> But the spec is there for a reason, so let&#8217;s try to adhere to it first. The specification is up to the following two interfaces and one exception.</p>
<ul>
<li>HttpContext &#8211; Enables bundles to use provided information about a servlet or resource during registration.</li>
<li>HttpService &#8211; Enables other bundles to dynamically register sevlets or resources into the Http Service URI namespace.</li>
<li>NamespaceException &#8211; Thrown when a problem arises during registration of a servlet or resource into the Http Service UIR namespace.</li>
</ul>
<p>At first I tried to create my own implementation for these interfaces. It did not look to hard, but in the end I found the following patch which made my life a lot easier.<br /><a href="https://issues.apache.org/jira/secure/attachment/12372787/FELIX-55_jetty6.patch">jetty6 patch</a></p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/jetty-logo.gif" alt="jetty_logo.gif" border="0" width="269" height="112" align="right" />To be able to understand the implementation of an Http Service using jetty, you should understand the basics with respect to Jetty. In a forthcoming post I&#8217;ll talk more about these details. Within this post I&#8217;ll concentrate on the using of the service. I do need to make a few remarks. What if you do not want to apply the patch, change the pom, etc. Well you can download the one I have created from here : <a href="http://code.google.com/p/gridshore/source/browse/trunk/FelixTryout/RunnerApp/bundle/org.apache.felix.http.jetty-0.9.0-GRIDSHORE.jar">org.apache.felix.http.jetty-0.9.0-GRIDSHORE.jar</a>. Another thing I would like to stress is the current state of the bundle. There are a lot of TODO&#8217;d in there. It looks like security is not implemented as it should. There is a completely different implementation at the <a href="http://wiki.ops4j.org/confluence/display/ops4j/Pax+Web">ops4j website</a>. One disadvantage is the level of control, need to look into that thing again. It is much more complicated, uses other bundles of the pax project. It does look interesting, but for me it is not easy enough. Another implementation is available at the <a href="http://incubator.apache.org/sling/site/index.html">sling website</a>. But again a lot to graps before you can start. So for now I have chosen to continue with the slightly limited implementation, adhere to the spec and my bundles should work with the others as well.</p>
<p>Read more to learn about the sample using http.service and maven to build the bundle.</p>
<p><span id="more-66"></span></p>
<h2>The sample</h2>
<p>The goal was to play around with servlets and resources. I want to get a better idea about what OSGi can do. So I used the runner I introduced in my previous post (<a href="http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/">starting-with-osgi-using-apache-felix-step-1</a>). Of course there are some other bundles and there is an extra property to configure the jetty intance:</p>
<pre>
<strong>configMap.put("org.osgi.service.http.port","9081"); // set the port to listen to for jetty</strong>
configMap.put(AutoActivator.AUTO_START_PROP + ".1",
    "file:" + BUNDLE_ROOT + "training-service/1.0-SNAPSHOT/training-service-1.0-SNAPSHOT.jar " +
    "file:" + BUNDLE_ROOT + "http-servlets/1.0-SNAPSHOT/http-servlets-1.0-SNAPSHOT.jar " +
    "file:" + JETTY_ROOT + "jetty/6.1.7/jetty-6.1.7.jar " +
    "file:" + JETTY_ROOT + "jetty-util/6.1.7/jetty-util-6.1.7.jar " +
    "file:" + JETTY_ROOT + "servlet-api-2.5/6.1.7/servlet-api-2.5-6.1.7.jar " +
    "file:bundle/org.osgi.compendium-1.0.0.jar " +
    "file:bundle/slf4j-api-1.4.3.jar " +
    "file:bundle/slf4j-simple-1.4.3.jar " +
<strong>    "file:bundle/org.apache.felix.http.jetty-0.9.0-GRIDSHORE.jar " + // use the created patched http.service</strong>
    "file:bundle/org.apache.felix.shell-1.0.0.jar " +
    "file:bundle/org.apache.felix.shell.tui-1.0.0.jar ");
</pre>
<p>The training service is a very easy service with one method returning a list of trainings. The more interesting bundle is the http-servlets bundle. This bundle contains the servlet that uses the training-service and some static resources like html pages, style sheets, etc. Let&#8217;s start with a look at the internal structure of the bundle. Please remember that we use the <a href="http://cwiki.apache.org/FELIX/bundle-plugin-for-maven-bnd.html">maven-bundle-plugin</a> plugin. Therefore we adhere to basic maven project structure. The java files are in the src/main/java folder. The static resources are in the src/main/resources folder. The plugin than creates the right MANIFEST.MF file.</p>
<pre>
Manifest-Version: 1.0
Built-By: jettro
Created-By: Apache Maven Bundle Plugin
Bundle-Activator: nl.gridshore.samples.bundles.httpservlets.impl.Activ
 ator
Import-Package: javax.servlet;version="2.5",javax.servlet.http;version
 ="2.5",nl.gridshore.samples.bundles.trainingservice.api,org.osgi.fram
 ework;version="1.3",org.osgi.service.http;version="1.2",org.slf4j;ver
 sion="1.4"
Bnd-LastModified: 1204315796232
Bundle-Version: 1.0.0.SNAPSHOT
Bundle-Name: http-servlets
Build-Jdk: 1.5.0_13
<strong>Private-Package: htmls,htmls.css,htmls.images,nl.gridshore.samples.bun
 dles.httpservlets.impl</strong>
Bundle-ManifestVersion: 2
Bundle-SymbolicName: http-servlets
Tool: Bnd-0.0.227
</pre>
<p>Take good notice of the Private-Packge, here the directories are listed that are in the resources folder. So by default these resources are private. We need the http service to expose these resources. The next step is to have a look at the Activator of the http-servlets bundle. Let&#8217;s step through the separate methods that are important.</p>
<pre>
<strong>public void start(BundleContext bundleContext) throws Exception</strong> {
    this.bundleContext = bundleContext;
    doRegister();
    synchronized (this) {
        bundleContext.addServiceListener(this,
                "(|(objectClass=" + TrainingService.class.getName() + ")" +
                "(objectClass=" + HttpService.class.getName() + "))");
    }
}
</pre>
<p>Two important things happen in the start method, we first try to register the servlet (more on that later). After that we add a service listener that listens to events related to the TrainingService class and the HttpService class. This means that if one of these instances are started, stopped or updated we are notified. This notification is important to unregister the servlet if the training service disappears. Of course it is also important to register the servlet if the http service becomes available. Let&#8217;s move on to the register methods.</p>
<pre>
<strong>private void register() throws InvalidSyntaxException, ServletException, NamespaceException</strong> {
    ServiceReference[] trainingReferences = bundleContext.getServiceReferences(TrainingService.class.getName(), null);
    TrainingService trainingService = null;
    if (trainingReferences != null) {
        trainingService = (TrainingService) bundleContext.getService(trainingReferences[0]);
    } else {
        logger.info("No training service available");
    }

    ServiceReference[] httpReferences = bundleContext.getServiceReferences(HttpService.class.getName(), null);
    HttpService httpService = null;
    if (httpReferences != null) {
        httpService = (HttpService) bundleContext.getService(httpReferences[0]);
    } else {
        logger.info("No http service available");
    }

    if ((trainingService != null) &#038;&#038; (httpService != null)) {
        logger.info("training servlet will be registered.");
        httpService.<strong>registerServlet</strong>("/trainings", new TrainingsServlet(trainingService), null, null);
        httpService.<strong>registerResources</strong>("/","/htmls",null);
    } else {
        logger.info("No servlet to register, problem with training service or http service");
    }
}

<strong>private void doRegister()</strong> {
    try {
        register();
    } catch (InvalidSyntaxException e) {
        logger.error("Could not register servlet based on an Invalid Syntax",e);
    } catch (ServletException e) {
        logger.error("Could not register servlet based on an Servlet exception",e);
    } catch (NamespaceException e) {
        logger.error("Could not register servlet based on an Namespace exception",e);
    }
}
</pre>
<p>Concentrate on the register method. First we check for available training service references. If a reference is available, we get the actual service. Then the same is done for the http service. If both of them are availble, we use the http service to register a new servlet that accepts the training service to obtain trainings from. As you can see we first register the servlet, the two null parameters represent the servlet config parameters and the special HttpContext. By providing null a default context is created. We also register a folder with static resources. The first string is the path or alias where the user should access the resources. The second string is the path to the resources within the bundle. The final parameter is the same as for the servlet, the HttpContext, again null so the default value. There are to more methods I want to show, first for unregistering and second for handling change events.</p>
<pre>
<strong>private void unregister() throws InvalidSyntaxException</strong> {
    logger.info("Unregister a servlet");
    ServiceReference[] httpReferences = bundleContext.getServiceReferences(HttpService.class.getName(), null);
    if (httpReferences != null) {
        HttpService httpService = (HttpService) bundleContext.getService(httpReferences[0]);
        httpService.unregister("/trainings");
        httpService.unregister("/");
    }
}

<strong>private void doUnregister()</strong> {
    try {
        unregister();
    } catch (InvalidSyntaxException e) {
        logger.error("Could not unregister servlet",e);
    }
}

<strong>public void serviceChanged(ServiceEvent event)</strong> {
    String objectClass = ((String[]) event.getServiceReference().getProperty("objectClass"))[0];
    logger.info("Service change event occurred for : {}", objectClass );
    if (event.getType() == ServiceEvent.REGISTERED) {
        doRegister();
    } else if (event.getType() == ServiceEvent.UNREGISTERING) {
        doUnregister();
    } else if (event.getType() == ServiceEvent.MODIFIED) {
        doUnregister();
        doRegister();
    }
}
</pre>
<p>The unregister function is pretty obvious. So let&#8217;s have a better look at the serviceChanged method. I took the easy way out here. Just check the type of event. In case of a new registration, register the servlet and resources. In case of an unregistration, we unregister the servlet and in case of a change we just do an unregister and a register. This works oke for my situation. Using the following screendumps I&#8217;ll show what happens when we start all bundles, stop de training-service bundle, and in the end start it again. First the output from the console, then the screens.</p>
<pre>
Welcome to Felix.
=================

1 [FelixStartLevel] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - No http service available
1 [FelixStartLevel] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - No servlet to register, problem with training service or http service
org.mortbay.log:Logging to org.mortbay.log via org.apache.felix.http.jetty.LogServiceLog
org.mortbay.log:started org.mortbay.jetty.servlet.HashSessionIdManager@2b2057
org.mortbay.log:started org.mortbay.jetty.servlet.HashSessionManager@85c0de
org.mortbay.log:starting OsgiServletHandler@395aaf
org.mortbay.log:started OsgiServletHandler@395aaf
org.mortbay.log:starting SessionHandler@70b819
org.mortbay.log:started SessionHandler@70b819
org.mortbay.log:starting org.mortbay.jetty.servlet.Context@1b50a1{/,null}
org.mortbay.log:starting ErrorHandler@46ad8b
org.mortbay.log:started ErrorHandler@46ad8b
org.mortbay.log:started org.mortbay.jetty.servlet.Context@1b50a1{/,null}
org.mortbay.log:jetty-6.1.x
org.mortbay.log:started Realm[OSGi HTTP Service Realm]==[]
org.mortbay.log:started org.mortbay.thread.BoundedThreadPool@ebaf12
org.mortbay.log:starting Server@32e910
org.mortbay.log:started org.mortbay.jetty.nio.SelectChannelConnector$1@19549e
org.mortbay.log:Started SelectChannelConnector@0.0.0.0:9081
org.mortbay.log:started SelectChannelConnector@0.0.0.0:9081
org.mortbay.log:started Server@32e910
191 [FelixStartLevel] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - Service change event occurred for : org.osgi.service.http.HttpService
191 [FelixStartLevel] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - training servlet will be registered.
org.mortbay.log:started /trainings/*
org.mortbay.log:started /htmls
-> stop 1
36499 [Felix Shell TUI] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - Service change event occurred for : nl.gridshore.samples.bundles.trainingservice.api.TrainingService
36499 [Felix Shell TUI] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - Unregister a servlet
-> start 1
org.mortbay.log:started /trainings/*
org.mortbay.log:started /htmls
43500 [Felix Shell TUI] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - Service change event occurred for : nl.gridshore.samples.bundles.trainingservice.api.TrainingService
43500 [Felix Shell TUI] INFO nl.gridshore.samples.bundles.httpservlets.impl.Activator - training servlet will be registered.
->
</pre>
<p>Try to follow the steps, you can see the bundle containing the servlet starts before the training-service of the http-service. Then the change event is received and the servlet is registered. Next we stop the training service and the servlet is unregistered. And the servlet is registered again after a start of the training-service bundle (number 1).</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/felix-osgi-training-step1.jpg" alt="felix-osgi-training-step1.jpg" border="0" width="536" height="355"/>This is the initial screen. Notice the url, this is a static resource called index.html that loads a stylesheet and an image from the bundle.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/felix-osgi-training-step2.jpg" alt="felix-osgi-training-step2.jpg" border="0" width="536" height="356"/>Now we have stopped the training service bundle, which has resulted in a unregister of the servlet, therefore the page is not available anymore.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/felix-osgi-training-step3.jpg" alt="felix-osgi-training-step3.jpg" border="0" width="537" height="355"/>I have started the training service bundle again, so the servlet gets registered and now I have clicked the link for trainings. As you can see we have two very interesting trainings.</p>
<p>So that is about it, it turned out to become a pretty long post. Hope you liked it. Please leave a comment if you did, and of course if you did not. All your ideas and suggestions are welcome. If you want to have a look at the source, you can find everyting in the FelixTryout project at my <a href="http://code.google.com/p/gridshore/source/browse">google code website</a>. </p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2008%2F02%2F29%2Fcreating-a-jetty-based-osgi-httpservice-for-apache-felix%2F&amp;title=Creating%20a%20jetty%20based%20OSGi%20HttpService%20for%20apache%20felix&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2008/02/29/creating-a-jetty-based-osgi-httpservice-for-apache-felix/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Embedding Jetty in OSGi (osgi felix sample step 3)</title>
		<link>http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/</link>
		<comments>http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/#comments</comments>
		<pubDate>Fri, 15 Feb 2008 15:41:03 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[felix]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[servlet]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/</guid>
		<description><![CDATA[<p>This is my third post in the osgi basics series. The topic of today is embedding a servlet container within an osgi container. Of course I am continuing to use felix and now I start using jetty from mortbay. Starting from version 6.1.x, jetty is packaged as a bundle in itself. It is very [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/logo1.png" alt="logo.png" border="0" width="165" height="63" align="left" />This is my third post in the osgi basics series. The topic of today is embedding a servlet container within an osgi container. Of course I am continuing to use felix and now I start using <a href="http://www.mortbay.org/">jetty from mortbay</a>. Starting from version 6.1.x, jetty is packaged as a bundle in itself. It is very easy to start a jetty instance within a felix container. Some steps we are going to take in this tutorial:
</p>
<p></p>
<ol>
<li>initialize the container with the required bundles.</li>
<li>Start up the jetty instance with a servlet listening to the default path</li>
<li>Add a servlet that uses a service and takes care of the lifecycle.</li>
</ol>
<h3>Setting up the context</h3>
<p>I already talked in my previous post about starting felix and adding bundles to the context. The following block of code shows the bundles that we install after initialization. I install the training service and the sample client. The sample client contains the code to start jetty and install the servlet. Then there are three jars you need to install before you are able to use the jetty instance: jetty, jetty-util and servlet api. Beware, if you want to use jsp&#8217;s as well you need to add more jars. Check the following website: <a href="http://docs.codehaus.org/display/JETTY/Embedding+Jetty">embedding jetty</a>.
</p>
<pre>
configMap.put(AutoActivator.AUTO_START_PROP + ".1",
    "file:" + BUNDLE_ROOT + "training-service/1.0-SNAPSHOT/training-service-1.0-SNAPSHOT.jar " +
    "file:" + BUNDLE_ROOT + "example-client/1.0-SNAPSHOT/example-client-1.0-SNAPSHOT.jar " +
    "file:" + JETTY_ROOT + "jetty/6.1.7/jetty-6.1.7.jar " +
    "file:" + JETTY_ROOT + "jetty-util/6.1.7/jetty-util-6.1.7.jar " +
    "file:" + JETTY_ROOT + "servlet-api-2.5/6.1.7/servlet-api-2.5-6.1.7.jar " +
    "file:bundle/slf4j-api-1.4.3.jar " +
    "file:bundle/slf4j-simple-1.4.3.jar " +
    "file:bundle/org.apache.felix.shell-1.0.0.jar " +
    "file:bundle/org.apache.felix.shell.tui-1.0.0.jar ");
</pre>
<h3>Start the jetty instance</h3>
<p><img src="http://www.gridshore.nl/wp-content/uploads/jetty-logo.gif" alt="jetty_logo.gif" border="0" width="269" height="112" align="right" /><br />
Starting a jetty instance is very easy. The following code shows you how to create a jetty instance while listening to a certain port. Next step is to initialize the context using a context url. In our case we use the root, so you should go to http://localhost:8091/ to have a look at the application. Second step is to add a HelloServlet instance listening to everything in the root path &#8220;/*&#8221;. The final step before actually starting the jetty instance might be a little less obvious. Here we define an empty servlet returning a non available message. The next step will show why. This servlet will be listening to the url &#8220;/trainings&#8221;
</p>
<pre>
Server server = new Server(9081);
Context root = new Context(server, JETTY_CONTEXT_PATH, Context.SESSIONS);
root.addServlet(new ServletHolder(new HelloServlet()), MAIN_SERVLET_PATH_SPEC);
servletHolder = new ServletHolder();
servletHolder.setServlet(new NonAvailableServlet());
root.addServlet(servletHolder, TRAININGS_SERVLET_PATH_SPEC);
server.start();
</pre>
<h3>Add training servlet if service is available</h3>
<p>We start by registering a service listener that is listening to events related to objects with a name TrainingService : </p>
<pre>
bundleContext.addServiceListener(this,
    "(&#038;(objectClass=" + TrainingService.class.getName() + "))");
</pre>
<p>You can add other properties to this query, but for now we do not need that. Since the activator class implements the <strong>ServiceListener</strong> interface we need to implement the following method. That method receives events that comply to the provided filter.
</p>
<pre>
public void serviceChanged(ServiceEvent event) {
    if (event.getType() == ServiceEvent.REGISTERED) {
        logger.info("Training service is registered");
        servletHolder.setServlet(new TrainingsServlet(
            (TrainingService)bundleContext.getService(event.getServiceReference())));
    } else if (event.getType() == ServiceEvent.UNREGISTERING) {
        logger.info("Training service is unregistered");
        servletHolder.setServlet(new NonAvailableServlet());
    } else if (event.getType() == ServiceEvent.MODIFIED) {
        logger.info("Training service is modified");
        servletHolder.setServlet(new TrainingsServlet(
            (TrainingService)bundleContext.getService(event.getServiceReference())));
    }
}
</pre>
<p>
As you can see from the code there are three type of events we support. We get an event when the service is registered, unregistered or changed. This gives us the opportunity to register the servlet that uses the training service if the service is available and to register the empty servlet when the training service is not available.
</p>
<p>
You can find the complete source code <a href="http://code.google.com/p/gridshore/source/browse">here</a> (look for the FelixTryout project). and the specific Activator containing the jetty stuff <a href="http://code.google.com/p/gridshore/source/browse/trunk/FelixTryout/example-client/src/main/java/nl/gridshore/samples/bundles/exampleclient/impl/Activator.java">here</a>.
</p>
<p>
That is about it, hope you liked the article. Use the comments if you have questions. If you would like to read the previous articles, click on them here or click on felix in the tag cloud.<br />
<a href="http://www.gridshore.nl/2008/02/10/starting-with-osgi-using-apache-felix-step-1/">step 1</a> &#8211; <a href="http://www.gridshore.nl/2008/02/13/using-maven-to-create-an-osgi-bundle-osgi-felix-sample-step-2/">step 2</a></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2008%2F02%2F15%2Fembedding-jetty-in-osgi-osgi-felix-sample-step-3%2F&amp;title=Embedding%20Jetty%20in%20OSGi%20%28osgi%20felix%20sample%20step%203%29&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2008/02/15/embedding-jetty-in-osgi-osgi-felix-sample-step-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

