public abstract class TinyPlugz extends Object
ServiceLoader and
URLClassLoader classes. Before usage, TinyPlugz must be configured to
specify the plugins which should be loaded. After deploying, TinyPlugz can be
accessed like a singleton:
TinyPlugzConfigurator.setup()
.withProperty("key", value) // some TinyPlugz implementations might
// need additional properties
.withPlugins(source -> source.addAll(pluginFolder))
.deploy();
final Iterator<MyService> providers = TinyPlugz.getInstance()
.loadServices(MyService.class);
This is the preferred usage scenario. TinyPlugz will be configured to use the application's Classloader as parent Classloader. The immediate implication is that the host application does not see classes loaded from plugins but plugins see classes of the host application. The only way for the host application to access features of loaded plugins is to use the java service extension feature through the TinyPlugz API.
This method is preferred because it provides a single point of accessing
plugin functionality. However, low level access is still possible by using
the plugin Classloader directly.
In this scenario your whole application will be loaded by TinyPlugz, making
TinyPlugz the parent Classloader of your application. This is achieved by
TinyPlugz calling the main method of your application. This implies that your
application can natively access classes from loaded plugins and all loaded
plugins can access classes of your application's static class path. For this
scenario, your application needs two main methods: One which
initializes TinyPlugz and a "real" one which is then called by TinyPlugz in
the context of the correct Classloader:
// This is the entry point main method of your application
public static void main(String[] args) {
TinyPlugzConfigurator.setup()
.withProperty("key", value)
.withPlugins(source -> source.addAll(pluginFolder))
.deploy()
.runMain("com.your.domain.ClassWithRealMainMethod", args);
}
Please note that this method also replaces the context Classloader of the
main thread with TinyPlugz's plugin Classloader.
The TinyPlugz instance returned by getInstance() is
automatically determined by using java's ServiceLoader class. It will
look for an registered service provider for the type TinyPlugz and use the
first encountered provider. If no provider is found, the default
implementation will be used.
| Constructor and Description |
|---|
TinyPlugz() |
| Modifier and Type | Method and Description |
|---|---|
protected DelegateClassLoader |
createClassLoader(PluginSource source,
ClassLoader parent)
Creates a
ClassLoader which accesses the given collection of
plugins. |
protected void |
defaultDispose()
Default behavior for
dispose(): Calls close if the Classloader returned by getClassLoader() is an
instance of Closeable. |
protected <T> Optional<T> |
defaultGetFirstService(Class<T> type)
Default implementation for
getFirstService(Class) building upon
result of getServices(Class). |
protected Optional<URL> |
defaultGetResource(String name)
Default implementation for
getResource(String) building upon
result of getClassLoader(). |
protected ElementIterator<URL> |
defaultGetResources(String name)
Default implementation for
getResources(String) building upon
result of getClassLoader(). |
protected <T> T |
defaultGetService(Class<T> type)
Default implementation of
getService(Class) building upon result
of getServices(Class). |
protected void |
defaultRunMain(String className,
String[] args)
Default implementation for
runMain(String, String[]). |
protected abstract void |
dispose()
Called upon
undeploy to release resources. |
protected abstract Iterator<DeployListener> |
findDeployListeners(ClassLoader pluginClassLoader)
Looks up
DeployListener to be notified right after this instance
has been deployed by the TinyPlugzConfigurator class. |
abstract ClassLoader |
getClassLoader()
Returns the ClassLoader which can access classes from loaded plugins.
|
abstract <T> Optional<T> |
getFirstService(Class<T> type)
Loads services of the given type which are accessible from loaded plugins
and the host application by using java's
ServiceLoader
capabilities. |
static TinyPlugz |
getInstance()
Gets the single TinyPlugz instance.
|
abstract Collection<PluginInformation> |
getPluginInformation()
Gets a collection of information about all loaded plugins.
|
abstract Optional<URL> |
getResource(String name)
Searches for a resource with given name within loaded plugins and the
host application.
|
abstract ElementIterator<URL> |
getResources(String name)
Finds all the resources with the given name within loaded plugins and the
host application.
|
abstract <T> T |
getService(Class<T> type)
Loads services of the given type which are accessible from loaded plugins
and the host application by using java's
ServiceLoader
capabilities. |
abstract <T> ElementIterator<T> |
getServices(Class<T> type)
Loads all services of the given type which are accessible from loaded
plugins and the host application by using java's
ServiceLoader
capabilities. |
protected abstract void |
initialize(PluginSource source,
ClassLoader parentClassLoader,
Map<Object,Object> properties)
This method is called by the TinyPlugz runtime right after instantiation
of this instance.
|
static boolean |
isDeployed()
Checks whether TinyPlugz is currently deployed and is thus accessible
using
getInstance(). |
boolean |
isServiceAvailable(Class<?> service)
Checks whether there is at least one provider available for the given
service.
|
abstract void |
runMain(String className,
String[] args)
Executes a main method in the context of the plugin ClassLoader.
|
void |
undeploy()
|
public static TinyPlugz getInstance()
public static boolean isDeployed()
getInstance().TinyPlugz is deployed.public final void undeploy()
protected abstract void initialize(PluginSource source, ClassLoader parentClassLoader, Map<Object,Object> properties)
source - The plugins to load.parentClassLoader - The Classloader to use as parent for the plugin
Classloader.properties - Additional configuration parameters.TinyPlugzException - When initializing failed.protected abstract Iterator<DeployListener> findDeployListeners(ClassLoader pluginClassLoader)
DeployListener to be notified right after this instance
has been deployed by the TinyPlugzConfigurator class. The listeners are
retrieved querying Java's ServiceLoader for the service
DeployListener.class.pluginClassLoader - The ClassLoader for accessing services from plugins.protected abstract void dispose()
undeploy to release resources.protected final void defaultDispose()
dispose(): Calls close if the Classloader returned by getClassLoader() is an
instance of Closeable.public abstract void runMain(String className, String[] args)
className and then searches for a
public static void main(String[] args) method to execute.
Additionally, the plugin ClassLoader is set as context ClassLoader for
the current thread.
Using this method it is possible to use TinyPlugz as an execution container for the whole application, because all subsequently loaded classes will be loaded by a Classloader which has the plugin Classloader as parent.
className - Name of the class which contains the main method.args - Arguments to pass to the main method.TinyPlugzException - If loading the class or calling it's main
method fails.protected final void defaultRunMain(String className, String[] args)
runMain(String, String[]).className - Name of the class which contains the main method.args - Arguments to pass to the main method.TinyPlugzException - If loading the class or calling it's main
method fails.public abstract Collection<PluginInformation> getPluginInformation()
public abstract ClassLoader getClassLoader()
TinyPlugz class instead.protected final DelegateClassLoader createClassLoader(PluginSource source, ClassLoader parent)
ClassLoader which accesses the given collection of
plugins.source - The plugins.parent - The parent ClassLoader.public abstract Optional<URL> getResource(String name)
name - Name of the resource.protected final Optional<URL> defaultGetResource(String name)
getResource(String) building upon
result of getClassLoader().name - Name of the resource.public abstract ElementIterator<URL> getResources(String name) throws IOException
name - The name of the resource.IOException - If I/O errors occur.ElementIteratorprotected final ElementIterator<URL> defaultGetResources(String name) throws IOException
getResources(String) building upon
result of getClassLoader().name - The name of the resource.IOException - If I/O errors occur.public final boolean isServiceAvailable(Class<?> service)
getFirstService(service).isPresent().service - The service to check for.public abstract <T> ElementIterator<T> getServices(Class<T> type)
ServiceLoader
capabilities.T - The type of the service provider interface.type - Type of the service to load.public abstract <T> Optional<T> getFirstService(Class<T> type)
ServiceLoader
capabilities. This method only returns the first service or an empty
Optional if no provider for the requested service is found.T - The type of the service provider interface.type - Type of the service to load.protected final <T> Optional<T> defaultGetFirstService(Class<T> type)
getFirstService(Class) building upon
result of getServices(Class).T - The type of the service provider interface.type - Type of the service to load.public abstract <T> T getService(Class<T> type)
ServiceLoader
capabilities. This method expects that there exists a single provider for
the requested service. An exception will be thrown if no provider has
been found or if multiple providers have been found.T - The type of the service provider interface.type - Type of the service to load.IllegalStateException - If no provider or if more than one provider
of given type is available.protected final <T> T defaultGetService(Class<T> type)
getService(Class) building upon result
of getServices(Class).T - The type of the service provider interface.type - Type of the service to load.IllegalStateException - If no provider or if more than one provider
of given type is available.Copyright © 2014–2015. All rights reserved.