HowTo JPF

Aus Java Student User Group Austria - Java + JVM in Wien Österreich / Vienna Austria
Version vom 30. Dezember 2008, 19:43 Uhr von Christoph.pickl (Diskussion | Beiträge) (Die Seite wurde neu angelegt: written by Christoph P; created Tuesday, December 30, 2008 =introduction= ==architecture overview== <code> | ...)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

written by Christoph P; created Tuesday, December 30, 2008

introduction

architecture overview

|                                          |
|               boot                       |
|                                          |
+------------------------------------------+
|            |              |              |
|    core    |   plugin_1   |   plugin_n   |   
|            |              |              |
+++++++++++++++++++ JPF ++++++++++++++++++++
*********** Java, VM, Classloader **********

the plugin concept

  • plugin: with jpf the whole application is separated in plugins (kind of module). it holds the code, resources, libraries and defines requirements/imports, exports, extension-points and extensions.
  • extension-point: an interface which is provided by the plugin. an extension-point is identified by its plugin-id and extension-point-id, and defines parameters for that interface.
  • extension: could be thought as an implementation for a given interface. a plugin can extend the extension-point of another plugin and pass concrete values as arguments (most of the time only a "class" attribute which holds the full qualified name of a class).

example

startuping up the framework

you can start the java plugin framework either by simply providing a boot.properties file and executing a utility jar, or by writing custom code which gives you full control of boot procedure (preferred way). the last option is nevertheless required for unit tests.

let properties-file do the work (simple)

file boot.properties

# application plugin id
org.java.plugin.boot.applicationPlugin = at.ac.tuwien.jsug.jpf.startup
# [ full | light | off ]
org.java.plugin.boot.integrityCheckMode = light
#org.java.plugin.boot.splashImage = ${applicationRoot}/splash.png

#-------------------------------------------------------------------------------
# JPF runtime configuration

org.java.plugin.PathResolver = org.java.plugin.standard.ShadingPathResolver
org.java.plugin.standard.ShadingPathResolver.shadowFolder = ${applicationRoot}/temp/.jpf-shadow
org.java.plugin.standard.ShadingPathResolver.unpackMode = smart
org.java.plugin.standard.ShadingPathResolver.excludes = CVS

#-------------------------------------------------------------------------------
# could be some more properties defined for own usage

execute following line on the command line interface: java -jar lib/jpf-boot.jar

take over full control (advanced)

<source lang="java"> package at.ac.tuwien.jsug.jpf.boot;

import javax.swing.SwingUtilities; import org.java.plugin.ObjectFactory; import org.java.plugin.PluginManager; import org.java.plugin.PluginManager.PluginLocation; import org.java.plugin.boot.DefaultPluginsCollector; import org.java.plugin.util.ExtendedProperties; import at.ac.tuwien.jsug.jpf.core.ICoreApplicationPlugin;

/**

* entry point for the application to bootstrap jpf and
* invoke CoreApplicationPlugin.startApplication().
*/

public class JpfBooter { private static final String PLUGINS_REPOSITORY = "./plugins";

public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new App().start(); }}); }

private void start() { final PluginManager manager = ObjectFactory.newInstance().createManager(); final DefaultPluginsCollector collector = new DefaultPluginsCollector(); final ExtendedProperties props = new ExtendedProperties(); props.setProperty("org.java.plugin.boot.pluginsRepositories", PLUGINS_REPOSITORY);

try { collector.configure(props); manager.publishPlugins(collector.collectPluginLocations().toArray(new PluginLocation[] {}));

final ICoreApplicationPlugin corePlugin = (ICoreApplicationPlugin) manager.getPlugin("at.ac.tuwien.jsug.jpf.core"); corePlugin.startApplication(); } catch (Exception e) { e.printStackTrace(); } } } </source>

create the main boot part

* src/main/java/
  - at.ac.tuwien.jsug.jpf.boot.JpfBooter.java
* src/main/resources/
  - log4j.properties
* plugins/
  - at.ac.tuwien.jsug.jpf.core/ ... target output for core plugin
  - at.ac.tuwien.jsug.jpf.export/ ... target output for export plugin

create the core application plugin

* src/main/java/
  - at.ac.tuwien.jsug.jpf.core.CoreApplicationPlugin.java
  - at.ac.tuwien.jsug.jpf.core.ICoreApplicationPlugin.java
  - at.ac.tuwien.jsug.jpf.core.IMenuBarPlugin.java
* src/main/resources/
  - plugin.xml

file plugin.xml <source lang="xml"> <?xml version="1.0" ?> <!DOCTYPE plugin PUBLIC "-//JPF//Java Plug-in Manifest 1.0" "http://jpf.sourceforge.net/plugin_1_0.dtd"> <plugin id="at.ac.tuwien.jsug.jpf.core" version="0.0.1" class="at.ac.tuwien.jsug.jpf.core.CoreApplicationPlugin">

<runtime> <library id="core" path="/" type="code"> <export prefix="*" /> </library> </runtime>

<parameter-def id="class" /> </extension-point> </plugin> </source>

you might want to use the following handy method for retrieving plugins: <source lang="java"> @SuppressWarnings("unchecked") public static <T> List<T> fetchPlugins( final Plugin plugin, final String extPointPluginId, final String extPointId, final String attributeName) throws Exception { final List<T> result = new LinkedList<T>();

final PluginManager manager = plugin.getManager();

final ExtensionPoint extPoint = manager.getRegistry().getExtensionPoint(extPointPluginId, extPointId); for (final Extension extension : extPoint.getConnectedExtensions()) { // LOG.info("Processing extension point: " + extension);

final PluginDescriptor extensionDescriptor = extension.getDeclaringPluginDescriptor(); manager.activatePlugin(extensionDescriptor.getId()); final ClassLoader classLoader = manager.getPluginClassLoader(extensionDescriptor); final String pluginClassName = extension.getParameter(attributeName).valueAsString(); final Class<T> pluginClass = (Class<T>) classLoader.loadClass(pluginClassName); final T pluginInstance = pluginClass.newInstance(); result.add(pluginInstance); }

return result; } </source>

create an extension

* src/main/java/
  - at.ac.tuwien.jsug.jpf.export.ExportMenuBarPlugin.java
* src/main/resources/
  - plugin.xml

file plugin.xml <source lang="xml"> <?xml version="1.0" ?> <!DOCTYPE plugin PUBLIC "-//JPF//Java Plug-in Manifest 1.0" "http://jpf.sourceforge.net/plugin_1_0.dtd"> <plugin id="at.ac.tuwien.jsug.jpf.export" version="0.0.1">

<requires> <import plugin-id="at.ac.tuwien.jsug.jpf.core" /> </requires>

<runtime> <library id="src" path="/" type="code" /> </runtime>

<extension plugin-id="at.ac.tuwien.jsug.jpf.core" point-id="MenuBar" id="ExportMenuBar"> <parameter id="class" value="at.ac.tuwien.jsug.jpf.export. ExportMenuBarPlugin" /> </extension> </plugin> </source>

<source lang="java"> package phudy.jpf.pluginexport;

import at.ac.tuwien.jsug.jpf.core.IMenuBarPlugin;

public class ExportMenuBarPlugin implements IMenuBarPlugin {

public String getTitle() { return "Export"; }

public int getWeight() { return 500; }

public void execute() { System.out.println("exec export"); }

}

</source>

appendix

links

notes

  • although it is more common to write "plug-in" instead of "plugin", i am going not to write the additional "-" character :)