Automatic Spring in InspectIT RCP

Since the Spring is used in the InspectIT RCP as the plug-in dependency we can have the advantage of automatic Spring in this plug-in.

Additional Dependencies

To be able to use the automatic Spring on the UI these additional budeles are required:

		<dependency org="org.springframework.osgi" name="org.springframework.osgi.core" rev="1.2.1" conf="osgi->compile" />
		<dependency org="org.springframework.osgi" name="org.springframework.osgi.extender" rev="1.2.1" conf="osgi->compile" />
		<dependency org="org.springframework.osgi" name="org.springframework.osgi.io" rev="1.2.1" conf="osgi->compile" />

Implementation

Implementation is quite straight forward:

  1. All Spring .xml files should be placed in the META-INF/spring folder. The Spring will automatically search there if not said otherwise.
  2. MANIFEST.MF file of InspectIT RCP should add the following line: 

    Spring-Context: *;create-asynchronously:=false

    This line means two things:


    1. The '*' tells Spring to load all files from the META-INF/spring folder
    2. Not to create the Spring context asynchronously (for us this is not an option since we need some services exposed by context during start-up
  3.  In the start(BundleContext context) method of the info.novatec.inspectit.rcp.InspectIT class it is neccessary to manually start the org.springframework.osgi.extender bundle: 

    	public void start(BundleContext context) throws Exception {
    		plugin = this;
    		super.start(context);
    		// Enforcing that Spring Dynamic Modules extender is started
    		Platform.getBundle("org.springframework.osgi.extender").start();
    	}

Exposing of Services

With Spring Dynamic Modules it is possible to expose any Spring bean as the bundle service. This means that any bean can be a service of our info.novatec.inspectit.rcp bundle context. Currently we expose two services: 

<osgi:service id="storageManagerService" ref="storageManager" interface="info.novatec.inspectit.rcp.storage.InspectITStorageManager"/>
<osgi:service id="cmrServiceProviderService" ref="cmrServiceProvider" interface="info.novatec.inspectit.rcp.repository.service.cmr.CmrServiceProvider"/>

Services can be later retrieved by executing the utility method in the InspectIT class:

	/**
	 * Returns a service, if one is registered with the bundle context.
	 * 
	 * @param clazz
	 *            Class of service.
	 * @param <E>
	 *            Type
	 * @return Service or <code>null</code> is service is not registered at the moment.
	 */
	public <E> E getService(Class<E> clazz)

Problems

One problem that I stumbled on was with manual creating the HttpInvokerProxyFactoryBean. The bean class loader of this bean has to be manually changed to the same class loader all classes in the RCP plug-in where loaded with. This is a known problem, and this solution was suggested on several places I have looked:

HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean = new HttpInvokerProxyFactoryBean();


// we need to set the class loader on our own
// the problems is that the service interface class can not be found
// I am not quite sure why, but this is suggested on several places as a patch
httpInvokerProxyFactoryBean.setBeanClassLoader(getClass().getClassLoader());