(转)Hello, OSGi, Part 3: Take it to the server side

This story appeared on JavaWorld at
http://www.javaworld.com/javaworld/jw-06-2008/jw-06-osgi3.html

<!-- -->

Hello, OSGi, Part 3: Take it to the server side

OSGi Web application development with Server-Side Equinox

By Sunil Patil, JavaWorld.com, 06/05/08

The first two articles in the Hello, OSGi series have laid the groundwork for understanding how the OSGi service platform works. In this final installment, you'll learn how OSGi's pluggable, component-based development model applies to Web applications. You'll build a bundles-based OSGi application that can be used to serve static resources, servlets, or JSPs. You'll also gain hands-on experience using the Equinox framework to easily leverage OSGi's modularity, versioning, and dynamic services in your Web applications.

The first article is this series, "Hello, OSGi, Part 1: Bundles for beginners ," introduced OSGi development concepts and showed you how to build a simple Hello World application using Equinox, Eclipse's OSGi container implementation. "Hello, OSGi, Part 2: Spring Dynamic Modules " introduced Spring DM, which makes it very easy to build Spring applications that can be deployed in an OSGi container. This final article in the series tackles the question being asked by many developers right now: I like the concept of OSGi, but how do I use it to build Web applications?

As you'll learn in this article, OSGi's development model greatly simplifies the process of writing truly pluggable, modular, and componentized server-side applications. Development exercises will be based (as they have been throughout this series) on the OSGi container reference implementation, Equinox. This time, however, we'll be using Equinox on the server side. We'll begin by discussing the options for deploying your OSGi Web application (in this case Jetty or Tomcat), followed by a short tutorial in setting up your Web application development environment. You will then develop a simple Hello World OSGi Web app and experiment with the different ways to deploy it.

Application deployment using Server-Side Equinox

Equinox rising
Although the Server-Side Equinox project is in the early stages of development, it is quickly growing. There is a move to add support for popular MVC frameworks such as Apache Struts and the Spring Web framework, along with popular object-relational mapping tools such as Hibernate. The Rich Ajax Platform is another Eclipse project that allows you to use Ajax applications with server-side Equinox.

There are two ways to deploy OSGi Web applications using Server-Side Equinox : You can embed a lightweight servlet container such as Jetty inside your OSGi container, or you can embed your OSGi container inside a Web application, and then deploy that application in a servlet container such as Apache Tomcat .

Now, here's the good news: the process of developing an OSGi Web application is the same no matter which approach you choose. Thus, it's best to embed the servlet container inside your OSGi container during the development process; once your application is ready, you can re-package and deploy it if you wish. You'll learn how to embed a servlet container inside an OSGi container in just a moment. First we need to set up your development environment.

Setting up the development environment

For this article's application development exercise you will wrap a lightweight servlet container inside an OSGi bundle (or plug-in , in the Eclipse context). Once this plug-in is installed in your OSGi container, it will listen for HTTP requests. Upon receiving a request it will check to see if any of the installed plug-ins can handle it and, if so, will then forward control to the appropriate plug-in to generate a response. Once the response has been generated, the OSGi container will forward it to the client.

Server-Side Equinox simplifies OSGi-based Web application development by providing a couple of readymade plug-ins that wrap a servlet container inside an OSGi plug-in. Each of the following plug-ins has an embedded servlet container:

  • org.eclipse.equinox.http : A plug-in with a very small footprint, suitable for resource-constrained environments.
  • org.eclipse.equinox.http.jetty : Uses Jetty as the underlying engine for providing Servlet API 2.4 support.

