Showing posts with label RCP. Show all posts
Showing posts with label RCP. Show all posts

Thursday, December 24, 2009

Override Eclipse Key Binding

A few weeks back is was struggling with an Eclipse key binding problem. I had to override the CTRL+S binding. Since I had my own "org.eclipse.ui.bindings" extension, I keept on getting conflict messages (no wonder).
So I thought I'll make a post as personal reference and maybe it helps some other developer.

This is what I did in ApplicationActionBarAdvisor.makeActions().

IBindingService bindingService = (IBindingService) window.getService(IBindingService.class);
bindingService.addBindingManagerListener(new IBindingManagerListener() {
@Override
public void bindingManagerChanged(BindingManagerEvent event) {
BindingManager manager = event.getManager();
for (Binding binding : manager.getBindings()) {
ParameterizedCommand command = binding.getParameterizedCommand();
if (command != null && ActionFactory.SAVE.getCommandId().equals(command.getId())) {
manager.removeBinding(binding);
}
}
}
});

IWorkbenchAction saveDocumentAction = ActionFactory.SAVE.create(window);
saveDocumentAction.setId("saveDocument");
saveDocumentAction.setActionDefinitionId(SAVE_DOCUMENT_COMMAND);

register(saveDocumentAction);

Monday, March 16, 2009

Use EMF and Riena

EMF, Teneo and Riena are great Eclipse projects. Use EMF to model your business objects and generate the Java code, use Teneo to persist through Hibernate and Riena to transfer your objects to the Eclipse RCP client and back. Isn't that sexy!

Nevertheless As I tried to use that setup, I ran into a few problems.
  • Transferring a 0...* reference causes an Exception: java.util.ArrayList ([...]) cannot be assigned to org.eclipse.emf.common.util.EList
  • Registered Adapters (EObjectImpl:eAdapters) can not be passed over the wire and causes Exception
  • In some cases I had trouble transferring the EObjectImpl:eProperties attribute
The way I figured to solve those issues, is the AbstractSerializerFactory.

Through extension points I can register my own EObjectSerializerFactory which uses my Deserialiser/Serializer for all EObjects.
My classes need to be in a "common" plug-in which is active on the server and client.
Both the EObjectSerializer and EObjectDeserializer are based on the JavaSerializer/JavaDeserializer provided by Caucho.

Basiclly all I do, is serializing the content of the EStructuralFeatures instead of serializing the Java fields.
So this way eFlags, eAdapters, eContainer, eContainerFeatureID and eProperties (EObjectImpl fields) are not passed over the wire.
I my case this works since I don't need the eContainer on the server.

Here the classes, maybe they help you to use the same combination:
EObjectSerializerFactory.java


/*******************************************************************************
* $URL: $
*
* Copyright (c) 2007 henzler informatik gmbh, CH-4106 Therwil
*******************************************************************************/
package com.softmodeler.service.communication;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;

import com.caucho.hessian.io.AbstractSerializerFactory;
import com.caucho.hessian.io.Deserializer;
import com.caucho.hessian.io.HessianProtocolException;
import com.caucho.hessian.io.Serializer;

