OSGI mit Felix

Hier ein kleines Beispiel zu OSGI mit Apache Felix

Man benötigt:

Apache Felix
BND-Tool
oder, ganz neu, für noch komfortableres Arbeiten das BND-Tool als Eclipse-Plugin

bndtools
Eclipse

Einstellungen für Eclipse:
Man legt eine neue User Library mit Namen Felix an: Window->Preferences->Java->Build path->User Libraries->New

Die felix.jar wird mit der neuen User Library verlinkt: Window->Preferences->Java->Build path->User Libraries->Add JARs

Anschließend legt man ein neues Java-Projekt in Eclipse an und fügen die neue User Library hinzu.
Danach kopiert man die beiden Ordner bundle und conf direkt in das Projektverzeichnis des erstellten Projekts.

Felix starten:
Man richtet unter Eclipse eine neue Laufzeitkonfiguration für Felixein: Run->Run Configurations->Java Applaction->New

In der Console kann man sich jetzt mit “ps” die installierten Bundles oder mit “help” die verfügbaren Kommandos ansehen.

BND-Tool:
Die Jar des BND-Tools wird in das Projektverzeichnis kopiert und außerdem in das Dropin-Verzeichnis von Eclipse. Danach muss man Eclipse neu starten.

Das eigentliche Programm:

Man erzeugt ein Service-Interface sowie die Implementierung dazu:

package de.pmannel.osgi;

public interface HelloService
{
	void sayHello();
}
package de.pmannel.osgi;

public class HelloServiceImpl implements HelloService
{

	@Override
	public void sayHello()
	{
		System.out.println("Hello Felix! Greetings from Service");

	}
}

Außerdem erzeugt man einen Activator, der beim Starten/Stoppen des Bundles ausgeführt wird.

package de.pmannel.osgi;

import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;

public class HelloFelixActivator implements BundleActivator
{
	private HelloService helloService;
	private ServiceTracker serviceTracker;

	@Override
	public void start(BundleContext context) throws Exception
	{
		Dictionary props = new Hashtable();
		props.put("objectName", "de.pmannel.osgi<:type=HelloService");
		context.registerService(HelloService.class.getName(), new HelloServiceImpl(), props);
		serviceTracker = new ServiceTracker(context, HelloService.class.getName(), null);
		serviceTracker.open();
		helloService = (HelloService)serviceTracker.getService();

		helloService.sayHello();
	}

	@Override
	public void stop(BundleContext context) throws Exception
	{
		serviceTracker.close();
		serviceTracker = null;
		helloService = null;
		System.out.println("Goodby Felix..");

	}
}

Nun erzeugt man im Projektverzeichnis eine .bnd-Datei, in der man bestimmte Parameter für die spätere Manifest-datei des OSGI-Bundles setzt.

# felix.bnd
Private-Package: de.pmannel.osgi
Bundle-Activator: de.pmannel.osgi.HelloFelixActivator
Bundle-SymbolicName: HelloFelix
Bundle-Version: 1.1.0

Mit einem Rechtsklick auf der Datei ->Make Bundle erzeugt man automatisch die Manifest-Datei.

Manifest-Version: 1.0
Private-Package: de.pmannel.osgi
Bundle-Version: 1.1.0
Tool: Bnd-0.0.384
Bnd-LastModified: 1273493680531
Bundle-Name: HelloFelix
Bundle-ManifestVersion: 2
Created-By: 1.6.0_07 (Sun Microsystems Inc.)
Bundle-Activator: de.pmannel.osgi.HelloFelixActivator
Import-Package: org.osgi.framework,org.osgi.util.tracker
Bundle-SymbolicName: HelloFelix

Das Bundle wird in Felix über die Console installiert:

install file:HelloFelix.jar

Anschließend wird das Bundle gestartet, indem man sich über “ps” die ID des Bundles holt:

start 9

Das war’s!

Man kann jetzt auch im laufenden Betrieb zb.: die sayhello()-Methode ändern und dann mit

update 9

eine neue Ausgabe erzeugen….




RSS-Feeds mit Rome & Spring 2.5

Problem: Wie erzeuge ich einen RSS-Feed mit Rome und Spring MVC

Lösung:

Man lädt sich Rome und Spring Modules herunter und packt beide Jars in seinen Classpath.

Danach erzeugt man einen RSSView:

public class RSSView extends AbstractRssView
{
	private static final String[] FEED_TYPE = {"rss_0.90","rss_0.91","rss_0.92","rss_0.93","rss_0.94","rss_1.0","rss_2.0","atom_0.3"};	

	private static final DateFormat DATE_PARSER = new SimpleDateFormat("yyyy-MM-dd");

	private String description;

	/**
	 * Generates the Feed.
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected void buildFeed(Map model, HttpServletRequest request, HttpServletResponse response, SyndFeed feed)
	{
		feed.setFeedType(FEED_TYPE[6]);

		feed.setTitle("Peters Feeds");
		feed.setLink(getBaseUrl());
		feed.setDescription(description);

		SyndImage image 	= new SyndImageImpl();
		image.setLink(getBaseUrl());
		image.setUrl("URLTOIMAGE");
		image.setDescription(description);
		image.setTitle("Peter");
		feed.setImage(image);

		List entries = new ArrayList();
		SyndEntry entry;

		entry = new SyndEntryImpl();
		entry.setTitle("Rome v1.0");
		entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01");
		entry.setPublishedDate(DATE_PARSER.parse("2004-06-08"));
		description = new SyndContentImpl();
		description.setType("text/plain");
		description.setValue("Initial release of Rome");
		entry.setDescription(description);
		entries.add(entry);

		entry = new SyndEntryImpl();
		entry.setTitle("Rome v2.0");
		entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome02");
		entry.setPublishedDate(DATE_PARSER.parse("2004-06-16"));
		description = new SyndContentImpl();
		description.setType("text/plain");
		description.setValue("Bug fixes, minor API changes and some new features");
		entry.setDescription(description);
		entries.add(entry);

		feed.setEntries(entries);

	}

	public void setDescription(String description)
	{
		this.description = description;
	}

}

Anschließend erzeugt man den dazugehörigen Controller:

public class RssFeedController implements Controller
{

	@Override
	public ModelAndView handleRequest(HttpServletRequest arg0,
			HttpServletResponse arg1) throws Exception
	{

		return  new ModelAndView("rSSView");
	}
}

Als Letztes verdrahtet man alles in seiner dispatcher.xml:

...
RssFeedController

	

	

	
	
...

… ab Version 3.0 des Springframework kann man das ganz einfach so machen.