In this section, you will set up your OSGi Web application development environment by embedding the Jetty plug-in inside your Eclipse IDE. (You should start up your IDE now if you haven't already.)

  1. Download jettyhttp-anon.psf onto your desktop.
  2. Right-click Package Explorer and choose Import > Team > Team Project Set. Then click Next .
  3. On the Import a Team Project Set dialog, click Browse and select the jettyhttp-anon.psf file that you downloaded to your desktop, as shown in Figure 1.importpsf_thumb.gifuploading.4e448015.gif转存失败重新上传取消Importing the plug-in.

    Figure 1. Importing the plug-in (click to enlarge)

    Click Finish to start the import process. This step may take a few minutes, depending on your Internet connection, because Eclipse will try to download the necessary project files from the dev.eclipse.org CVS repository.
  4. Once the import is complete, you should see that the following bundles have been imported into your workspace:
    • javax.servlet v2_4
    • org.apache.commons.logging v1_0_4
    • org.eclipse.equinox.http.jetty
    • org.eclipse.equinox.http.registry
    • org.eclipse.equinox.http.servlet
    • org.mortbay.jetty v5_1_11

Your development environment is ready to go. The next step is to execute your bundles in the Equinox OSGi Framework. Revisit the first part of this series if you don't remember how to do that.

<!-- -->

Verify your setup

Once you've executed the bundles in the Equinox OSGi Framework, you will see the OSGi> prompt in the console view. You should be able to see messages generated by the Jetty servlet container in the OSGi console; they'll look like the ones in Listing 1.

Listing 1. Jetty messages on the OSGi console

osgi> May 21, 2008 12:28:06 PM org.mortbay.http.HttpServer doStart
INFO: Version Jetty/5.1.x
May 21, 2008 12:28:07 PM org.mortbay.util.Container start
INFO: Started org.mortbay.jetty.servlet.ServletHandler@f47bf5
May 21, 2008 12:28:07 PM org.mortbay.util.Container start
INFO: Started HttpContext[/,/]
May 21, 2008 12:28:07 PM org.mortbay.http.SocketListener start
INFO: Started SocketListener on 0.0.0.0:80
May 21, 2008 12:28:07 PM org.mortbay.util.Container start
INFO: Started org.mortbay.http.HttpServer@1f6df4c


Wait until you see the message INFO: Started org.mortbay.http.HttpServer@1f6df4c before moving on to the next step.

You can verify that you can access the Jetty server by pointing your browser to http://localhost/. You should see an error page with the messages in Listing 2.

Listing 2. Jetty errors

HTTP ERROR: 404
ProxyServlet: /
RequestURI=/
Powered by Jetty://


You've received a 404 error because Jetty is unable to find the requested resources. The Jetty OSGi plug-in does not have any default index page that it serves when it is unable to find a registered plug-in for handling the current request; it throws this 404 page instead.

Assuming your setup matches mine so far, you're ready for your first exercise in using Server-Side Equinox to develop an OSGi-based Web application.

Developing a HelloWorld OSGi Web application

The application for this exercise will be an OSGi bundle that contains two resources. The first is helloworld.html, which is a static HTML file, and the second is HelloWorldServlet , which is an HttpServlet . It's important to note that the OSGi container has an HttpService OSGi service. Every bundle that wants to handle HTTP requests calls methods on this service to tell the OSGi container what URLs it can handle. There are two ways to register the URLs an OSGi bundle can handle:

  • Programmatic : You first retrieve HttpService from OSGi's service registry, then call methods on it to register the request URLs that the bundle can service.
  • Declarative : You define the request URLs that your bundle can handle in a file called plugin.xml.

We'll walk through both of these techniques, starting with the programmatic registration approach.

Programmatic registration

Follow these steps to programmatically register URLs that your plug-in can handle.

  1. The first thing that you should do is create new OSGi plug-in called com.javaworld.sample.osgi.web.programmatic . (See "Developing a Hello World bundle " in the first article in this series for more about creating OSGi plug-ins in Eclipse.)
  2. Open the MANIFEST.MF file for the com.javaworld.sample.osgi.web.programmatic plug-in and modify it so that it imports the javax.servlet , javax.servlet.http , org.osgi.service.http , and org.osgi.util.tracker packages. After making these changes, your MANIFEST.MF should look like what you see in Listing 3.

    Listing 3. MANIFEST.MF file for a programmatic plug-in

    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: Webapp Plug-in
    Bundle-SymbolicName: com.javaworld.sample.osgi.web.programmatic
    Bundle-Version: 1.0.0
    Bundle-Activator: com.javaworld.sample.osgi.web.webapp.Activator
    Bundle-Vendor: JAVAWORLD
    Bundle-Localization: plugin
    Import-Package: javax.servlet;version="2.4.0",
    javax.servlet.http;version="2.4.0",
    org.osgi.framework;version="1.3.0",
    org.osgi.service.http;version="1.2.0",
    org.osgi.util.tracker;version="1.3.2"
    
    
    
    As you can see, the value of the Import-Package manifest header defines the list of packages that you want to import.
  3. Create the simple helloworld.html file shown in Listing 4 at the root directory for your plug-in. This file displays the message "Hello From helloworld.html."

    Listing 4. helloworld.html

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>HelloWorld OSGi Web</title>
    </head>
    <body>
    <h3>Hello From helloworld.html</h3>
    </body>
    </html>
    
    
    
  4. Next, create the HelloWorldServlet shown in Listing 5.

    Listing 5. HelloWorldServlet

    package com.javaworld.sample.osgi.web.webapp;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class HelloWorldServlet extends HttpServlet{
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html");
            resp.getWriter().println("<h3>Hello from HelloWorldServlet</h3>");
        }
    }
    
    
    
    The HelloWorldServlet class extends HttpServlet and overrides its doGet() method. The only thing the new doGet() method does is write "Hello from HelloWorldServlet " in the output.
  5. Next, you need to execute some code at the startup of the com.javaworld.sample.osgi.web.programmatic plug-in. Activator.java , which will act as a bundle activator for this plug-in, is shown in Listing 6.

    Listing 6. Activator.java

    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import org.osgi.util.tracker.ServiceTracker;
    public class Activator implements BundleActivator {
        ServiceTracker httpServiceTracker;
        public void start(BundleContext context) throws Exception {
            System.out.println("Hello World!!");
            httpServiceTracker = new HttpServiceTracker(context);
            httpServiceTracker.open();
        }
    
        public void stop(BundleContext context) throws Exception {
            System.out.println("Goodbye World!!");
            httpServiceTracker.close();
            httpServiceTracker = null;
        }
    }
    
    
    
    The Activator class extends BundleActivator and implements two methods:
    • start() : The start() method will be called when the OSGi container starts this plug-in. Inside the start() method, you create an object of class HttpServiceTracker ; this is the ServiceTracker class that you'll use to track HttpService . Once you have an object of class HttpService , you call its open() method to start tracking the HttpService .
    • stop() : The OSGi container will call the stop() method when it's time to shut down the plug-in. Inside the stop() method, you call the HttpServiceTracker object's close() method to stop tracking HttpService .
  6. The last step is to create the HttpServiceTracker class, shown in Listing 7.

    Listing 7. HttpServiceTracker

    import org.osgi.framework.BundleContext;
    import org.osgi.framework.ServiceReference;
    import org.osgi.service.http.HttpService;
    import org.osgi.util.tracker.ServiceTracker;
    public class HttpServiceTracker extends ServiceTracker{
        public HttpServiceTracker(BundleContext context) {
            super(context, HttpService.class.getName(), null);
        }
        public Object addingService(ServiceReference reference) {
            HttpService httpService = (HttpService) context.getService(reference);
            try {
                httpService.registerResources("/helloworld.html", "/helloworld.html", null);
                httpService.registerServlet("/helloworld", new HelloWorldServlet(), null, null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return httpService;
        }
        public void removedService(ServiceReference reference, Object service) {
            HttpService httpService = (HttpService) service;
            httpService.unregister("/helloworld.html");
            httpService.unregister("/helloworld");
            super.removedService(reference, service);
        }
    }
    
    
    

<!-- -->

Notes about HttpServiceTracker

HttpService is the OSGi service that allows bundles in the OSGi environment to dynamically register and unregister both resources and servlets in the HttpService 's URI namespace -- in other words, to map request URIs to either a static HTML file or to an HttpServlet . The HttpServiceTracker class is an object of type ServiceTracker , which simplifies the tracking of HttpService . (See "Tracking services " in the first article in this series for more about OSGi's ServiceTracker .)

The HttpServiceTracker class shown in Listing 7 overrides two methods: addingService() and removedService() . They're worth explaining here:

  • addingService() : This is a callback method that will be invoked once HttpService is available. Inside this method, you first call HttpService.registerResources("/helloworld.html", "/helloworld.html", null) to map the helloworld.html file to /helloworld.html. After this, whenever you request http://localhost/helloworld.html, the HttpService will serve helloworld.html to the user. Please note that you needn't map helloworld.html to the /helloworld.html URL; the filename doesn't need to match the address, and you could map it to something like /test.html instead.

    If you want to serve more than one HTML file in your plug-in, then you can create multiple directories. If you wanted an /html directory, you could register it by calling HttpService.registerResources("/html", "/html", null) . If you then wanted to access test.html inside the html folder, the appropriate address would be http://localhost/html/test.html. The registerServlet() method is used for mapping a URL to the HttpServlet class. In the sample code, a call to registerServlet("/helloworld", new HelloWorldServlet(), null, null) is used to map the /helloworld URL to the HelloWorldServlet class. If you want to pass initialization parameters to your HttpServlet , then you can create an java.util.Dictionary object and pass it as third argument to registerServlet() .
  • removedService() : Whenever you override the addingService() method in your ServiceTracker to get a service, you should also override removedService() to unget that service. Inside the removedService() method, you call the unregister() method to unregister both the /helloworld.html and the /helloworld URI. This informs HttpService that com.javaworld.sample.osgi.web.programmatic no longer wishes to serve requests for the given URIs. If you call the unregister() method to unregister the servlet, then the destroy() method of that servlet will be called to give it a chance to clean itself up.

Now the HelloWorld OSGi Web application is ready and you can execute all your bundles in the Equinox OSGi Framework. You should be able to access helloworld.html at http://localhost/helloworld.html, and access the HelloWorld servlet at http://localhost/helloworld.

Declarative registration

As you've probably noted, programmatically registering the request URLs that your OSGi plug-in can handle is no small undertaking. Further, if you ever wanted to change the URL for helloworld.html -- from /helloworld.html to /hello.html, say -- you would have to update HttpServiceTracker.java , re-compile your code, and then deploy it in the OSGi container. Next, we'll take a look at the declarative approach, which is a bit easier.

  1. Create a new plug-in project, com.javaworld.sample.osgi.web.declarative . Choose OSGi Equinox Framework as the target platform.
  2. Edit the MANFIEST.MF file for the com.javaworld.sample.osgi.web.declarative bundle so that it imports the javax.servlet and javax.servlet.http packages and makes org.eclipse.equinox.http.registry a required bundle for this bundle. After making these changes, your MANIFEST.MF file should look like Listing 8.

    Listing 8. MANIFEST.MF for declarative plug-in

    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: Declarative Plug-in
    Bundle-SymbolicName: com.javaworld.sample.osgi.web.declarative;singleton:=true
    Bundle-Version: 1.0.0
    Bundle-Vendor: JAVAWORLD
    Bundle-Localization: plugin
    Import-Package: javax.servlet;version="2.4.0",
     javax.servlet.http;version="2.4.0"
    Require-Bundle: org.eclipse.equinox.http.registry
    
    
    
    The Require-Bundle manifest header contains a list of bundle symbolic names that need to be searched after the imports are searched but before the bundle's classpath is searched. However, only packages that are marked as exported by the required bundles are visible to the requiring bundle.
  3. Copy helloworld.html and HelloWorldServlet.java from the com.javaworld.sample.osgi.web.programmatic bundle to the com.javaworld.sample.osgi.web.declarative bundle.
  4. Finally, change the plugin.xml file for the com.javaworld.sample.osgi.web.declarative bundle to register all the requests it can handle, as shown in Listing 9.

    Listing 9. plugin.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <?eclipse version="3.0"?>
    <plugin>
         <extension-point id="servlets" name="HttpService servlets" schema="schema/servlets.exsd"/>
         <extension-point id="resources" name="HttpService resources" schema="schema/resources.exsd"/>
         <extension-point id="httpcontexts" name="HttpService httpcontexts" schema="schema/httpcontexts.exsd"/>
         <extension
               id="helloServlet"
               point="org.eclipse.equinox.http.registry.servlets">
            <servlet
                  alias="/decl/helloworld"
                  class="com.javaworld.sample.osgi.web.webapp.HelloWorldServlet">
            </servlet>
         </extension>
         <extension
               id="helloResource"
               point="org.eclipse.equinox.http.registry.resources">
            <resource
                  alias="/decl/helloworld.html"
                  base-name="/helloworld.html"
                  />
         </extension>
    </plugin>
    
    
    

Note that plugin.xml has two <extension> elements. The first, with an id attribute whose value is helloServlet , says that the HelloWorldServlet class should be used for handling /decl/helloworld requests. By setting the value of the point attribute to org.eclipse.equinox.http.registry.servlets , you're indicating that this is the servlet class. The second <extension> element, with an id attribute given a value of helloResource , indicates that user requests for /decl/helloworld.html should return the helloworld.html file to the user.

Now your HelloWorld OSGi Web application, rebuilt using a declarative approach, is ready, and you can execute all your bundles in the Equinox OSGi Framework. You can access helloworld.html at http://localhost/decl/helloworld.html and access the HelloWorld servlet at http://localhost/decl/helloworld.

<!-- -->

Executing the OSGi container outside Eclipse

Executing the Equinox OSGi container within the Eclipse IDE is convenient for development. Once your application is ready for deployment, however, you will want to run your OSGi container outside Eclipse. Follow these steps to launch your Equinox OSGi container from the command line.

  1. Download the eclipse-equinox-<buildno>.zip file framework binaries from the Equinox download site. The sample code for this article is tested against version 3.3.
  2. Unzip the download somewhere on your machine. This example will use the directory C:\software.
  3. Create a directory called C:\equinox (or the appropriate equivalent for your operating system) on your machine.
  4. Copy the following JARs from C:\software into C:\equinox:
    • org.eclipse.osgi_<version>.jar
    • javax.servlet v2_4.jar
    • org.apache.commons.logging v1_0_4.jar
    • org.eclipse.equinox.http.jetty.jar
    • org.eclipse.equinox.http.registry.jar
    • org.eclipse.equinox.http.servlet.jar
    • org.mortbay.jetty v5_1_11.jar
    • org.eclipse.equinox.common_<version>.jar
    • org.eclipse.equinox.registry_<version>.jar
    • org.eclipse.osgi.services_<version>.jar
  5. Now, open the command console and change directories to C:\equinox, then execute the following command:

    <!-- --><!-- -->
    java -jar org.eclipse.osgi_<version>.jar -console
    
    
    

    The Equinox OSGi container will start, and you will see the OSGi> prompt.

Install, verify, and execute plug-ins

Note that even though you copied all the plug-in JARs to the C:\equinox directory, none of those plug-ins have been installed into the OSGi container yet. You have to install them one by one. You can install a plug-in in the OSGi container with the following command syntax:

install file:<pathtoplug-injar>


For example if you want to install the javax_servlet v2_4 plug-in, then you will have to execute the following command:

install file:javax.servlet_2.4<version>.jar


Use the install command to install all the necessary plug-ins now.

Once all of your plug-ins are installed, you can verify them by executing the ss command. The OSGi console will display a three-column table listing all the installed plug-ins: the first column displays the ID of the plug-in, the second the state of the plug-in, and the third the name of the bundle.

Notice that all the bundles are in the INSTALLED state except for the org.eclipse.osgi bundle, which is in the ACTIVE state. So, the next thing you need to do is start all of the plug-ins. You can start a plug-in by using the following command:

start <pluginid>


In this case, the ID the javax.servlet v2_4 bundle is 1, so you can start it like so:

start 1


Once all the plug-ins are started, you can verify them by invoking the ss command. The output on your OSGi console should look like what you see in Figure 2.

jettyconsole_thumb.gifuploading.4e448015.gif转存失败重新上传取消Screenshot of the Jetty console.

Figure 2. Jetty console (click to enlarge)

Finally, you can test whether your OSGi Web application is set up properly by pointing your browser to http://localhost/helloworld.html. You should see the message "Hello from helloworld.html".

<!-- -->

Embedding the OSGi container in a servlet container

In this section, you will see another deployment approach for an OSGi Web application, which is to embed an Equinox OSGi container inside a Web application and then deploy that Web application inside a servlet container such as Apache Tomcat. The Equinox Framework provides bridge.war , a template Web application that has an Equinox OSGi container embedded inside it.

The bridge.war application contains the org.eclipse.equinox.servletbridge.BridgeServlet servlet. This servlet takes care of initializing your OSGi container. Whenever it receives a client request, it checks to see if there is an OSGi plug-in that can handle the request; if there is, it forwards control to that plug-in. The following steps will demonstrate how you can use the com.javaworld.sample.osgi.web.programmatic and com.javaworld.sample.osgi.web.declarative plug-ins inside bridge.war.

  1. If you do not already have Apache Tomcat installed, download Apache Tomcat 5.5 and extract it in the operating system folder C:\software (or the appropriate equivalent).
  2. Download bridge.war , then install it in your Apache Tomcat server. Start the bridge.war Web application once you've installed it.
  3. You can test the Bridge Web application by pointing your browser to http://localhost:8080/bridge/sp_test. You should see a message that reads "Servlet delegate registered - org.eclipse.equinox.http.servlet.HttpServiceServlet".
  4. Now, go back to your Eclipse IDE. In the package explorer view, right-click and choose Export > Deployable plug-ins and fragments , then click the Next button. In the Deployable Plug-ins and fragments dialog, enter the values shown in Figure 3.exporttomcatplugin_thumb.gifuploading.4e448015.gif转存失败重新上传取消Exporting plug-ins.

    Figure 3. Exporting plug-ins (click to enlarge)

    When you click Finish , Eclipse will export com.javaworld.sample.osgi.web.declarative.jar and com.javaworld.sample.osgi.web.programmatic.jar to the C:\software\apache-tomcat-5.5.25\webapps\bridge\WEB-INF\eclipse\plugins folder (or its equivalent for your OS). Note that the Bridge Web application copies the contents of C:\software\apache-tomcat-5.5.25\webapps\bridge\WEB-INF\ to the Tomcat work directory and executes it from there. When you access the URL http://localhost:8080/bridge/sp_deploy, the Bridge Web application will copy these new JARs to C:\software\apache-tomcat-5.5.25\work\Catalina\localhost\bridge\eclipse\plugins.
  5. Now restart your Tomcat server. Once Tomcat has restarted, you will see the osgi> prompt in the Tomcat console.
  6. Type ss to display a list of all the OSGi bundles installed in bridge.war. Make sure that the com.javaworld.sample.osgi.web.declarative and com.javaworld.sample.osgi.web.programmatic plug-ins are installed in OSGi container; if they aren't, install them by executing the install file:<jarfilename> command.
  7. Start the com.javaworld.sample.osgi.web.declarative.jar and com.javaworld.sample.osgi.web.programmatic.jar plug-ins by executing the start <bundleid> command at the OSGi prompt.
  8. You should now be able to access helloworld.html by pointing your browser to http://localhost:8080/bridge/helloworld.html.

Explore the application

The Bridge application provides the following URLs that you can use to control the OSGi container from a browser. (These should be appended to http://localhost:8080/bridge/ for this example; this URL could change based on your Tomcat install.)

  • sp_deploy: Copies the contents of the platform to a work or temporary directory
  • sp_undeploy: Removes the copy of Eclipse from the work directory
  • sp_redeploy: Resets the platform (e.g., stops, undeploys, deploys, and starts it)
  • sp_start: Starts a deployed platform
  • sp_stop : Stops the platform
  • sp_test: Provides a sanity check and determines if an OSGi-based servlet is ready to accept requests

Go ahead and play with the application -- and give yourself a pat on the back: you've built your first OSGi Web application!

In conclusion

Although OSGi's roots are in embedded and client-side solutions, many believe it will yield the greatest rewards in server-side development. Server-Side Equinox is one initiative that makes it far easier to apply OSGi's pluggable, component-based development model to Web applications. (SpringSource Application Platform is another, but well beyond the scope of this article.) By following the examples in this article, you've taken your first steps toward developing your own OSGi-based Web applications. You've set up your OSGi Web application development environment in Eclipse; learned about both programmatic and declarative approaches to registering OSGi bundles; and walked through the two different approaches to deploying your OSGi-based Web application: embedding a Jetty servlet container plug-in into Equinox, and embedding Equinox into Tomcat.

In this series you've learned enough to get started with building OSGi-based applications. You've learned about OSGi's development model and built a simple client-server application consisting of two bundles. You've learned how Spring Dynamic Modules makes it easier to build Spring applications in an OSGi container. And you've learned how Server-Side Equinox provides an accessible framework for developing and deploying OSGi applications in a server environment. All of these hands-on exercises have served to get you started with OSGi-based development. In the process, you've likely grappled with the concept of Java modularity, as many developers are doing right now. Hopefully this series has helped you to better understand OSGi and Java modularity and see where it fits into your future Java development projects. Visit the Resources section to learn more about OSGi .

About the author

Sunil Patil is a Java Enterprise/Portlet developer working for Ascendant Technology in San Francisco, California. He is the author of Java Portlets 101 (SourceBeat, April 2007) and has written numerous articles published by O'Reilly Media. Sunil was a member of IBM's WebSphere Portal Server development team for three years and is actively involved in the Pluto community. In addition to being an IBM Certified WebSphere Portal Server Application Developer for both v5.0 and v5.1, he is a Sun Microsystems Certified Java Programmer, a Web component developer, and a business component developer. You can view Sunil's blog at http://jroller.com/page/SunilPatil .

All contents copyright 1995-2008 Java World, Inc. http://www.javaworld.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值