/**
* EObjectSerializerFactory, provides a serializer and deserializer for EObjects
*
* @see EObjectSerializer
* @see EObjectDeserializer
* @author created by Author: fdo, last update by $Author: fdo $
* @version $Revision: 1236 $, $Date: 2009-03-03 22:51:32 +0100 (Di, 03 Mrz 2009) $
*/
public class EObjectSerializerFactory extends AbstractSerializerFactory {
/** class name suffix for implemented EClassifiers */
private static final String CLASS_SUFFIX = "Impl"; //$NON-NLS-1$
/** packages that should be excluded from reading */
private static final String[] EXCLUDE_PACKAGE_NS_URI = new String[] { "http://www.eclipse.org/emf/2002/Ecore" }; //$NON-NLS-1$

/** internal cache of all EClassifiers existing in the system, ClassifierName=>EClassifier */
private Map allClassifiers = null;

/**
* Returns a map with all relevant EClassifiers
*
* @return map ClassifierName=>EClassifier
*/
private Map getAllClassifiers() {
if (allClassifiers == null) {
allClassifiers = new HashMap();

// iterate the EPackages and place all classifiers in the allClassifiers map
for (Object value : EPackage.Registry.INSTANCE.values()) {
if (value instanceof EPackage) {
EPackage ePackage = (EPackage) value;
if (isValidPackage(ePackage.getNsURI())) {
for (EClassifier eClassifier : ePackage.getEClassifiers()) {
allClassifiers.put(eClassifier.getName(), eClassifier);
}
}
}
}
}
return allClassifiers;
}

/**
* Returns true if the package is valid (not in the EXCLUDE_PACKAGE_NS_URI list)
*
* @param nsURI the package NameSpace URI
* @return true if valid
*/
private boolean isValidPackage(String nsURI) {
for (String excludePackage : EXCLUDE_PACKAGE_NS_URI) {
if (excludePackage.equals(nsURI)) {
return false;
}
}
return true;
}

/**
* Returns the EClassifier for the passed Class
*
* @param cl
* @return returns null if the class is not an EObject or not found in the EPackages
*/
@SuppressWarnings("unchecked")
private EClass getClassifier(Class cl) {
if (EObject.class.isAssignableFrom(cl)) {
String name = cl.getSimpleName();
if (name.endsWith(CLASS_SUFFIX)) {
EClassifier classifier = getAllClassifiers().get(name.substring(0, name.indexOf(CLASS_SUFFIX)));
if (classifier instanceof EClass) {
return (EClass) classifier;
}
}
}
return null;
}

@SuppressWarnings("unchecked")
@Override
public Deserializer getDeserializer(Class cl) throws HessianProtocolException {
EClass classifier = getClassifier(cl);
if (classifier != null) {
return new EObjectDeserializer(classifier);
}
return null;
}

@SuppressWarnings("unchecked")
@Override
public Serializer getSerializer(Class cl) throws HessianProtocolException {
EClass classifier = getClassifier(cl);
if (classifier != null) {
return new EObjectSerializer(classifier);
}
return null;
}
}




EObjectSerializer.java


/*******************************************************************************
* $URL: $
*
* Copyright (c) 2007 henzler informatik gmbh, CH-4106 Therwil
*******************************************************************************/
package com.softmodeler.service.communication;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.impl.EObjectImpl;

import com.caucho.hessian.io.AbstractHessianOutput;
import com.caucho.hessian.io.AbstractSerializer;
import com.caucho.hessian.io.JavaSerializer;

