Difference between revisions of "ADempiere/OSGi Integration"

From ADempiere
Jump to: navigation, search
This Wiki is read-only for reference purposes to avoid broken links.
(Overview: put pic)
(OSGi module framework in ADempiere)
Line 1: Line 1:
 
=OSGi module framework in ADempiere=
 
=OSGi module framework in ADempiere=
 
+
[[Image:120px-OSGi_Logo.gif|right]]
 
==Overview==
 
==Overview==
 
OSGi is a modular framework for Java with many advanced features. For information see  http://en.wikipedia.org/wiki/OSGi.
 
OSGi is a modular framework for Java with many advanced features. For information see  http://en.wikipedia.org/wiki/OSGi.

Revision as of 22:42, 1 August 2008

OSGi module framework in ADempiere

120px-OSGi Logo.gif

Overview

OSGi is a modular framework for Java with many advanced features. For information see http://en.wikipedia.org/wiki/OSGi.

Modular design has many advantages on huge projects such as ADempiere. Integrating OSGi may have huge impact on maintainability of the code.

Integration with ADempiere was done by Schmidt András.

OSGi module framework is not part of the project yet it is just a proposal.

Technical documentation and howto

Overview

150px-Apache Felix Logo.png

The Apache Felix OSGi implementation was selected for integration. This is the framework that is easiest to be run embedded.

Embedding an OSGi framework with the following properties could be a common task when converting non-OSGi software to modular design. So I have decided to create a new project for the embedding code. This project's output is a single jar file that contains felix.jar and some helper methods for easier startup. Helper methods' interface are implementation independent so change to Equinox or Knopflerfish can be done by just replacing a single jar of the project. The embedder is announced here: http://i-erp.i-logic.hu/?q=content/osgi-embedder-adempiere-and-other-projects. It is not documented too much yet.

The properties of embedding:

  1. Don't use a constant configuration but create a new one for each started instance in a temporary directory.
  2. Start all plugins in a directory on startup. So installing plugins can be done by just copying them.
  3. Hot Start plugins, so plugins can be started without restarting the server.
  4. Export some packages of the host application, so they can be reached from the osgi bundles.

Parameters of the OSGI starter

Exported packages

The exported packages of the host application (so bundles can resolve these packages and load classes from them) are listed in file: "base/src/org/compiere/exported.properties"

This file is a comma and whitespace separated list of package names. It has ".properties" suffix so that it will be packaged into the created jar file without changing the build.xml files.

Initial startup plugins directory

Osgi bundles in this directory will be started on ADempiere (embedded osgi) startup. This directory is:

  1. either the system property: System.getProperty("org.osgi.bundles.dir")
  2. or the directory "%ADEMPIERE_HOME%/plugins" if this system parameter does not exist.

Dynamic startup plugins directory

File changes in this directory will be scanned periodically. Plugins copied here will be started automatically just as ear and web application hot deploy works on application and web servers. This directory is:

  1. either the system property: System.getProperty("org.osgi.bundles.dynamic.dir")
  2. or the directory "%ADEMPIERE_HOME%/dynPlugins" if this system parameter does not exist.

Creating a extension bundle

Import packages from ADempiere

The extension bundle has to import packages from ADempiere using import package in MANIFEST.MF. It can be handled in the Dependencies/import packages field if edited using Eclipse plugin manifest editor.

Import-Package: org.adempiere.process,
 org.adempiere.util

Publish a service

In activator's start method:

	public void start(BundleContext context) throws Exception {
		Dictionary<String, Object> props=new Hashtable<String, Object>();
		props.put("name", "org.myorg.MyProcessClassName");
		context.registerService(ProcessCall.class.getName(),
				new MyProcess(), props);
	}

If the name parameter is used then the ClassByNameUtil (in ADempiere) will find this class on the given name instead of the class's real name.


Changes made to the source code

  1. replace class.forName(name) constructions throughout the code with ClassLoaderUtil.loadClass(name). It is imperative as the few lines of class loading n-plicates code all around the project. This util handles OSGI extension mechanisms _and_ class.forName mechanism. OSGI class loading and later extension mechanisms can then be integrated at a single point.
  2. Hook OSGI startup to server and client startup.
  3. Include the modified apache felix Osgi framework jar into the project.
  4. Add a plugin autoloader funcionality to OSGI that scans a directory for new plugins, so installing a plugin does not require hacking with configuration files.
  5. Add a MANIFEST.MF file to the project with "Export-Package: " tag. This way osgi plugins in Eclipse workspace will be able to resolve dependencies set as packages to the ADempiere project. This package export should be added to each separate project too. As I use single project workspace I could not do that work.

See Also