Using Cayenne with RCP
The most common style when using Cayenne inside an RCP-Application is to create three plugins. The first plugin is a simple wrapper around the "cayenne.jar". The second one defines our domain objects, our custom cayenne data objects. The third plugin might be the user interface plugin, that uses the domain objects. Since every plugin in Eclipse has its own classloader, this usually leads to the following common problems:
- The cayenne-plugin needs to load classes from the domain objects plugin.
- The domain-objects plugin needs to load classes from the cayenne plugin for extension an data object maniplulation.
- The user interface plugin needs to load classes from the domain-objects plugin and the cayenne-plugin, to have access to a conistent type hierachy.
When you try to solve this with the dependencies mechanism, you get cycles in your dependency graph. The cayenne-plugin needs the domain-objects on the classpath, the domain-objects need the cayenne-plugin on the classpath. The user-interface plugin needs both of them on the classpath.
Buddy Classloading
Since Eclipse 3.1 there is a new mechnism called "Buddy Classloading". Plugin A can say "I want to be someones buddy", by putting the following lines into the OSGi-Manifest of the plugin:
Eclipse-BuddyPolicy: registered
Plugin B can say "I want to be a buddy of plugin A" by putting this into the manifest:
Eclipse-RegisterBuddy: A
Now plugin A is able to load classes from plugin B without specifiying a dependency to plugin B. This is exactly what we need in order to run Cayenne inside an RCP-Application. The cayenne-plugin needs to put Eclipse-BuddyPolicy: registered into its manifest, to make it accept buddies. The domain-objects plugin needs to register the cayenne-plugin as its buddy: Eclipse-RegisterBuddy: cayenne-plugin. Additionaly the domain-objects plugin must reexport the dependency to cayenne to make it accessible to the user-interface plugin. Now voila:
- The cayenne-plugin is able to load classes from the domain-objects plugin.
- The domain-objects plugin is able to load classes from the cayenne-plugin.
- The user-interface plugin has access to a consistent type hirarchy, because the domain-objects plugin reexports the cayenne-plugin.
By the way: Lots of the logging libraries for Java like Log4J share common problems. They have to instantiate custom appenders, via reflection, that are defined in other plugins, than the log4j.jar.
Hope this helps.
Send your sugestions go to adam.mansfeld<at>gmx<dot>de.