Equinox Integration

From ADempiere
Jump to: navigation, search
This Wiki is read-only for reference purposes to avoid broken links.
ADempiere is now pluggable thanks to Joerg Viola!

Eclipse Equinox Plugins in ADempiere

Eclipse Equinox (http://www.eclipse.org/equinox) is an implementation of OSGi R4. Moreover, it provides applications with a plugin mechanism based on extension points and extensions satisfying them.

Integration with ADempiere has only truly started with the proofs in this page by Joerg Viola of ObjectCode GMBH working on the shoulders of Schmidt András's earlier Felix usage and Low Heng Sin's advice to use Equinox instead. (You may want to read Joerg Viola's [german article about Equinox])

Two technical approaches are feasible:

  • Approach 1: Embedding Equinox in Adempiere, described in this article
  • Approach 2: Embedding Adempiere in Equinox, described here

Currently, an alpha demo is available. The vision is to integrate it into Adempiere core an have every further extension be delivered as a plugin.

Technical documentation

The integration consists of four components, implemented each in its own project in an eclipse environment.

Adempiere patch

  • This patch currently is very simple. It consists of
    • The interface IExtension, a factory for IExtensions called Extension and two implementations:
      • The DefaultExtension contains code extracted from ADempiere core classes.
      • Equinox contains code to delegate the functionality to equinox plugins.
      • Which extension is used, depends on a prefix of e.g. the given classname: osgi://formClassName would use Equinox whereas formClassName would use the DefaultExtension and thus provide a clean fallback
    • Patched core classes, namely:
    • class org.compiere.Adempiere: Start all extensions
    • class org.compiere.apps.form.FormFrame: Form class loading
    • class org.adempiere.util.ProcessUtil: Process class loading
    • class org.compiere.model.GridTab: Callout class loading
    • The Equinox Extension starts the Equinox container
      • It does so in a seperate thread, because the platform modifies the context classloader
      • It fires up an OSGi console on port 1234, so that you may connect to it via telnet and see whats going on
      • It then asks for the so-called "host service", an OSGi-Service gatewaying requests from the patched adempiere core into equinox
    • A lib-folder that must be copied to the runtime classpath
      • In fact, I don't like the way, libraries are re-packages during Adempiere install
      • Nevertheless, the Equinox OSGI jar must stay intact in order to work, so I switched to only deploy the patch itself, not the supporting libraries re-packaged
    • An build file that, after having setup a build.properties does the re-packaging and deploying into an installed JBoss.

Adempiere Extension

  • This is an extension fragment to the system bundle (OSGi slang...)
  • It provides the ADempiere classes to the classpath of all plugins
  • It is merely declarative and contains no code

Adempiere Equinox bundle

  • This is a bundle that connects plugins to the ADempiere internals
  • It will provide the extension points for ADempiere
  • Currently, there are
    • ModelValidator
    • Form
    • Callout
    • Process
  • It implements and registers the so-called "host-service" that receives requests from the adempiere core and dispatches them to bundles, typically via extension points.
  • It implements and registers the "dictionary service", that uses PackIn to import PackOut.xml.
  • It provides a Plugin base class, AbstractAdempierePlugin, that handles install and startup:
    • If the plugin is started for the first time:
      • If /META-INF/PackOut.xml exists, it is PackedIn
      • If not, the plugin is manually registered as an imported package
      • The method install() of the bundle is called
    • The Method start() of the bundle is called (this substitutes start(BundleContext) from OSGi)
    • On stop, The Method stop() of the bundle is called (this substitutes stop(BundleContext) from OSGi)
  • So, if you want a full re-install of the plugin, you must increment the version number or delete the corresponding entry in "Imported packages"
  • Caution: Name and Version in the bundle header and in PackOut.xml must correspond!

The TestPlugin

  • This is a very simple plugin testing the above
  • Its activator does nothing
  • It provides extensions to the extension points ModelValidator, Callout and Process
  • The extension consists of a ModelValidator class (you wouldn't have thought so, would you?)

Basic Setup

This Basics and JBoss Setup will make use of the WebUI layer. Other Setups will target Java Client, WebStart and so on.

Basics and JBoss Setup

  • Install an eclipse, checkout the ADempiere trunk (as adempiereTrunk) an install it.
    • adempiereTrunk/adempiere/Adempiere/jboss will then contain a jboss ready to run
  • The Code is in this branch: /branches/osgi/approach1
    • There are several projects to be separately checked out aside adempiereTrunk
  • copy Adempiere-patch/build.properties to build-local.properties and set the path to the adempiere project
  • at Line 103 of build.xml change AdempiereOriginal.jar to Adempiere.jar
  • at Line 112 of build.xml change webuiOriginal.war to webui.jar
  • run Adempiere-patch/build.xml
    • It will populate your Adempiere JBoss with the patch, all required equinox library and configurations

Equinox Manifest

  • Open AdempiereEquinox/META-INF/MANIFEST.MF (make sure you are in the J2EE Perspective)

EclipseExtPoint.PNG

  • NOTES
    • The tab "extension points" contains the ModelValidator point.
    • Click on the third icon in the header ("Export deployable...") or in the menu File/Export/Plugin Development/Deployable plugins and fragments.

Deploying

EclipseDeploy.PNG

  • NOTES
    • Ensure build.properties has right settings, such as - jars.extra.classpath = ../../adempiereTrunk/install/build/Adempiere/lib/Adempiere.jar
    • Select AdempiereEquinox, AdempiereExtension and the TestPlugin for deployment
    • Choose as destination directory: <path to adempiere project>\adempiere\adempiere\Adempiere\jboss\server\adempiere\deploy\adempiere.ear\lib
    • Click Finish
    • In the ear deployment in JBoss, you should have a lib folder containing jar, a configuration folder and a plugins folder with the three plugins from above

Start Application Server

  • Start your JBoss
    • Watch out for the lines:
INFO  [STDOUT] Starting Equinox...
INFO  [STDOUT] Listening on port 1234 ...
INFO  [STDOUT] Adempiere Host Bundle started
INFO  [STDOUT] Got Val Engine: ModelValidationEngine[Validators=#1, ModelChange=#1, DocValidate=#1]
INFO  [STDOUT] ModelValidator on: AD_User
INFO  [STDOUT] Hello World!!

Congrats! Your equinox container started, opened a telnet port, started the Host Bundle which in turn got a ModelValidation engine, found the TestPlugin listening on Table AD_User and registered it on the Engine.

Test

  • Now fire up the ZK Web UI, login as SuperUser, Role System Administrator and change any field value in the Window User.
  • You will see:
INFO  [STDOUT] ModelChange 2 on AD_User:1000000
INFO  [STDOUT] ModelChange 5 on AD_User:1000000
  • Phew! ADempiere plugin via equinox is working!
  • Now open TestPlugin/META-INF/MANIFEST.MF

EclipseExt.PNG

  • On the extension tab, you can see why it listens on AD_User: It was declared to the host bundle in the manifest!

Other Setups

Here we see the deployment on other clients in use such as the Java Swing Client, WebStart client on LAN and other forms of plugins.

Swing Client Setup

If you have successfully installed Equinox into your JBoss, making it available in the Swing Client is easy:

  • run Adempiere-patch/build.xml
    • Use the target dist-client for instrumenting your swing client
  • run RUN_setup.sh in order to re-package the jars again
  • Repeat the plugin deployment above, using $ADEMPIERE_HOME/lib destination directory
  • ... and eventually a nasty step: Edit the script $ADEMPIERE_HOME/lib/RUN_Adempiere.sh (or .bat) locate the line where the CLASSPATH is set up and add $ADEMPIERE_HOME/lib/org.eclipse.osgi_3.4.2.R34x_v20080826-1230.jar to it.

WebStart Setup

Equinox is useable in a WebStart-Deployment also! Nevertheless, currently it is tricky to configure, which plugins are to be deployed with the Webstart Client. Do the following:

Build your own plugin

  • simply create a new eclipse plugin project
  • use AdempiereEquinox as required bundle
  • register a ModelValidator class as the extension
  • deploy the plugin to JBoss as above
  • restart JBoss (or use the telnet session an stop/start the host bundle)

Form extensions

It is now possible to deploy swing forms via a plugin. To do this, create a plugin and specifiy some dependencies:

EclipseFormDep.PNG

Switch to the extension tab, click add and choose the AdempiereEquinox.Form extension point. Right-click on the new extension and choose New.../client. Create or select the class (must be of type FormPanel)

EclipseFormExt.PNG

Deploy the plugin. As usual, as SuperUser create a new Form, spüecifying the class as above and a new Menu entry. Try it!

WebForm extensions

This works essentially the same as for Form above, extending the point WebForm of course. Nevertheless, two things are different:

  • Since plugins essentially are deployed in the EJB layer but must have access to classes in the web layer (org.adempiere.webui.* and org.zkoss.*), the JBoss WAR classloader has to be turned off. This is a drawback since we no longer have classpath separation between web- and ejb-tier. You do this by switching the attribute UseJBossWebLoader to true in $JBOSS/server/adempiere/deploy/jboss-web.deployer/META-INF/jboss-service.xml.
  • You have to import several additional packages in your plugin, at least: org.adempiere.webui.component, org.adempiere.webui.panel,org.zkoss.zk.ui and org.zkoss.zk.ui.event.

Other Possible Requirements

  • If we deploy plugins to a server, we should be able to choose which plugins are applied to certain situations - for example - if accounting methods (allowed under various IFRS) were plugins, then each adempiere client would need to select or configure which plugin they use for each accounting schema. Therefore, we would need to be able to have a plugin lookup field, and select the plugin and perhaps a method for each feature (similar to current class callouts).
  • We might want to define plugin types - where we can have say accounting method plugins, which implement accounting methods and can be selected from the accounting method field on the accounting schema tab/window. i.e. a way of filtering plugin selection to only valid types
  • We might need to see a list of available and installed plugins - propose available plugin list is retrieved from the repository and installed plugin list is stored in a table
  • We would need to configure plugins - e.g like sysconfig - suggest extending sysconfig for core / plugin - perhaps we could have a config interface which implements a config form / window in a plugin implementation (template)


See Also

Tutorials for me (an idiot)