tiny-plugz

Parent POM for all skuzzle GitHub Projects

License

License

GroupId

GroupId

de.skuzzle.tinyplugz
ArtifactId

ArtifactId

tiny-plugz-parent
Last Version

Last Version

0.3.0
Release Date

Release Date

Type

Type

pom
Description

Description

tiny-plugz
Parent POM for all skuzzle GitHub Projects

Download tiny-plugz-parent

How to add to project

<!-- https://jarcasting.com/artifacts/de.skuzzle.tinyplugz/tiny-plugz-parent/ -->
<dependency>
    <groupId>de.skuzzle.tinyplugz</groupId>
    <artifactId>tiny-plugz-parent</artifactId>
    <version>0.3.0</version>
    <type>pom</type>
</dependency>
// https://jarcasting.com/artifacts/de.skuzzle.tinyplugz/tiny-plugz-parent/
implementation 'de.skuzzle.tinyplugz:tiny-plugz-parent:0.3.0'
// https://jarcasting.com/artifacts/de.skuzzle.tinyplugz/tiny-plugz-parent/
implementation ("de.skuzzle.tinyplugz:tiny-plugz-parent:0.3.0")
'de.skuzzle.tinyplugz:tiny-plugz-parent:pom:0.3.0'
<dependency org="de.skuzzle.tinyplugz" name="tiny-plugz-parent" rev="0.3.0">
  <artifact name="tiny-plugz-parent" type="pom" />
</dependency>
@Grapes(
@Grab(group='de.skuzzle.tinyplugz', module='tiny-plugz-parent', version='0.3.0')
)
libraryDependencies += "de.skuzzle.tinyplugz" % "tiny-plugz-parent" % "0.3.0"
[de.skuzzle.tinyplugz/tiny-plugz-parent "0.3.0"]

Dependencies

compile (6)

Group / Artifact Type Version
junit : junit jar
org.mockito : mockito-all jar
org.powermock : powermock-core jar
org.powermock : powermock-module-junit4 jar
org.powermock : powermock-api-mockito jar
org.powermock : powermock-classloading-xstream jar

provided (1)

Group / Artifact Type Version
org.eclipse.jdt : org.eclipse.jdt.annotation jar 2.0.0

test (1)

Group / Artifact Type Version
org.slf4j : slf4j-simple jar 1.7.12

Project Modules

  • tiny-plugz
  • tiny-plugz-guice

Build Status Maven Central Coverage Status SonarQube

TinyPlugz

TinyPlugz is a very small (tiny!) library for building simple modular applications. It is built around the facilities provided by the java ServiceLoader and URLClassLoader classes.

Features:

  • Access code from jar files dynamically during runtime of your application.
  • Own ClassLoader implementation, allowing plugins to specify dependencies of their own.
  • Plugins provide features for other plugins or for the host application using java service provider interfaces (SPI).
  • Deploy time extensibility: The whole TinyPlugz implementation can be exchanged during deploy time of your application to provide additional features.
  • Web application integration.

Maven Dependency

TinyPlugz is available through maven central:

<dependency>
    <groupId>de.skuzzle.tinyplugz</groupId>
    <artifactId>tiny-plugz</artifactId>
    <version>0.3.0</version>
</dependency>

TinyPlugz guice extension:

<dependency>
    <groupId>de.skuzzle.tinyplugz</groupId>
    <artifactId>tiny-plugz-guice</artifactId>
    <version>0.3.0</version>
</dependency>

Documentation

JavaDoc is available here:

Usage

Before TinyPlugz can be used, it needs to be configured using the TinyPlugzConfigurator class. This class is responsible for deploying an application wide single instance of TinyPlugz which can then be accessed using the static TinyPlugz.getInstance() method.

In your host application (probably in its void main) write:

final Path pluginFolder = ...; // folder containing plugins to be loaded
TinyPlugzConfigurator.setup()
    .withPluings(source -> source.addAllPluginJars(pluginFolder))
    .deploy();

If you use TinyPlugz in a web application, you can use the TinyPlugzServletContextListener for deploying TinyPlugz.

Now you can access services provided by your plugins anywhere in your application:

Iterator<MyService> services = TinyPlugz.getInstance().getServices(MyService.class);

Services are then searched among all plugins and the host application using java's ServiceLoader class.

Logging

TinyPlugz only has a single dependency on a 3rd party library. It uses slf4j as logging abstraction to support multiple logging frameworks if desired.

Extension

As mentioned above, the whole TinyPlugz behavior can be exchanged during deploy time of your application. This is achieved by loading the TinyPlugz implementation itself using the ServiceLoader: if the configurator class finds a service providing an instance of TinyPlugz it will use just that instance. Otherwise, the default implementation will be used.

The tiny-plugz-guice extension takes advantage of this features to provide a plugin system with supporting dependency injection: while deploying, it pulls implementations of Guice modules from plugins using the ServiceLoader and then implements the TinyPlugz interface using a Guice Injector.

Internals

Classloading

There are several ClassLoaders involved with plugin loading which follow a strict delegation model to separate dependencies of different plugins.

  • The PluginClassLoader extends java's own URLClassLoader and is responsible for loading classes from a single plugin.
  • The PluginClassLoader has a child URLClassLoader which is responsible for loading dependent classes that are specified in the plugin's manifest file.
  • The DelegateClassLoader connects all plugins with each other and thus allows plugins and the application to access classes from other plugins. This is the loader returned by TinyPlugz.getPluginClassLoader().

The parent ClassLoader of every ClassLoader mentioned above is the application's ClassLoader that has been specified in the setup phase (TinyPlugzConfigurator.setup...). This delegation model has the following implications:

  1. Classes of plugins can access classes of other plugins.
  2. Classes of plugins can access classes of the application.
  3. Classes of plugins can access classes of their own dependencies.
  4. Classes of plugin dependencies can access classes of the application.
  5. Classes of plugin dependencies can access classes of other dependencies of the same plugin.
  6. Classes of the application can access classes of plugins using the TinyPlugz interface.

To seperate the concerns of single plugins, here is a list of relations that are not possible:

  1. Classes of plugins can not access classes of other plugin's dependencies.
  2. Classes of the application can not access classes from any plugin's dependencies.
  3. Classes of a plugin's dependency can not access classes of that, or any other plugin.

Plugin HowTo

A TinyPlugz plugin is no more than a single jar file containing custom code to extend your application. In order for your application to be extendable, it should specify interfaces that can be implemented as services by your plugins.

Plugin Manifest

For full compatibility your plugins should specify a META-INF/MANIFEST.mf file, which at least contains the Implementation-Title attribute to specify the plugin's name. Additionally, if it specifies the Class-Path attribute, then the given entries are treated as relative paths to the plugin's own location and classes from the listed dependencies will be visible to the plugin during execution.

Versions

Version
0.3.0
0.2.0
0.1.0