/**
* Serializes EObjects, this class is based on the {@link JavaSerializer} instead of working with java fields,
* {@link EStructuralFeature} are used to serialize the 'data' values of the {@link EObject}.

* Java fields of the {@link EObjectImpl}; eAdapters, eFlags, eContainer, eContainerFeatureID and eProperties are
* ignored
*
* @see JavaSerializer
* @author created by Author: fdo, last update by $Author: fdo $
* @version $Revision: 1151 $, $Date: 2009-02-25 22:47:19 +0100 (Mi, 25 Feb 2009) $
*/
public class EObjectSerializer extends AbstractSerializer {
private List fieldSerializers;
private List fields;

/**
* constructor
*
* @param classifier
*/
@SuppressWarnings("unchecked")
public EObjectSerializer(EClass classifier) {
fields = classifier.getEAllStructuralFeatures();
fieldSerializers = new ArrayList();

for (EStructuralFeature feature : fields) {
if (!feature.isMany()) {
EClassifier eDataType = feature.getEType();
Class type = eDataType.getInstanceClass();
fieldSerializers.add(getFieldSerializer(type));
} else {
fieldSerializers.add(ListFieldSerializer.SER);
}
}
}

@SuppressWarnings("unchecked")
@Override
public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {
if (out.addRef(obj)) {
return;
}

Class cl = obj.getClass();

int ref = out.writeObjectBegin(cl.getName());

if (ref < -1) { writeObject10((EObject) obj, out); } else { if (ref == -1) { writeDefinition20(out); out.writeObjectBegin(cl.getName()); } writeInstance((EObject) obj, out); } } private void writeObject10(EObject obj, AbstractHessianOutput out) throws IOException { for (int i = 0; i < feature =" fields.get(i);" i =" 0;" feature =" fields.get(i);" ser =" new" value =" null;" value =" obj.eGet(feature);" ser =" new" value =" false;" value =" (Boolean)" ser =" new" value =" 0;" value =" (Integer)" ser =" new" value =" 0;" value =" (Long)" ser =" new" value =" 0;" value =" (Double)" ser =" new" value =" null;" value =" (String)" ser =" new" value =" null;" objvalue =" (List)" value =" new">



EObjectDeserializer.java


/*******************************************************************************
* $URL: $
*
* Copyright (c) 2007 henzler informatik gmbh, CH-4106 Therwil
*******************************************************************************/
package com.softmodeler.service.communication;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;

import com.caucho.hessian.io.AbstractHessianInput;
import com.caucho.hessian.io.AbstractMapDeserializer;
import com.caucho.hessian.io.HessianFieldException;
import com.caucho.hessian.io.IOExceptionWrapper;
import com.caucho.hessian.io.JavaDeserializer;

/**
* Deserializes EObjects, this class is based on the {@link JavaDeserializer} instead of working with java fields,
* {@link EStructuralFeature} are used to deserialize the 'data' values of the {@link EObject}.

* Java fields of the {@link EObjectImpl}; eAdapters, eFlags, eContainer, eContainerFeatureID and eProperties are
* ignored
*
* @see JavaDeserializer
* @author created by Author: fdo, last update by $Author: fdo $
* @version $Revision: 1236 $, $Date: 2009-03-03 22:51:32 +0100 (Di, 03 Mrz 2009) $
*/
public class EObjectDeserializer extends AbstractMapDeserializer {
private Map fieldMap;
private EClass classifier;

/**
* constructor
*
* @param classifier
*/
public EObjectDeserializer(EClass classifier) {
this.classifier = classifier;
fieldMap = getFieldMap(classifier);
}

@SuppressWarnings("unchecked")
@Override
public Class getType() {
return classifier.getInstanceClass();
}

@Override
public Object readMap(AbstractHessianInput in) throws IOException {
try {
EObject obj = instantiate();

return readMap(in, obj);
} catch (IOException e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IOExceptionWrapper(classifier.getName() + ":" + e.getMessage(), e); //$NON-NLS-1$
}
}

@Override
public Object readObject(AbstractHessianInput in, String[] fieldNames) throws IOException {
try {
Object obj = instantiate();
return readObject(in, (EObject) obj, fieldNames);
} catch (IOException e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IOExceptionWrapper(classifier.getName() + ":" + e.getMessage(), e); //$NON-NLS-1$
}
}

public Object readMap(AbstractHessianInput in, EObject obj) throws IOException {
try {
int ref = in.addRef(obj);

while (!in.isEnd()) {
Object key = in.readObject();

FieldDeserializer deser = fieldMap.get(key);

if (deser != null) {
deser.deserialize(in, obj);
} else {
in.readObject();
}
}

in.readMapEnd();

in.setRef(ref, obj);
return obj;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOExceptionWrapper(e);
}
}

public Object readObject(AbstractHessianInput in, EObject obj, String[] fieldNames) throws IOException {
try {
int ref = in.addRef(obj);

for (String name : fieldNames) {
FieldDeserializer deser = fieldMap.get(name);

if (deser != null) {
deser.deserialize(in, obj);
} else {
in.readObject();
}
}

in.setRef(ref, obj);
return obj;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOExceptionWrapper(obj.getClass().getName() + ":" + e, e); //$NON-NLS-1$
}
}

/**
* create an instance of the passed classifier
*
* @return
* @throws Exception
*/
protected EObject instantiate() throws Exception {
return EcoreUtil.create(classifier);
}

/**
* Creates a map featureName=>FieldDeserializer.
*/
@SuppressWarnings("unchecked")
protected Map getFieldMap(EClass classifier) {
Map fieldMap = new HashMap();

for (EStructuralFeature feature : classifier.getEAllStructuralFeatures()) {
if (feature.isTransient() || fieldMap.containsKey(feature.getName())) {
continue;
}
FieldDeserializer deser;

EClassifier eDataType = feature.getEType();
Class type = eDataType.getInstanceClass();

if (String.class.equals(type)) {
deser = new StringFieldDeserializer(feature);
} else if (byte.class.equals(type)) {
deser = new ByteFieldDeserializer(feature);
} else if (short.class.equals(type)) {
deser = new ShortFieldDeserializer(feature);
} else if (int.class.equals(type)) {
deser = new IntFieldDeserializer(feature);
} else if (long.class.equals(type)) {
deser = new LongFieldDeserializer(feature);
} else if (float.class.equals(type)) {
deser = new FloatFieldDeserializer(feature);
} else if (double.class.equals(type)) {
deser = new DoubleFieldDeserializer(feature);
} else if (boolean.class.equals(type)) {
deser = new BooleanFieldDeserializer(feature);
} else if (feature.isMany()) {
deser = new EListDeserializer(feature);
} else {
deser = new ObjectFieldDeserializer(feature);
}

fieldMap.put(feature.getName(), deser);
}
return fieldMap;
}

abstract static class FieldDeserializer {
protected EStructuralFeature feature;

public FieldDeserializer(EStructuralFeature feature) {
this.feature = feature;
}

abstract void deserialize(AbstractHessianInput in, EObject obj) throws IOException;

}

static class EListDeserializer extends FieldDeserializer {

EListDeserializer(EStructuralFeature feature) {
super(feature);
}

@SuppressWarnings("unchecked")
@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
List value = null;

try {
value = (List) in.readObject(List.class);
if (value.size() > 0) {
obj.eSet(feature, value);
}
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static class ObjectFieldDeserializer extends FieldDeserializer {

ObjectFieldDeserializer(EStructuralFeature feature) {
super(feature);
}

@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
Object value = null;

try {
value = in.readObject(feature.getEType().getInstanceClass());

if (value != null) {
obj.eSet(feature, value);
}
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static class BooleanFieldDeserializer extends FieldDeserializer {
BooleanFieldDeserializer(EStructuralFeature feature) {
super(feature);
}

@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
boolean value = false;

try {
value = in.readBoolean();

obj.eSet(feature, value);
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static class ByteFieldDeserializer extends FieldDeserializer {
ByteFieldDeserializer(EStructuralFeature feature) {
super(feature);
}

@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
int value = 0;

try {
value = in.readInt();

obj.eSet(feature, value);
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static class ShortFieldDeserializer extends FieldDeserializer {
ShortFieldDeserializer(EStructuralFeature feature) {
super(feature);
}

@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
int value = 0;

try {
value = in.readInt();

obj.eSet(feature, value);
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static class IntFieldDeserializer extends FieldDeserializer {
IntFieldDeserializer(EStructuralFeature feature) {
super(feature);
}

@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
int value = 0;

try {
value = in.readInt();

obj.eSet(feature, value);
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static class LongFieldDeserializer extends FieldDeserializer {
LongFieldDeserializer(EStructuralFeature feature) {
super(feature);
}

@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
long value = 0;

try {
value = in.readLong();

obj.eSet(feature, value);
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static class FloatFieldDeserializer extends FieldDeserializer {
FloatFieldDeserializer(EStructuralFeature feature) {
super(feature);
}

@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
double value = 0;

try {
value = in.readDouble();

obj.eSet(feature, value);
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static class DoubleFieldDeserializer extends FieldDeserializer {
DoubleFieldDeserializer(EStructuralFeature feature) {
super(feature);
}

@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
double value = 0;

try {
value = in.readDouble();

obj.eSet(feature, value);
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static class StringFieldDeserializer extends FieldDeserializer {
StringFieldDeserializer(EStructuralFeature feature) {
super(feature);
}

@Override
void deserialize(AbstractHessianInput in, EObject obj) throws IOException {
String value = null;

try {
value = in.readString();

obj.eSet(feature, value);
} catch (Exception e) {
logDeserializeError(feature, obj, value, e);
}
}
}

static void logDeserializeError(EStructuralFeature feature, Object obj, Object value, Throwable e)
throws IOException {
String fieldName = (feature.getContainerClass().getName() + "." + feature.getName()); //$NON-NLS-1$

if (e instanceof HessianFieldException) {
throw (HessianFieldException) e;
} else if (e instanceof IOException) {
throw new HessianFieldException(fieldName + ": " + e.getMessage(), e); //$NON-NLS-1$
}

if (value != null) {
throw new HessianFieldException(fieldName + ": " + value.getClass().getName() + " (" + value + ")" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ " cannot be assigned to " + feature.getEType().getName()); //$NON-NLS-1$
} else {
throw new HessianFieldException(fieldName + ": " + feature.getEType().getName() //$NON-NLS-1$
+ " cannot be assigned from null", e); //$NON-NLS-1$
}
}
}

Wednesday, June 11, 2008

Spring Dynamic Modules and Hibernate

I'm currently working on a Sourceforge project.
On the server side I want to use Spring DM and Hibernate.
Eclipse RCP and Spring DM builds the client.

I spent the last few evenings trying and searching for a working Spring DM/Hibernate example. I had a lot of classloading issues.
Yesterday I got it to work, you can download the plug-in here.

It's a simple application handling a User object and using HSQL as database.

I added all the dependent jars in the /lib directory. You can create separated plug-ins for them if you want.
Here a list of all the jar files, because thats where I had my problems:
  • cglib-nodep-2.1_3.jar
  • commons-collections.jar
  • commons-dbcp.jar
  • commons-pool.jar
  • dom4j-1.6.1.jar
  • hibernate3.jar
  • hsqldb.jar
  • jta.jar
  • spring-core.jar
  • spring-jdbc.jar
  • spring-orm.jar
  • spring-tx.jar // why is the org.springframework.dao package in this jar?

You can access the service in the Test class:

package com.blogspot.swissdev.springservice;

import org.osgi.framework.BundleContext;

/**
*
* @author Flavio Donze
*/
public class Test {

private BundleContext context = Activator.getDefault().getContext();

public void start() {
System.out.println("starting the test...");

UserService service = (UserService) context.getService(context.getServiceReference(UserService.class.getName()));

User user = (User) context.getService(context.getServiceReference(User.class.getName()));
user.setPassword("pass");
user.setUsername("user");
service.store(user);

for (User u : service.findAll())
{
System.out.println("User: "+u.getId() + ", " + u.getUsername() + ", " + u.getPassword());
}
}
}


And here is my Spring configuration:

<?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.5.xsd">

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="META-INF/spring/database.properties"/>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>

<bean id="test" init-method="start" class="com.blogspot.swissdev.springservice.Test"/>

<!-- USER beans, POJO, DAO, Service -->
<bean id="user" class="com.blogspot.swissdev.springservice.UserImpl" scope="prototype">
</bean>

<bean id="userDao" class="com.blogspot.swissdev.springservice.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>

<bean id="userService" class="com.blogspot.swissdev.springservice.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>

</beans>
Since I just wanted to get Spring DM and Hibernate to work, I didn't really test the rest, just in case you encounter some bugs.

To setup your workspace with Spring DM read the first part of my previous post.

For this example I used:
Eclipse 3.4 RC3
Spring Dynamic Modules for OSGi(tm) 1.0.2

Wednesday, June 4, 2008

Eclipse RCP Application using Spring DM

Last week I was searching the web for some example of Spring DM running on a Eclipse RCP application.
Didn't find one, so I thought I could write a post.

Download:
Eclipse 3.4 RC3
Spring Dynamic Modules for OSGi(tm) 1.0.2

Now create a new Plug-in-Project, using the settings below:
























As a next step you have to import the Spring DM Plug-ins.
File->Import->Plug-in Development->Plug-ins and Fragments.
Point the plug-in location to the extracted "spring-osgi-1.0.2/dist" directory.



On the next page, add the following plug-ins:
  • org.springframework.bundle.osgi.core
  • org.springframework.bundle.osgi.extender
  • org.springframework.bundle.osgi.io
You just imported the Spring DM OSGi part, you also need the actual Spring framework.
Do the same as above, but instead of the "dist" directory select the "spring-osgi-1.0.2/lib" dir and select those plugins:
  • org.springframework.bundle.spring.aop
  • org.springframework.bundle.spring.beans
  • org.springframework.bundle.spring.context
  • org.springframework.bundle.spring.core
  • org.springframework.osgi.aopalliance.osgi
We have to manually create a apache commons logging plugin.
Spring DM has some classloading problems with the existing plugin contained in the eclipse platform.
New->Plug-in Development->Plug-in from existing JAR archives.
Add External...
Now if you have the Spring framework including dependencies on your machine select the commons-logging.jar located at "spring-framework-2.5.x/lib/jakarta-commons", otherwise download the jar here.
Name the plugin "org.apache.commons.logging

Ok, so now your workspace is ready.
Let's create a Spring service.

package swissdev.springdm;

public interface IMyService {

String getSomething();
}


package swissdev.springdm;

public class MyService implements IMyService {

@Override
public String getSomething() {
return "something";
}

public void start() {
System.out.print("start service");
}

public void stop() {
System.out.print("stop service");
}
}

META-INF/spring/applicationContext.xml

<?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.5.xsd">

<bean id="myService"
class="swissdev.springdm.MyService"
init-method="start"
destroy-method="stop"/>

</beans>


META-INF/spring/applicationContext-osgi.xml

<?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 id="myServiceOsgi" ref="myService" interface="swissdev.springdm.IMyService"/>

</beans>


Our application is basically ready to launch, so lets do that.
Right click on the swissdev.springdm plug-in: Run-As -> Eclipse Application.
A simple window containing a view is launched, nothing special.

Open the run configuration: Run -> Run Configurations...
Select your "swissdev.springdm.application" launch config and change to the "Arguments" tab.
Add "-console" to the Program arguments.
Switch to the Plug-ins tab and select all the "Workspace" plug-ins, hit the "Add Required Plug-ins" button and run again.
Type ss in the console, you will get the following output:



So our Spring plug-ins are not active.
Open the run configurations again and switch to the "Configurations" tab, change the Configurations File option to "Use existing config.ini file as a template" and enter ${workspace_loc}/swissdev.springdm/config.ini.
We can get the default generated config.ini in our workspace.
It's located at /.metadata/.plugins/org.eclipse.pde.core/swissdev.springdm.application/config.ini, copy it to your plug-in.
Right click on the ini file and select Open With -> Text Editor.
Ctrl+f Find: extender
You should find ....org.springframework.bundle.osgi.extender add @start at the end:
org.springframework.bundle.osgi.extender@start
Do the same with the swissdev.springdm plugin.

Launch again, you will see a lot of output and somewhere between "start service", thats the output we defined in the MyService class.
Spring DM is working!

To use our service we first need to modify our Activator:

private BundleContext context;

public BundleContext getContext() {
return context;
}

public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
this.context = context;
}



Open the generated View class and edit the createPartControl method:

public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL);
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setInput(getViewSite());
viewer.addDoubleClickListener(new IDoubleClickListener() {

@Override
public void doubleClick(DoubleClickEvent event) {
ServiceTracker tracker = new ServiceTracker(Activator.getDefault().getContext(), IMyService.class.getName(),null);
tracker.open();
IMyService service = (IMyService) tracker.getService();
System.out.println(service.getSomething());
}
});
}


Launch again and double click one of the itms in the window, in the console there should appear an "something" output.

That was it....