Spring recently released their DM server. The DM server is an application server that is tightly integrated with OSGi and allows deployment of Spring web apps as OSGi bundles, giving them all the features of OSGi and those of Spring. Awesome idea, so I wanted to play with it. But for people like me, who have never worked with Spring before, getting started on developing for the DM server is a bit tedious. There is little documentation for newbies, most tutorials that I found require previous knowledge of Spring and mostly cover porting an old Spring app to the DM server. So I decided to write down my experiences getting started with it in the form of a tutorial on getting started for people who know about OSGi but have never used Spring. If you know what OSGi is and how to write OSGi bundles and have general knowledge about programming and using programming tools you should be well prepared for this tutorial. Afterwards you should be well prepared to write your own apps that use Spring’s features and OSGi, though some more reading on Spring is probably a good idea.
This tutorial will cover the setup of the environment as well as the development of a Hello World application. I will include all required steps to start from scratch, with no previous tools installed. The setup of Eclipse, the Spring DM Server and the Spring tools for Eclipse will be covered here. You should have a basic understanding of Eclipse if you want to understand what happens in this part, though understanding it is not too important when you just want to develop the apps. If you know your way around Eclipse and have worked with it before you should be done in a couple of minutes with the setup since there isn’t really that much hard stuff here.
After the setup I will write a hello world app to run on the DM server. This serves as a guideline that describes how to go about developing such applications. This can be used to cover the very basic getting-started steps for Spring development, because I don’t expect any previous knowledge. Here you will learn how to use the tools that were installed in part one. There were some things here that I found to be non-obvious and that stopped me for some time, so this part covers the stuff that got me to think I should write this tutorial.
So let’s get started with installing the tools. Here’s a list of what you will need:
- The Spring DM server
- Eclipse
- The Spring Eclipse plugin
The first thing to get is the Spring DM server. There’s a free community version on the Spring homepage. Simply unzip this to any directory, just remember the directory as you will need it again shortly. I unzipped it to /Developer/Spring-DM-Server/springsource-dm-server-1.0.1.RELEASE
The next thing to install, if you haven’t done so before, is Eclipse. Eclipse is, especially when you want to develop OSGi bundles, the best Java IDE I know of. Since you’ll develop a web application, get the IDE for Java EE developers, because it includes all necessary plugins for web development. Eclipse doesn’t need to be installed, you can simply unzip it to any folder. When you start Eclipse, you will be asked for a workspace location. This is where all files of your projects will be stored. Use any folder you want, though it should be empty to make your life easier.
Next up: The Spring Eclipse plugin. Open Eclipse and go to Help -> Software Updates… Click on “Available Software” and then on the “Add Site…” button on the right. Add Spring’s update site, which is http://dist.springframework.org/release/IDE and from there install “Spring IDE Core” and “Spring IDE OSGi Extensions”. You will also need the dm server Eclipse plugin. Add another update site, http://static.springsource.com/projects/sts-dm-server/update, and install the SpringSource Tool Suite dm Server Tools.
The final step is to setup the Spring DM server as an application server that Eclipse knows about. Go to Eclipse’s preferences and there to Server -> Runtime Environments. Click the Add…-button on the right and select SpringSource -> SpringSource dm Server (Runtime) v1.0. Make sure to check the “Create a new local server” checkbox at the bottom. After clicking Next>, you will be asked to enter a name for the server (choose any name) and then you need to choose the installation directory of the server. Select the directory you installed the server to, so in my case I entered /Developer/Spring-DM-Server/springsource-dm-server-1.0.1.RELEASE. Click Finish.
As a final step for the setup of the environment we will try to start the DM server from Eclipse. Go the the “Servers” tab on the bottom of Eclipse (if you still have the default layout), or open it via Window -> Show View -> Other… -> Server -> Servers. Select your server and click on the “start” button (white triangle on green background) or right-click and select start. When the state has changed to “Started”, open a web browser and open http://localhost:8080. The server’s start page should come up. You can open the admin console by clicking on the link and entering the default credentials (Username: admin, password: springsource). You will then see a list of the deployed applications which, for now, is almost empty.
This concludes the setup part of this tutorial. In the next part we will put all of this to use in a simple hello world app.
Now, with a working development environment, we will develop a hello world app. The app will consist of two bundles: One OSGi bundle which will publish a service and a second bundle which will contain a web app that uses this service to display the greeting on a web site.
Though in many cases it will probably a good idea to put the service interface into a different bundle from the implementation, we will not do so for this tutorial. To create the bundle, we first need to create a new project. In Eclipse, go to File -> New -> Project… -> SpringSource dm Server and create a new Bundle Project. Call it HelloProvider. On the Bundle Content page, make sure the Module Type is “None”. When the project has been created, create a new interface that defines the service’s interface. In my case it is called com.loetzer.helloprovider.HelloProvider. This interface has a single method:
Next, create an implementation class; I called this com.loetzer.helloprovider.impl.HelloProviderImpl. It implements the interface we have just defined; the method is implemented as follows:
1 2 3
| public String getGreeting () {
return "Hello World!";
} |
In regular OSGi, we would now create a BundleActivator which would instatiate the service implementation and register it upon startup. However, since we use Spring’s DM server, we don’t have to – Spring takes care of this. You still can, though, and it will work fine if you do – which is nice for porting old applications onto the DM server.
In order to use Spring’s scheme of registering OSGi services, create a new folder “spring” inside the META-INF directory of your bundle. Inside that folder, create a file “osgi-context.xml”. In this file, we will define a bean and have that bean registered as an OSGi service. Put in the following into that file:
1 2 3 4 5 6 7 8 9 10
| < ?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">
<osgi:service interface="com.loetzer.helloprovider.HelloProvider">
<bean class="com.loetzer.helloprovider.impl.HelloProviderImpl" />
</osgi:service>
</beans> |
You can see that we have registered the implementation class as a service with the service interface that we developed before. Upon starting this bundle, the DM server will now instatiate the HelloProviderImpl class and register it as a HelloProvider server in the OSGi service registry so that other bundles can use the service.
In order to allow them to do it, we need to export the interface. Open the bundle’s manifest and go to the Runtime tab. Add the com.loetzer.helloprovider package to the exported packages. Make sure not to export the implementation package.
Now we need to develop the web application that uses this service to display a greeting. Again create a new Bundle Project and call it GreeterUI. This time select “Web” as the Module Type. On the bundle properties screen, put “greeter” into the textbox for the context path. This is the path on the application server that will later host your project.
When the project has been created, right-click it and open its properties. Here, go to Project References and select the HelloProvider project. Then open the project’s manifest (META-INF -> MANIFEST.MF) and add the following packages to the imported packages on the Dependencies screen:
1 2 3 4 5 6 7 8
| com.loetzer.helloprovider
javax.servlet.http
org.apache.commons.logging
org.apache.taglibs.standard.lang.jstl
org.apache.taglibs.standard.tag.rt.core
org.apache.taglibs.standard.tei
org.apache.taglibs.standard.tlv
org.osgi.framework |
Next, import the org.springframework.spring library in the bottom right corner of the screen.
The next step is to create the controller for the applications. Create a class called com.loetzer.greeterui.GreetingsController extending import org.springframework.web.servlet.mvc.AbstractController. Give it the following body:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| private HelloProvider greetingProvider ;
public void setGreetingProvider (HelloProvider greetingProvider ) {
this. greetingProvider = greetingProvider ;
this. logger. debug("Greeting provider set: " + greetingProvider. getClass(). getName());
}
@Override
protected ModelAndView handleRequestInternal (HttpServletRequest arg0, HttpServletResponse arg1 ) throws Exception {
ModelAndView mv = new ModelAndView ();
mv. addObject("greeting", this. greetingProvider. getGreeting());
mv. setViewName("greetings");
return mv ;
} |
The setter will be used by the DM server to set the reference to the HelloProvider service which we have registerd in the OSGi service registry before. The handleRequestInternal will be called by spring when the user opens the associated web page. In this case the logic is very simple and gets the greeting from the greetingProvider. The view name will be resolved to a JSP which gets rendered and set back to the client.
In order to have Spring wire the services together, i.e. look up the HelloProvider and give a reference to it to the GreetingsController, you need to tell Spring what services the bundle requires. To do this, create a bundle-context-osgi.xml file in META-INF/spring. Here is the content for that file:
1 2 3 4 5 6 7
| < ?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">
<osgi:reference id="greeter" interface="com.loetzer.helloprovider.HelloProvider"/>
</beans> |
This file will link the ID greeter to a reference to a registered HelloProvider. The next step is now to give the reference to the GreetingsController. In order to do this, create a file called greeter-servlet.xml in the same directory. The content for the file is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| < ?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="greetingController" class="com.loetzer.greeterui.GreetingsController">
<property name="greetingProvider" ref="greeter"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/index.htm">greetingController</prop>
</props>
</property>
</bean>
</beans> |
The first bean is the Controller. Spring will now look for a setter for the property called greetingProvider (using standard Java naming conventions, i.e. it will look for setGreetingProvider) and take the reference with the id “greeter” and pass it to that setter method. The other two beans are standard spring beans. The view resolver is used to – who would have thought – resolve views. It is responsible for mapping the “mv.setViewName(“greetings”);” call to a JSP. In this case, it will simply append /WEB-INF/jsp/ and .jsp to the passed string and look for a file with that name in the bundle. The URL mapping maps URLs to controllers, in this case all requests for /index.htm will be handled by our GreetingController.
As a last step, we need to create the JSP that will be rendered to display the greeting. Create a directory MODULE-INF/WEB-INF/jsp and put a file called greetings.jsp into it. Here is the content for that JSP:
1 2 3 4 5 6 7 8 9 10
| < %@ page contentType="text/html;charset=UTF-8" language="java" %>
< %@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Hello! </title>
</head>
<body>
<c:out value="${greeting}" />
</body>
</html> |
When the controller gets a request, the following call registers the greeting in the ModelAndView object:
1
| mv.addObject("greeting", this.greetingProvider.getGreeting()); |
The ModelAndView object can now receive whatever was registered under the name “greeting”, in our case
1
| <c:out value="${greeting}" /> |
simply prints the string representation.
This concludes the development and all that’s left is the deployment. For this, open the “Servers” tab in Eclipse and right-click your dm Server. Select “Add and Remove Projects…” and add both the GreeterUI and the HelloProvider to the configured projects. When you start the server now, you should see log entries similar to these:
[2008-12-26 20:23:39.604] nnection(4)-192.168.78.1 Deployment of ‘HelloProvider’ version ‘1’ completed.
[2008-12-26 20:23:40.644] nnection(4)-192.168.78.1 Creating web application ‘/greeter’.
[2008-12-26 20:23:40.735] async-delivery-thread-1 Starting web application ‘/greeter’.
[2008-12-26 20:23:41.130] nnection(4)-192.168.78.1 Deployment of ‘GreeterUI’ version ‘1’ completed.
When you have seen these, open your browser and point it to http://localhost:8080/greeter/index.htm and you will be greeter with whatever you wrote into your HelloProvider.
This concludes the tutorial. You now have a fully functional development environment for spring web applications and have a basic understanding of how to develop for Spring’s DM server and use it’s OSGi integration. You have seen how to register services, how to get references to registered services and how to use Spring MVC. With this, you are well prepared to go explore on your own and write some fun applications. If you have any feedback on this tutorial, a suggestion for improving it or have found a mistake I have made, please write a comment on this post. I would love to hear from you! Until then, have fun with Spring and OSGi!