29
S Proteus Framework Redefining the plugin

Proteus Framework

  • Upload
    arav

  • View
    64

  • Download
    0

Embed Size (px)

DESCRIPTION

Proteus Framework. Redefining the plugin. Why a new framework?. Present approaches (e.g. OSGi ) use non-standard approaches that create too many breaking points Designing a plugin architecture for both scalability and supportability requires an extra level of design often overlooked - PowerPoint PPT Presentation

Citation preview

Page 1: Proteus Framework

S

Proteus FrameworkRedefining the plugin

Page 2: Proteus Framework

Why a new framework?

Present approaches (e.g. OSGi) use non-standard approaches that create too many breaking points

Designing a plugin architecture for both scalability and supportability requires an extra level of design often overlooked

Few developers embrace the built-in plugin capabilities of the Java platform

Page 3: Proteus Framework

Forward Compatibility

Definition: the ability of an SDK to ensure that plugins written in version n continue work without recompilation in version n+1

As the architect of a plugin-driven application, how do you guarantee forward compatibility when the plugin consumer has imported your interfaces into their binaries?

Page 4: Proteus Framework

What’s wrong with OSGi?

In a word: nothing However, it may not be the right framework for

your application. Why pick Struts over Spring? Why use Spring over pure EJB? Advocates of each of these frameworks can quickly enumerate why they felt (or chose) one framework over the other.

One framework doesn't solve every problem

Page 5: Proteus Framework

OSGi vs Proteus

Both embody the notion of SOA in a Virtual Machine Modularity is at the core of both designs Plugins (or Bundles, in OSGi parlance) are published, found by a

consumer dynamically at runtime, and bound in order to issue service invocation requests

OSGi relies on the MANIFEST.MF metadata to publish (export) its plugins (bundles)

Proteus relies on compiled code, Plugin Archetypes that define a class of service, and core Java SE’s Service Provider Interface (SPI) architecture

Page 6: Proteus Framework

Runtime vs Compile Time

OSGi relies on "proprietary” MANIFEST.MF metadata to wire up services Googling shows just how hard time consuming it can be to

wire up existing libraries into OSGi Inherent class loader problems come along for free

Proteus adopts the standardized Java Service Provider Interface (SPI) architecture built-in to Java SE No wiring beyond declaring the factory in META-INF/services Not designed to solve the “2 versions of the same library”

problem

Page 7: Proteus Framework

Comparing Coding Styles

OSGiString serviceName = Service.class.getName();ServiceReference ref = ctx.getServiceReference(serviceName); Service svc = (Service) ctx.getService(ref));svc.callSomeMethod();

ProteusINamespace ns = new Namespace(“com.foo”, “Bar”);IPluginRegistrar pluginRegistrar = delegate.getPluginRegistrar(ns);MyService svc = pluginRegistrar.createPlugin(new Version(1), MyService.class);svc.callSomeMethod();

Page 8: Proteus Framework

Breaking Dependencies

Instead of the plugin consumer directly importing the plugins actual interface, the plugin consumer needs to import a proxy that represents a specific version of a plugin interface. Java includes native support for dynamic proxy objects!

Plugin consumer achieves compile type type checking, but they do so by compiling against a specific version of a proxy interface instead of the actual physical interface used by the actual plugin Look at the last slide again- notice the explicit version request of

a proxy interface, 1.0 of MyService.

Page 9: Proteus Framework

GoF Interface Development

Develop against an interface, not an implementation

Proteus, like OSGi, forces the developer to embrace this fundamental tenant of object oriented development

Plugin Archetype is a physical construct that drives interface over implementation development at the plugin level Comprised of a namespace and a set of versioned interfaces Typically deployed in a single .jar file Plugin Archetype = Category of Plugin

Page 10: Proteus Framework

Versions: First Class Citizens

Semantic Versioning http://semver.org Major.Minor.Patch Versions must increase over time

Minor version may include new, backwards compatible functionality 1.0 is forward compatible with 1.1 1.1 is not backward compatible with 1.0

Patch level is never considered when determining version compatibility Patches must not introduce new functionality, only bug fixes!

All Proteus plugin access includes an explicit version reference

Page 11: Proteus Framework

Triple-Bonded Factory Design

Proteus Factory Registrar is the master registrar that manages one or more Plugin Archetypes

Each Plugin Archetype maintains its own Plugin Registrar that manages one or more concrete implementations of the archetype.

The Plugin Registrar is a factory that can create instances of a specific version and/or instance of the plugin archetypeProteus Factory Registrar Plugin Registrar Plugin

Instance

Page 12: Proteus Framework

Proteus Factory Registrar

Entry point into the Proteus plugin architecture Registrar is solely responsible for being the

authoritative registrar for all known Plugin Archetypes

Access to the Proteus Factory Registrar is implicit through an injected delegate:

IPluginRegistrar pluginRegistrar = delegate.getPluginRegistrar(NAMESPACE);

Page 13: Proteus Framework

a priori Archetype Knowledge

Applications must have a priori knowledge of the plugin archetypes they intend to support

Application is designed against a specific archetype interface version Remember, archetype is defined by a namespace and version

Java SE Service Provider Interface ServiceLoader architecture used to dynamically locate and enumerate plugin archetypes instances Archetypes are declared in the .jar manifest according to Java SE by

defining their fully qualified class within a text file defined by Java SE SPI architeture:

META-INF/services/org.proteusframework.spi.ProteusRegistrarFactory

Page 14: Proteus Framework

Plugin Registrar

Plugin Registrar is the authoritative registrar for a specific Plugin Archetype.

Specific plugin instances can be be created by version

Proteus embraces Java GenericsVersion ver = new Version(1);MyInterface plugin =

pluginRegistrar.createPlugin(ver, MyInterface.class);

Page 15: Proteus Framework

Dynamic Plugin Discovery

Plugin Archetypes require a priori knowledge programmed into the application

Concrete instances of a plugin archetype have no such requirement; discovered dynamically by Java SE by searching the CLASSPATH for .jar manifest entries

META-INF/services/org.proteusframework.pluigin.spi.MyPlugin

Page 16: Proteus Framework

Plugin Architecture Review

The Proteus Factory Registrar manages a collection of Plugin Archetypes

A Plugin Archetype Registrar Factory creates a singular Plugin Registrar

A Plugin Registrar manages a collection of homogenous Plugin Instances

A Plugin Instance provides a specific configurable concrete plugin

Page 17: Proteus Framework

Defining a Plugin Archetype

Page 18: Proteus Framework

Archetype Package Structure

Interfaces Defines one or more versions of a plugin’s interface

Registrar Plugin Archetype Registrar Factory that collects concrete instances of the

archetype and stands ready to instantiate specific plugin implementation versions SPI

Abstract plugin factory extended by concrete instances Plugin Archetype Registrar Factory delegates construction of the plugin instance

here META-INF/services

How a plugin archetype is declared within a Proteus Application

Page 19: Proteus Framework

Archetype Definition

By and large boilerplate code Anticipate implement a mvn plugin so that a plugin can

be created via mvn archetype:archetype command Decide on a namespace Implement one or more plugin interface versions Link the interfaces to semantic versions within the

VersionCollection

Page 20: Proteus Framework

Concrete Plugin Structure

Page 21: Proteus Framework

Plugin Factory Implementation

Page 22: Proteus Framework

Version Implementation

Proxy Interface unused by concrete plugin implementations Concrete plugin extends the actual version interface; the

plugin instance is explicitly dependent upon the Plugin Archetype .jar

public class Version1Impl extends AbstractStandardPlugin implements ISampleVersion1

Specific Version Each plugin is tied to a specific version explicitly be the

versioned interface it implements from the plugin archetype

Page 23: Proteus Framework

Bootstrap a Proteus Application

Create a main class that extends AbstractRuntimeEnginepublic class SampleApplication extends AbstractRuntimeEngine

Create an instance of either a StandardProteusApplication or ExtendedProteusApplication

IProteusApplication myApplication = new StandardProteusApplication();

Instantiate the runtime engine IRuntimeEngine myRuntimeEngine = new SampleApplication();

Page 24: Proteus Framework

Bootstrap a Proteus Application

Inject the runtime engine into the application myApplication.setRuntimeEngine(myRuntimeEngine);

Start the applicationmyApplication.startApplication();

Formally launch the application in the run() methodpublic void run() {runningFlag = true; ... }

Page 25: Proteus Framework

Application Configuration

Standard Proteus applications can easily separate out their configuration from the actual runtime implementation

Use of IConfigurationLoader provides an abstraction on IProteusApplication between configuration and storage Java SE deployment will differ from an Android

deployment

Page 26: Proteus Framework

Plugin Instantiation

Get version 1 interface from the default plugin provider Default can be defined during runtime engine

configuration (e.g. .properties file)

MyExpectedVersion1Interface example1 = pluginRegistrar.createPlugin(new Version(1),

MyExpectedVersion1Interface.class);

Page 27: Proteus Framework

Plugin Instantiation

Get version 1 interface from a specific concrete plugin

INamespace pluginNS = new Namespace(”com.foo", “FooRegistrar");IVersionDescriptor vd = new VersionDescriptor(pluginNS, new Version(1, 0));

MyVersion1Interface example2 = pluginRegistrar.createPlugin(vd, MyVersion1Interface.class);

Page 28: Proteus Framework

Application Shutdown

Resource cleanup requires that the engine be shutdown propertly Accomplished with a single call:

myApplication.stopApplication();

Page 29: Proteus Framework