Coder Social home page Coder Social logo

pf4j's Introduction

Plugin Framework for Java (PF4J)

Join the chat at https://gitter.im/decebals/pf4j GitHub Actions Status Coverage Maven Central

A plugin is a way for a third party to extend the functionality of an application. A plugin implements extension points declared by application or other plugins. Also, a plugin can define extension points.

NOTE: Starting with version 0.9 you can define an extension directly in the application jar (you're not obligated to put the extension in a plugin - you can see this extension as a default/system extension). See WhazzupGreeting for a real example.

Features/Benefits

With PF4J you can easily transform a monolithic java application in a modular application.
PF4J is an open source (Apache license) lightweight (around 100 KB) plugin framework for java, with minimal dependencies (only slf4j-api) and very extensible (see PluginDescriptorFinder and ExtensionFinder).

Practically, PF4J is a microframework that aims to keep the core simple but extensible. We also have a community-driven ecosystem of extensions. For now are available these extensions:

No XML, only Java.

You can mark any interface or abstract class as an extension point (with marker interface ExtensionPoint) and you specified that an class is an extension with @Extension annotation.

Components

  • Plugin is the base class for all plugins types. Each plugin is loaded into a separate class loader to avoid conflicts.
  • PluginManager is used for all aspects of plugins management (loading, starting, stopping). You can use a built-in implementation as JarPluginManager, ZipPluginManager, DefaultPluginManager (it's a JarPluginManager + ZipPluginManager) or you can implement a custom plugin manager starting from AbstractPluginManager (implement only factory methods).
  • PluginLoader loads all information (classes) needed by a plugin.
  • ExtensionPoint is a point in the application where custom code can be invoked. It's a java interface marker.
    Any java interface or abstract class can be marked as an extension point (implements ExtensionPoint interface).
  • Extension is an implementation of an extension point. It's a java annotation on a class.

PLUGIN = a container for EXTENSION POINTS and EXTENSIONS + lifecycle methods (start, stop, delete)

A PLUGIN is similar with a MODULE from other systems. If you don't need lifecycle methods (hook methods for start, stop, delete) you are not forced to supply a plugin class (the PluginClass property from the plugin descriptor is optional). You only need to supply some description of plugin (id, version, author, ...) for a good tracking (your application wants to know who supplied the extensions or extensions points).

How to use

It's very simple to add pf4j in your application.

Define an extension point in your application/plugin using ExtensionPoint interface marker:

public interface Greeting extends ExtensionPoint {

    String getGreeting();

}

Create an extension using @Extension annotation:

@Extension
public class WelcomeGreeting implements Greeting {

    public String getGreeting() {
        return "Welcome";
    }

}

Create (it's optional) a Plugin class if you are interested in plugin's lifecycle events (start, stop, ...):

public class WelcomePlugin extends Plugin {

    @Override
    public void start() {
        System.out.println("WelcomePlugin.start()");
    }

    @Override
    public void stop() {
        System.out.println("WelcomePlugin.stop()");
    }
    
    @Override
    public void delete() {
        System.out.println("WelcomePlugin.delete()");
    }
    
}

In above code we've created a plugin (welcome) that comes with one extension for the Greeting extension point.

You can distribute your plugin as a jar file (the simple solution). In this case add the plugin's metadata in MANIFEST.MF file of jar:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: decebal
Build-Jdk: 1.6.0_17
Plugin-Class: org.pf4j.demo.welcome.WelcomePlugin
Plugin-Dependencies: x, y, z
Plugin-Id: welcome-plugin
Plugin-Provider: Decebal Suiu
Plugin-Version: 0.0.1

In the manifest above, we've described a plugin with the id of welcome-plugin (mandatory attribute). We've also defined a class org.pf4j.demo.welcome.WelcomePlugin (optional attribute), with version 0.0.1 (mandatory attribute) and with dependencies to plugins x, y, z (optional attribute).

Now you can play with plugins and extensions in your code:

public static void main(String[] args) {
    ...

    // create the plugin manager
    PluginManager pluginManager = new JarPluginManager(); // or "new ZipPluginManager() / new DefaultPluginManager()"
    
    // start and load all plugins of application
    pluginManager.loadPlugins();
    pluginManager.startPlugins();

    // retrieve all extensions for "Greeting" extension point
    List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
    for (Greeting greeting : greetings) {
        System.out.println(">>> " + greeting.getGreeting());
    }
    
    // stop and unload all plugins
    pluginManager.stopPlugins();
    pluginManager.unloadPlugins();
    
    ...
}

The output is:

>>> Welcome

PF4J is very customizable and comes with a lot of goodies. Please read the documentation to discover yourself the power of this library.

Documentation

Documentation is available on pf4j.org

Demo

Demo applications are available in demo folder

Quickstart (call to action)

  1. Read this file to have an overview about what this project does
  2. Read Getting started section of documentation to understand the basic concepts
  3. Read Quickstart section of documentation to create your first PF4J-based modular application

pf4j's People

Contributors

ajithalbus avatar asafbennatan avatar decebals avatar dmitry-timofeev avatar ecumene avatar ggsjyoon avatar gitblit avatar gunoh avatar harbulot avatar hazemkmammu avatar janhoy avatar johnniang avatar kkriske avatar ktdynamic avatar lightglitch avatar milgner avatar neel24 avatar nextreports avatar pinhead84 avatar rationalityfrontline avatar robfrank avatar rreich avatar shirishpandharikar avatar slovdahl avatar ssherwood avatar stixits avatar styurin avatar tylerhawkes avatar valkuc avatar wolframhaussig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pf4j's Issues

Failed tests

On mvn clean test I retrieved:

Failed tests:   testGetPluginArchives(ro.fortsoft.pf4j.DefaultPluginRepositoryTest): expected:<plugin-[2].zip> but was:<plugin-[1].zip>

PluginManager.disablePlugin -> UnsupportedOperationExeption

When trying to disable a plugin without having a "disabled.txt" file in the plugins directory, DefaultPluginStatusProvider::disablePlugin() fails with an Exception.

As far as I can tell this is due to thet FileUtils::readLines returns Collections.emptyList() in case the files doesn't exist and DefaultPluginStatusProvider assigns this to disabledPlugins.

I assume the same would be true for enablePlugin.

/Cheers
Torgny
(Btw, nice framework :))

Missing dependency in Maven Central

Problem

Using pf4j causes Failed to load class "org.slf4j.impl.StaticLoggerBinder" Error

Cause

The POM file in Maven Central is missing the slf4j-simple dependency

Workaround

Manually include slf4j-simple version 1.7.5 into your project.

Ignore .svn folder in the plugin directory

I have the plugins directory under a subversion repo, and the DefaultPluginManager.loadPlugins() detects the .svn folder as a Plugin, and it gives an error.

I've tried to extend the DefaultPluginManager or create my own PluginManager implementing the interface, but I cannot achieve it due to the restricted visibility of the base objects.

Would you agree in modifiying the DefaultPluginManager to ignore the .svn folder in the plugins folder? I think the .svn folder is a standard-de-facto, and it will not annoy anyone.

Unable to detect Extensions

I have followed the procedure outlined in the home page.

  1. I have one plugin that is dropped into the plugins folder as a ZIP file.
    When the EAR is deployed and starts up in Wildfly, I can see that the ZIP file is unzipped. The manifest seems to be correct, and the extensions.idx has the class name.
  2. PF4J is able to read the plugin, and records that one possible extension is found.
  3. However, when I try to getExtensions(), the error is that the type is not assignable from the extension Class.

Please let me know if you require any additional information to help me with this issue.

Thanks and Best Regards,
GPN

Advice for injecting into Plugins

I'm looking for advice for integrating Guice injection for Plugins and Extensions.

Here is my approach for Extension injection, which is working fine but you may have a better idea.

pf4j = new DefaultPluginManager(dir) {
  @Override
  protected ExtensionFinder createExtensionFinder() {
    DefaultExtensionFinder extensionFinder = new DefaultExtensionFinder(this) {
      @Override
      protected ExtensionFactory createExtensionFactory() {
        return new ExtensionFactory() {
          @Override
          public Object create(Class<?> extensionType) {
            logger.debug("Create instance for extension '{}'", extensionType.getName());
            try {
              return runtimeManager.getInjector().getInstance(extensionType);
            } catch (Exception e) {
              logger.error(e.getMessage(), e);
            }
            return null;
          }
        };
      }
    };
    addPluginStateListener(extensionFinder);
    return extensionFinder;
  }
};

Unfortunately, there is no easy way to instantiate/inject a Plugin without having to duplicate/rewrite large parts of pf4j. ๐Ÿ˜ฆ Or maybe I am missing something.

DefaultPluginManager.loadPluginDirectory->new PluginWrapper()->createPluginInstance()

Issue with Jersey

I have this code:

    public void start()
    {
        log.info("[Plugin] iris-rest plugin started!");

        Config cfg = new Config();
        Map<String, String> config = cfg.getConfig();

        try
        {
            ResourceConfig rc = new PackagesResourceConfig("ru.iris.restful");
            rc.getProperties().put("com.sun.jersey.spi.container.ContainerRequestFilters", "ru.iris.restful.AuthFilter");
            HttpServer server = HttpServerFactory.create("http://" + config.get("httpHost") + ":" + config.get("httpPort") + "/", rc);
            server.start();

        }
        catch (IllegalArgumentException | IOException e)
        {
            log.error(e.toString());
        }
    }

And POJO classes (example) in ru.iris.restful package:

@Path("/rest")
public class CommonREST
{

    @GET
    @Path("/recognized/{device}/{text}")
    @Consumes(MediaType.TEXT_PLAIN + ";charset=utf-8")
    public String cmd(@PathParam("text") String device, @PathParam("text") String text)
    {
        JsonMessaging messaging = new JsonMessaging(UUID.randomUUID());
        messaging.broadcast("event.speak.recognized", new SpeakRecognizedAdvertisement().set(text, 100, device));
        messaging.close();

        return ("{ status: \"sent\" }");
    }

    @GET
    @Path("/speak/say/{device}/{text}")
    @Consumes(MediaType.TEXT_PLAIN + ";charset=utf-8")
    public String speak(@PathParam("text") String device, @PathParam("text") String text)
    {
        JsonMessaging messaging = new JsonMessaging(UUID.randomUUID());
        messaging.broadcast("event.speak", new SpeakAdvertisement().set(text, 100, device));
        messaging.close();

        return ("{ status: \"sent\" }");
    }
}

In non-pf4j program it works well - jersey detect my POJO classes and run, but in pf4j i getting:

Sep 30, 2014 9:30:19 PM com.sun.jersey.server.impl.application.RootResourceUriRules <init>
SEVERE: The ResourceConfig instance does not contain any root resource classes.
Exception in thread "main" com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.

Jersey cannot find any POJO classes.

can not resolve method close in PluginClassLoader?

I try to compile this project with "mvn package"
and the result is:
"/Users/passionke/work/pf4j/pf4j/src/main/java/ro/fortsoft/pf4j/PluginClassLoader.java:[133,12] ๆ‰พไธๅˆฐ็ฌฆๅท
็ฌฆๅท๏ผš ๆ–นๆณ• close()
ไฝ็ฝฎ๏ผš ็ฑป ro.fortsoft.pf4j.PluginClassLoader"


by the way, I delete the parent tag in the pom.xml

ServiceLoader interoperability problem

I have my application working with ServiceLoader. I'm trying to cut over to PF4J and I'm not having any luck. I'm basing my assumptions on your "ServiceLoader interoperability" section where you state:

if you have a modular application based on java.util.ServiceLoader class you can replace entirely the ServiceLoader.load() calls from your application with PluginManager.getExtensions() and migrate smooth from ServiceLoader to PF4J.

Here is what I have. I have created a facade for my application to use when loading Service interfaces.

public interface ExtensionProvider
{
    <T> List<T> getExtensions(Class<T> type);
}

I have an implementation that uses ServiceLoader like this:

public class ServiceLoaderExtensionProvider implements ExtensionProvider
{
    @Override
    public <T> List<T> getExtensions(Class<T> type)
    {
        List<T> result = new ArrayList<>();
        ServiceLoader.load(type).forEach(extension -> result.add(extension));
        return result;
    }
}

Now I have written a PF4J implementation like this:

public class PF4JExtensionProvider implements ExtensionProvider
{
    private final PluginManager pluginManager;

    public PF4JExtensionProvider()
    {
        //I think this is just for annotation processing, which we are not using at the moment(the services files are already in META-INF/services)
        System.setProperty("pf4j.storageClassName", "ro.fortsoft.pf4j.processor.ServiceProviderExtensionStorage");

        pluginManager = new DefaultPluginManager();
        pluginManager.loadPlugins();
        pluginManager.startPlugins();
    }

    @Override
    public <T> List<T> getExtensions(Class<T> type)
    {
        return pluginManager.getExtensions(type);
    }
}

My ExtensionProvider is defined as a Spring bean. I was hoping to just change the implementation to my PF4JExtensionProvider but that didn't work. So then, I tried making all my Service interfaces extend the PF4J ExtensionPoint interface. Still no luck.

Any ideas or suggestions?

Thanks in advance!

Make plugin configuration folders more flexible

Support loading plugins from multiple folders.
Support plugin expand to a configured folder.

This allows to load plugins from program path (in program files in windows for example) but also from user profile folder for 3ยช party plugins, the expand folder should be also on a profile folder.

This permits to reset the installation by deleting the profile folder and also separate the plugin installations by user profile.

Fails to recognize external extensions

I have an issue with external plugins.
They all load but fails to get recognized as plugins extending the correct extension point.

I took the demo project and extended it with one more plugin that is loaded from a .zip file. But when I did this I always get this error:

DEBUG ro.fortsoft.pf4j.DefaultExtensionFinder - 'test.pf4j.main.Greeting' is not assignable from extension point 'test.pf4j.plugins.CheersPlugin$WelcomeGreeting'

The exact same code works if I just move it into the same jar file as the main program.

Interface:

public interface Greeting extends ExtensionPoint {
    public String getGreeting();
}

Plugin:

public class CheersPlugin extends Plugin {
    public CheersPlugin(PluginWrapper wrapper) {
        super(wrapper);
    }

    @Extension
    public static class WelcomeGreeting implements Greeting {
        @Override
        public String getGreeting() {
            return "Cheers from outside";
        }
    }
}

not find META-INF/extensions.idx

Exception in thread "main" java.lang.NullPointerException
at ro.fortsoft.pf4j.DefaultExtensionFinder.readPluginsIndexFiles(DefaultExtensionFinder.java:176)
at ro.fortsoft.pf4j.DefaultExtensionFinder.readIndexFiles(DefaultExtensionFinder.java:132)
at ro.fortsoft.pf4j.DefaultExtensionFinder.find(DefaultExtensionFinder.java:54)
at ro.fortsoft.pf4j.DefaultPluginManager.getExtensions(DefaultPluginManager.java:559)

Avoid unzipping of zipped plugin

Hi,

My plugin is deployed as a zip. It is being unzipped during runtime. Any way I can avoid that, to keep my plugin folder clean?

Regards

Create Extensionpoint in plugin and access that in a different one

Dear Developer,

I'm currently struggling with the following thing:

I have a plugin which creates some extension points for other plugins.
Now I want those other plugins to use those extension points and use those plugins then inside my project.

E.g.:

Plugin CommandProvider: Has a interface: public interface CommandExtension extends ExtensionPoint

Plugin TestPlugin: Has a plugin public class TestPlugin extends Plugin which has a class inside @Extension public static class TestExtension implements CommandExtension


Now I want to access every CommandExtension from my CommandProvider:

for (CommandExtension commandExtension : comandPluginWrapper.getPluginManager().getExtensions(CommandExtension.class)) {
                if (commandExtension.canCall(pluginId, event)) {
                    commandExtension.call(pluginId, event);
                }
            }

This however returns always 0 Command Extension Points.

The following test however says that the plugin has the proper extension point:

   public void processEvent(String pluginId, Event event) {
        PluginWrapper plugin = wrapper.getPluginManager().getPlugin("Test Service");

        for (String extension : plugin.getPluginManager().getExtensionClassNames(plugin.getPluginId())) {
            logger.debug("Found Extension " + extension);
            try {
                for (Class<?> clazz : plugin.getPluginClassLoader().loadClass(extension).getInterfaces()) {
                    logger.warn(clazz.getName());
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        logger.warn("Found Command Extension " + plugin.getPluginManager().getExtensions(CommandExtension.class).size() + " times");
        if (event instanceof GenericMessageChatToBotEvent || event instanceof GenericMessageBotToChatEvent) {
            for (CommandExtension commandExtension : plugin.getPluginManager().getExtensions(CommandExtension.class)) {
                if (commandExtension.canCall(pluginId, event)) {
                    commandExtension.call(pluginId, event);
                }
            }
        }
    }
}

This produces the following output:

GlobalCommandPlugin - Found Command Extension 0 times
GlobalCommandPlugin - Found Extension at.lyze.plugin.testPlugin.TestPlugin$TestExtension:
GlobalCommandPlugin - at.lyze.pluginApi.extensions.services.ServiceExtension
GlobalCommandPlugin - at.lyze.plugin.globalCommandPlugin.CommandExtension

Do I do something wrong here?

Feature request: Load plugins remotely

Has anyone started development on a PluginManager that supports remote plugins (e.g. from a URL or other mechanism)?

I'd like to have a repository of plugins which pf4j accesses to load plugins. Ideally, the plug-in repository exposes a REST API that the PluginManager can query to determine which plugins should be loaded.

If no development has started for this feature, I'm willing to contribute. I'd create a PluginManager that supports URL (e.g. java.net.URL-supported) specified plugins (e.g. from local configuration), and also a more complex PluginManager that interacts with a REST API to determine the plugins to load.

best practice: how plugin-A makes use of plugin-B?

Hi there,

I have to plugins. A and B.

The running plugin B provides stuff which A has to use. This stuff is configured&started by PluginB#start() ...

I already set the dependency in plugin.properties, but I'm not sure what is the preferred way to access B from A without creating a new instance of B.

Any hints?

DefaultPluginManager: pls. make "initialize()" overwriteable

Hi there,

I would like to overwrite DefaultPluginManager#initialize() to change the log-message it produces and add some custom stuff etc., but it's "private".

Please change...

Beside that, I really would welcome it to have more "protected" stuff in this class instead of "mostly private". The name _Default_PluginManager says it: It's a kind of default implementation that could be overwritten. But asking for each and every part of it to be changed to protected is boring...

I'm sure this can be applied to all "Default*" classes of pf4j ...

br,
Alex

using slf4j with plugins --> CL problems?!

Hey there,

My plugins use slf4j ... Of course, the main application also use slf4j.

The main application uses the "slf4j-jdk14" logger.

If my plugins not just contain slf4j-api, but also sld4f-jdk14, I get an kind of warning:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/......../.m2/repository/org/slf4j/slf4j-jdk14/1.7.12/slf4j-jdk14-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/......../logicplugin/target/lib/slf4j-jdk14-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.JDK14LoggerFactory]

Makes sense...(but applications works...) --> Having the jdk14-lib two times is confusing. So, If I exclude the slf4j-jdk14 from my plugin (but keep in main application), I get this (and applications does not work):

2015-10-03 11:47:20.700 SEVERE [main] ro.fortsoft.pf4j.DefaultPluginFactory.create: null
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at ro.fortsoft.pf4j.DefaultPluginFactory.create(DefaultPluginFactory.java:61)
    at ro.fortsoft.pf4j.PluginWrapper.getPlugin(PluginWrapper.java:63)
    at ro.fortsoft.pf4j.DefaultPluginManager.startPlugins(DefaultPluginManager.java:226)
    at de.root1.kad.KadMain.<init>(KadMain.java:45)
    at de.root1.kad.KadMain.main(KadMain.java:60)
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of ro/fortsoft/pf4j/PluginClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:335)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:283)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:304)
    at de.root1.kad.logicplugin.LogicPlugin.<init>(LogicPlugin.java:56)
    ... 9 more

Exception in thread "main" java.lang.NullPointerException
    at ro.fortsoft.pf4j.DefaultPluginManager.startPlugins(DefaultPluginManager.java:226)
    at de.root1.kad.KadMain.<init>(KadMain.java:45)
    at de.root1.kad.KadMain.main(KadMain.java:60)

Anyone else facing this issue?

I've not yet digged into the root-cause, but it seems that this is a classloader issue with pf4j plugin classloader?!

any ideas before I investige time to find the cause?

br,
Alex

weird code formatting

I've seen this already a long time ago. But as more I am working with the source, the more annoying it gets...

Just an example. There are moe of this, some more, some less strange ...

bildschirmfoto vom 2015-10-03 11 30 22

Seems that the lin indent is broken?
Some is "tab", some is "white space".

Netbeans f.i. converts all indentation to white spaces...

Can this be fixed? Otherwise it's hard to read the code. I could format it locally with NB, but this will change the code and make fetchign code changes from GH more irritating...

Unable to Invoke Spring Beans

Hi Team,

I have used yours Spring plugins with the PF4j. The thing is its working with the main apps, But its not working on the Plugins created on the Plugins.

Reason its looking into the plugin class loader which pf4j and but if its look into the Webclassloader then only I can have the spring context.

In the Main app I have

AnnotationConfigApplicationContext applicationBeanContext = new AnnotationConfigApplicationContext();
applicationBeanContext.register(ResponseRegistryBootInjector.class);
applicationBeanContext.refresh();
// this.applicationContext = applicationBeanContext;

In the client App we have

ApplicationContext context = (ApplicationContext) mspUiContextObj.getContextInfo("APPSKEY");
// Object obj = context.getBean(LoginFormListener.class);

While debug on the above last statement "context.getBean(LoginFormListener.class)", I saw that its taking from the pluginclassloader not from the Spring which is in my case Webclassloader.
Eg here it is from the pf4j pluginclassloader "@OverRide
public Class<?> loadClass(String className) throws ClassNotFoundException {
log.debug("Received request to load class '{}'", className);"

Please assist.

editorconfig

I installed the editor config plugin and just updated me a lot of files automatically.
This files are different in your master, do you want a pull request?

How do I make a plugin using maven without installing the whole example project?

Hello,
I am new to pf4j and maven, and I tried my bet to find out how the hell it works, but i could't find a simple way to make plugin. There is no example plugin structure and i built the demo project with intelliJ, but that didn't help. As I want to let my program users the freedom to code plugin, i would like to know a way to make it Without maven or gradle, because they are quite confusing if you are new to it.
Please help me, I am stuck...

java.nio.file.FileSystemAlreadyExistsException

I have the following method that I am using to invoke a specific extension from a specific plugin:

public DispatchServices invokeDispatcher(Plugin plugin, Extension extension) throws MissingResourceException{

        PluginInvoker invoker = (plugin1, extension1) -> {

            // Load the plugins
            File userPluginFile = new File(AppConfig.getInstance().getUserPluginDir(plugin1.getOwner().getId()));
            PluginManager pluginManager = new DefaultPluginManager(userPluginFile);
            pluginManager.loadPlugins();

            if (plugin1.getStatus().equals(Plugin.State.ACTIVE)) pluginManager.startPlugin(plugin1.getName());

            List<DispatchServices> extensions = pluginManager.getExtensions(DispatchServices.class);
            for (DispatchServices ext : extensions) {
                if (ext.getClass().getName().equals(extension1.getImplementation())) {
                    return ext;
                }
            }
            throw new MissingResourceException("Could not invoke plugin extension.", plugin1.getName(), extension1.getName());
        };

        return (DispatchServices) invoker.invoke(plugin, extension);
    }

The first time this method is called everything works perfectly. However, subsequent calls to the method generate the following exception:

Caused by: java.nio.file.FileSystemAlreadyExistsException: null
    at com.sun.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:113) ~[zipfs.jar:1.8.0]
    at java.nio.file.FileSystems.newFileSystem(FileSystems.java:326) ~[na:1.8.0]
    at java.nio.file.FileSystems.newFileSystem(FileSystems.java:276) ~[na:1.8.0]
    at ro.fortsoft.pf4j.ServiceProviderExtensionFinder.readClasspathStorages(ServiceProviderExtensionFinder.java:70) ~[pf4j-0.12.0.jar:0.12.0]
    at ro.fortsoft.pf4j.AbstractExtensionFinder.readStorages(AbstractExtensionFinder.java:123) ~[pf4j-0.12.0.jar:0.12.0]
    at ro.fortsoft.pf4j.AbstractExtensionFinder.getEntries(AbstractExtensionFinder.java:131) ~[pf4j-0.12.0.jar:0.12.0]
    at ro.fortsoft.pf4j.AbstractExtensionFinder.find(AbstractExtensionFinder.java:49) ~[pf4j-0.12.0.jar:0.12.0]
    at ro.fortsoft.pf4j.DefaultExtensionFinder.find(DefaultExtensionFinder.java:41) ~[pf4j-0.12.0.jar:0.12.0]
    at ro.fortsoft.pf4j.DefaultPluginManager.getExtensions(DefaultPluginManager.java:555) ~[pf4j-0.12.0.jar:0.12.0]
    at co.ff36.halo.core.plugin.invoker.LocalPluginInvoker.lambda$invokeDispatcher$3(LocalPluginInvoker.java:55) ~[classes/:na]
    at co.ff36.halo.core.plugin.invoker.LocalPluginInvoker$$Lambda$4/1765003256.invoke(Unknown Source) ~[na:na]
    at co.ff36.halo.core.plugin.invoker.LocalPluginInvoker.invokeDispatcher(LocalPluginInvoker.java:66) ~[classes/:na]
    at co.ff36.halo.core.resource.server.impl.DispatcherProtocolsServerResource.represent(DispatcherProtocolsServerResource.java:55) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0]
    at org.restlet.resource.ServerResource.doHandle(ServerResource.java:523) ~[org.restlet-2.3.6.jar:na]
    ... 51 common frames omitted

Unfortunately the stack is not overly useful in diagnosing the problem.

Spring @ComponentScan not picking up plugin's Spring components

When I install my plugin as a zip file in the plugins folder, my spring configurations inside my plugin aren't being instantiated. I know you have a Spring project and I have looked at it, but it appears that it creates a separate ApplicationContext for each plugin. The reason this won't work for me is because my plugin has Autowired components like the main DataSource for the application.

My ApplicationContext gets created via a ContextLoaderListener defined in the web.xml file. It looks like spring has done it's thing before the wicket Application.init method. I suppose I could create my ApplicationContext within my Application.init method instead of using a ContextLoaderListener but I'm not sure what other issues this might cause.

Have you faced this problem in the past? Can you provide me any guidance in how to make this work?

Thanks!

plugin manifest issues

As explained in another issue/post, I create my plugins not as ZIP but as a single jar containing all dependencies.

For that I use the following build-plugin with maven:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.5.5</version>

                <executions>
                    <execution>
                        <id>make-plugin-assembly</id>
                        <!-- extend phase package to assembly the archives -->
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <archive>
                                <manifestEntries>
                                    <Plugin-Id>${plugin.id}</Plugin-Id>
                                    <Plugin-Class>${plugin.class}</Plugin-Class>
                                    <Plugin-Version>${plugin.version}</Plugin-Version>
                                    <Plugin-Provider>${plugin.provider}</Plugin-Provider>
                                    <Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
                                </manifestEntries>
                            </archive>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                            <finalName>${project.build.finalName}.plugin</finalName>
                            <appendAssemblyId>false</appendAssemblyId>
                        </configuration>
                    </execution>
                </executions>
            </plugin>   

Works quite well. Now I wanted to have the plugin-properties not in pom.xml

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>

        <plugin.id>de.root1.kad-logicplugin</plugin.id>
        <plugin.class>de.root1.kad.logicplugin.LogicPlugin</plugin.class>
        <plugin.version>1.0.0</plugin.version>
        <plugin.provider>Alexander Christian</plugin.provider>
        <plugin.dependencies></plugin.dependencies>        
    </properties>

but in an external plugin.properties file (makes life easier when using development-runtimemode). To not need to define plugin-properties twice (pom + properties), I used the following maven-build-plugin to read it from properties-file and use it in pom:

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>properties-maven-plugin</artifactId>
                <version>1.0-alpha-2</version>
                <executions>
                    <execution>
                        <id>read-plugin-properties</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>read-project-properties</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <files>
                        <file>${basedir}/plugin.properties</file>
                    </files>
                </configuration>
            </plugin>

Works in principle, but creates an name-conflict... It tooks me 2hrs to find the root-cause:

The pom variable ${plugin.id} is not only used by pf4j/it's plugin-configuration, but also by the maven assembly plugin... BUT: This only get's visible when reading the properties from properties-file. As long as you define the properties directly in pom.xml, ${plugin.id} will have the value we defined by outselves, don't matter where in the pom-file you use it.
If the property is read from propert-file (not direclty defined in pom), ${plugin.id} will contain the plugin-id of the build-plugin you're currenty configuring. In this case, it is "org.apache.maven.plugins:maven-assembly-plugin:2.5.5".

And it's getting further:

With ${plugin.class} you get an exception when running maven build:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.5.5:single (make-plugin-assembly) on project logicplugin: A type incompatibility occured while executing org.apache.maven.plugins:maven-assembly-plugin:2.5.5:single: java.lang.Class cannot be cast to java.lang.String

So ${plugin.class} at this point is not containing the plugin-class-string, but the plugin class object...

Maybe this is a kind of special case, as most users will not do that "advanced stuff" that I do.
But I recommend anyway to not use conflicting names.
Maybe prefix all the plugin-property-names with "pf4j." ....

I tried to overcome this issue with having my own manifestPluginDescriptorFinder... But again, some "private" tags prevent me from doing this... :-(

The ManifestPluginDescriptorFinder itself can be overwritten, but it depends on the Plugindescriptor, which has the "setXYZ()" methods package-private :-(

I would overcome also this by overwriting it and having a large constructor instead of using all the package-private setter... But this would be more a hack than "good code".

So, finally, two things should change:

  1. prefix the plugin-properties with "pf4j."
  2. enable the user to have an own prefix by overwriting *PluginDescriptorFinder (which is in principle already possible) and enable access to PluginDescriptor to set (somehow) the required values (so that overwriting *PlugindescriptorFinder makes sense.

br,
Alex

Can't use ExtensionPoints from Plugins

Dear Developer,
I'm currently having a problem with your library.

Let's say we have a basic project with:

  • core
  • pluginApi
  • plugins/globalOptions
  • plugins/commandPlugin

Inside the "globalOptions" plugin I have this interface:

package at.lyze.plugin.globalOptions.extensionpoint;
import ro.fortsoft.pf4j.ExtensionPoint;

public interface OptionHandlerExtension extends ExtensionPoint {
    void getOptions();
}

And then I have a class in the same project which uses the interface:

package at.lyze.plugin.globalOptions;

public class GlobalOptions extends Plugin {
@Extension
    public static class GlobalOptionsExtension implements OptionHandlerExtension {
        @Override
        public void getOptions() { โ€ฆ }
    }
}

Now inside the other plugin "commandPlugin" I try to access all "OptionHandlerExtension" via

List<OptionHandlerExtension> optionHandlers = wrapper.getPluginManager().getExtensions(OptionHandlerExtension.class);

But this doesn't return anything.

A temporary solution would be to move the Interfaces into the "pluginApi" project but I want to have that interface in the "globalOption" plugin.

Is there any way I could do this?

Edit: If you want to take a look at the full example: http://bitbucket.lyze.at/projects/DAR/repos/darkowlbot/browse
(Gradle build order would be: clean, jar, plugin, compilePluginsAndCopy, core:run)

Release-Plan for 0.11.0?

Hi there,

Is there any release plan for 0.11.0?
My application currently depends on 0.11.0-SNAPSHOT and I'm interested when 0.11.0 will be released...

br,
Alex

JSF plugin or sample

It is not an issue or defect, but request.

Any plans to create a sample/plugin for JSF based web application(s).

Thread safety

Hi,
Noticed that there is nothing mentioned about thread safety in the readme. Became curious about this when viewing DefaultPluginManager that use plain ArrayList and HashMap internaly with not clear synchronize or lock pathern.

What would be the sugested way to use this library safely in a multithreaded enviroment?

-F

I made a IntelliJ project to easily make plugins. (ant based)

Hello!

In the last few days, trying to make plugins for this awesome library has been a lot of struggle, so since i planned to make a generic intelliJ project to easily make and test plugins with intelliJ, I thought I would give it to you and explain to you how to adapt it to your application. the project is avaliable to download here: https://mega.nz/#!4NtUDCwR!BZQbiernX8sAk-03mxKSyhlAPu2_v7tI0LLOYQYjLao
just unzip it an you will have a functional intelliJ project.

But wait, Some configurations have to be done

first, you will notice a build.xml in the project folder. In my application, it necessitates a specific path to know where to put the plugin once it is packaged. To do so, you can either write it entirely instead of this:

<target name="package" depends="compile">
        <zip destfile="${plugin.path}/${plugin.id}-${plugin.version}.zip" basedir="out"/>
</target>

so it looks like this:

<target name="package" depends="compile">
        <zip destfile="Yourpath/zipname.zip" basedir="out"/>
</target>

or have this part modified:

<condition property="plugin.path" value="${user.home}/AppData/Roaming/rest of plugin path">
        <os family="windows"/>
    </condition>
    <condition property="plugin.path" value="${user.home}/Library/Application Support/rest of plugin path">
        <os family="unix"/>
    </condition>

into something like

<condition property="plugin.path" value="windows/path/to/your/plugin/folder">
        <os family="windows"/>
    </condition>
    <condition property="plugin.path" value="unix/path/to/your/plugin/folder">
        <os family="unix"/>
    </condition>

or if you do not care about os specificiality, just replace the condition lines as seen above by

<property name="plugin.path" value="Path/to/plugin/folder"/>

so that was the part for the output folder.
Now, there is something else to know:

the folder BaseLibs is there for the libraries that won't be included, put all libraries like pf4j, your applications library and the plugin dependencies in it.

the folder libs is the one that gets included for any additional 3rd party libraries used by your plugin, for instance an ASCII drawing api, cuz you like fancy ASCII art :)

Do not forget that intelliJ wont use them unless you specify them in file/project structure/libraries. Only referencing them there wont work either, they have to be in their corresponding libs folder and specified in intelliJ (for the autocompletion etc...).

Afterwards, you may want to modify the TestPlugin launch configuration, by telling him the path to your executable application jar, so you can instantly test you application by hitting the run button in IntelliJ.

Now just code your plugin in the src folder as you would normally do :)

That's all Folks :)

Hope it helps and don't hesitate and modify it as you want so you can give your users an easy tool to work with the plugins (instead of this bunch of maven code salad the lib author gave us ;) )

about a PF4J error

changed api and plugin's package name
type.isAssignableFrom(extensionClass) is false in DefaultExtensionFinder.java.

Pf4j with Nashorn Script Engine (JDK 8)

Hello, it's me again :)

Recently, I tried to use Nashorn Script Engine (JDK 8) within a plugin which is started by web application.

No mater what class loader I pass to ScriptEngineManagerscript can't get classes defined in the plugin project. Tried to pass PluginClassLoader, WebAppClassLoader (Tomcat app, parent of PluginClassLoader). I am not using SecurityManager.

For example: Plugin jar contains an abstract class - ABaseClass in package p.a.c.k.a.g.e. In plugin start method we create Nashorn engine as follows

    final ClassLoader scriptEngineClassLoader = **whatever way to get specific class loader**
    scriptEngineManager = new ScriptEngineManager(scriptEngineClassLoader);
    scriptEngine = scriptEngineManager.getEngineByName("nashorn");

Then we load and evaluate a Javascript file with content:

    var ScriptExtandable = Java.type("p.a.c.k.a.g.e.ABaseClass");
    var ScriptExtendedObj = new ScriptExtandable {
        onHi: function() {
            print("Hi from JS");
        }
    }

During evaluation script engine will throw RuntimeException - ClassNotFound("p.a.c.k.a.g.e.ABaseClass").

This works fine when pf4j is not used.

I wonder, had somebody already tried using Nashorn inside a plugin and had the same issue?
Or, maybe, somebody has any suggestions?

PluginWrapper usage

Hi,
In the demo application you have two kinds of plugins - external plugins located in plugin directory (WelcomePlugin) and default implementation located in the application jar (WhazzupGreeting).
I saw you added it not long ago and this is very good improvement.

The external plugins have a wrapper class that extends Plugin class and annotated with @extension while default implementation is only annotated with @extension.

What is the required behavior? Can I have external plugin that is only annotated with @extension without wrapper class?

Thanks for the help,
Elad Tamary

Unit Testing

We need to start having implementing this for the most important components. :)
Do you have some preferable approach?

Could You provider a demo of plugin.dependencies

for example:

  • plugin-person
    interface Person extends ExtensionPoint { ... }

    class PersonService {

        public List<Person> persons() {
            PluginManager pluginManager = ...;
            List<Person> persons = pluginManager.getExtensions(Person.class);
        }

    }
  • plugin-student, plugin.dependencies=plugin-person
    class Student implements Person { ... }
  • plugin-teacher, plugin.dependencies=plugin-person
    class Teacher implements Person { ... }

I'm trying this, but not success.

Thread safety in PluginClassLoader

Hi, we are starting to experiment with PF4J (thanks for the work by the way) and have come across a bug where the implementation of loadClass in PluginClassLoader is not thread safe. When we invoke it concurrently it tries to load the same class twice resulting in a LinkageError:

java.lang.LinkageError: loader (instance of ro/fortsoft/pf4j/PluginClassLoader): attempted duplicate class definition for name: "com/foo/MyExtension"
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.7.0_80]

I notice that java.lang.ClassLoader#loadClass is made thread safe with a per class name lock:

protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
...
}
}

PluginClassLoader overrides that method and so loses that synchronized block. I think the fix is as simple as adding in a synchronized block? The getClassLoadingLock method is protected and so available to PluginClassLoader.

For now we have synchronised access to DefaultPluginManager.

Spring several contexts and Spring Data Repositories

Hi, I am having a strange behaviour when using pf4j with spring.

My project structure is a web application org.home.server.communication (war) is deployed into Tomcat and uses SpringMVC. It loads loads a pf4j plugin - org.home.server.core (jar).
It works perfectly, until I try to use spring-data-mongodb in org.home.server.core (plugin project) and try to use MongoRepository/CrudRepository/Repository.

In the plugin constructor I do:

 super(wrapper);

 final AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext();
 appContext.setId("Core-Module-Context");
 appContext.setClassLoader(this.getClass().getClassLoader());
 appContext.getBeanFactory().setBeanClassLoader(this.getClass().getClassLoader());
 appContext.register(CoreRootConfig.class); //Stores MongoDB beans, repositories config..
 appContext.refresh();
 mApplicationContext = appContext;

But when I define any Repository and try to run the app, it crashes. Here is Repository example:

 public interface ConnectorRepository extends MongoRepository<Connector, String> {} 

Then plugin creation fails. It all works fine when I don't use pf4j, so I think this could be somehow related to pf4j. I am not sure exactly why it fails. And I hope, maybe, somebody already tried to use Spring-Data inside a plugin and had this problem.

I highlighted all exception messages to make it more readable. Maybe somebody could point me out where to look next?

Stack-trace and log:

D|DefaultListableBeanFactory              |Invoking afterPropertiesSet() on bean with name 'connectorRepository'
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.repository.core.support.AbstractRepositoryMetadata'
D|PluginClassLoader                       |Found class 'org.springframework.data.repository.core.support.AbstractRepositoryMetadata' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.repository.core.support.DefaultRepositoryMetadata'
D|PluginClassLoader                       |Found class 'org.springframework.data.repository.core.support.DefaultRepositoryMetadata' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.repository.core.support.AnnotationRepositoryMetadata'
D|PluginClassLoader                       |Found class 'org.springframework.data.repository.core.support.AnnotationRepositoryMetadata' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.repository.query.QueryLookupStrategy'
D|PluginClassLoader                       |Found class 'org.springframework.data.repository.query.QueryLookupStrategy' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.mongodb.repository.query.MongoEntityInformation'
D|PluginClassLoader                       |Found class 'org.springframework.data.mongodb.repository.query.MongoEntityInformation' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.repository.util.NullableWrapper'
D|PluginClassLoader                       |Found class 'org.springframework.data.repository.util.NullableWrapper' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryCollectingQueryCreationListener'
D|PluginClassLoader                       |Found class 'org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryCollectingQueryCreationListener' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.repository.core.CrudMethods'
D|PluginClassLoader                       |Found class 'org.springframework.data.repository.core.CrudMethods' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.core.GenericTypeResolver$TypeVariableMapVariableResolver'
D|PluginClassLoader                       |Found class 'org.springframework.core.GenericTypeResolver$TypeVariableMapVariableResolver' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.util.ParameterizedTypeInformation'
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.util.ParentTypeAwareTypeInformation'
D|PluginClassLoader                       |Found class 'org.springframework.data.util.ParentTypeAwareTypeInformation' in plugin classpath
D|PluginClassLoader                       |Found class 'org.springframework.data.util.ParameterizedTypeInformation' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.util.TypeVariableTypeInformation'
D|PluginClassLoader                       |Found class 'org.springframework.data.util.TypeVariableTypeInformation' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.repository.core.support.RepositoryFactorySupport$RepositoryInformationCacheKey'
D|PluginClassLoader                       |Found class 'org.springframework.data.repository.core.support.RepositoryFactorySupport$RepositoryInformationCacheKey' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.repository.core.support.DefaultRepositoryInformation'
D|PluginClassLoader                       |Found class 'org.springframework.data.repository.core.support.DefaultRepositoryInformation' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.querydsl.QueryDslUtils'
D|PluginClassLoader                       |Found class 'org.springframework.data.querydsl.QueryDslUtils' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'com.mysema.query.types.Predicate'
D|PluginClassLoader                       |Look in dependencies for class 'com.mysema.query.types.Predicate'
D|PluginClassLoader                       |Couldn't find class '{}' in plugin classpath. Delegating to parent
D|PluginClassLoader                       |Received request to load class 'com.mysema.query.types$Predicate'
D|PluginClassLoader                       |Look in dependencies for class 'com.mysema.query.types$Predicate'
D|PluginClassLoader                       |Couldn't find class '{}' in plugin classpath. Delegating to parent
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.mongodb.repository.support.SimpleMongoRepository'
D|PluginClassLoader                       |Found class 'org.springframework.data.mongodb.repository.support.SimpleMongoRepository' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.domain.Sort'
D|PluginClassLoader                       |Found class 'org.springframework.data.domain.Sort' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.domain.Pageable'
D|PluginClassLoader                       |Found class 'org.springframework.data.domain.Pageable' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.domain.Page'
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.domain.Slice'
D|PluginClassLoader                       |Found class 'org.springframework.data.domain.Slice' in plugin classpath
D|PluginClassLoader                       |Found class 'org.springframework.data.domain.Page' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'java.util.AbstractSet'
D|PluginClassLoader                       |Look in dependencies for class 'java.util.AbstractSet'
D|PluginClassLoader                       |Couldn't find class '{}' in plugin classpath. Delegating to parent
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity$MongoPersistentPropertyComparator'
D|PluginClassLoader                       |Found class 'org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity$MongoPersistentPropertyComparator' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.mapping.model.PreferredConstructorDiscoverer'
D|PluginClassLoader                       |Found class 'org.springframework.data.mapping.model.PreferredConstructorDiscoverer' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.util.ReflectionUtils'
D|PluginClassLoader                       |Found class 'org.springframework.data.util.ReflectionUtils' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.data.util.ReflectionUtils$DescribedFieldFilter'
D|PluginClassLoader                       |Found class 'org.springframework.data.util.ReflectionUtils$DescribedFieldFilter' in plugin classpath
D|PluginClassLoader                       |Received request to load class 'org.springframework.core.NestedExceptionUtils'
D|PluginClassLoader                       |Found class 'org.springframework.core.NestedExceptionUtils' in plugin classpath
D|DefaultListableBeanFactory              |Retrieved dependent beans for bean '(inner bean)#a303d13': [connectorRepository]
D|DefaultListableBeanFactory              |Retrieved dependent beans for bean '(inner bean)#72adbe38': [(inner bean)#a303d13]
D|DefaultListableBeanFactory              |Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@144f3ec6: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,coreRootConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor,org.home.server.core.module.config.CoreMongoDBConfig,mongo,mongoTemplate,org.springframework.data.mongodb.repository.config.MongoRepositoryConfigurationExtension#0,org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor#0,mongoMappingContext,connectorRepository]; root of factory hierarchy
D|DisposableBeanAdapter                   |Invoking destroy() on bean with name 'mongo'
D|PluginClassLoader                       |Received request to load class 'com.mongodb.ConcurrentLinkedDeque$CLDIterator'
D|PluginClassLoader                       |Found class 'com.mongodb.ConcurrentLinkedDeque$CLDIterator' in plugin classpath
D|DisposableBeanAdapter                   |Invoking destroy() on bean with name 'org.home.server.core.module.config.CoreMongoDBConfig'
D|DisposableBeanAdapter                   |Invoking destroy() on bean with name 'coreRootConfig'
E|DefaultExtensionFactory                 |null
<b>java.lang.reflect.InvocationTargetException: null </b>
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_20]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_20]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_20]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408) ~[na:1.8.0_20]
    at ro.fortsoft.pf4j.DefaultPluginFactory.create(DefaultPluginFactory.java:61) ~[DefaultPluginFactory.class:0.9.0]
    at ro.fortsoft.pf4j.PluginWrapper.getPlugin(PluginWrapper.java:63) [PluginWrapper.class:0.9.0]
    at ro.fortsoft.pf4j.DefaultPluginManager.startPlugins(DefaultPluginManager.java:213) [DefaultPluginManager.class:0.9.0]
    at org.home.server.communication.Starter.contextInitialized(Starter.java:86) [Starter.class:na]
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4758) [catalina.jar:8.0.9]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5184) [catalina.jar:8.0.9]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:8.0.9]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:724) [catalina.jar:8.0.9]
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:700) [catalina.jar:8.0.9]
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:714) [catalina.jar:8.0.9]
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1588) [catalina.jar:8.0.9]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_20]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_20]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_20]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_20]
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300) [tomcat-coyote.jar:8.0.9]
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) [na:1.8.0_20]
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) [na:1.8.0_20]
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:463) [catalina.jar:8.0.9]
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:413) [catalina.jar:8.0.9]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_20]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_20]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_20]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_20]
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300) [tomcat-coyote.jar:8.0.9]
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) [na:1.8.0_20]
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) [na:1.8.0_20]
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466) [na:1.8.0_20]
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) [na:1.8.0_20]
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307) [na:1.8.0_20]
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1399) [na:1.8.0_20]
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:828) [na:1.8.0_20]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_20]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_20]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_20]
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_20]
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323) [na:1.8.0_20]
    at sun.rmi.transport.Transport$1.run(Transport.java:178) [na:1.8.0_20]
    at sun.rmi.transport.Transport$1.run(Transport.java:175) [na:1.8.0_20]
    at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_20]
    at sun.rmi.transport.Transport.serviceCall(Transport.java:174) [na:1.8.0_20]
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:557) [na:1.8.0_20]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:812) [na:1.8.0_20]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:671) [na:1.8.0_20]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_20]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_20]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_20] <b>
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connectorRepository': Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError </b>
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553) ~ [AbstractAutowireCapableBeanFactory.class:4.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[AbstractAutowireCapableBeanFactory.class:4.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) ~[AbstractAutowireCapableBeanFactory.class:4.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) ~[AbstractBeanFactory$1.class:4.0.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[DefaultSingletonBeanRegistry.class:4.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) ~[AbstractBeanFactory.class:4.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) ~[AbstractBeanFactory.class:4.0.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:684) ~[DefaultListableBeanFactory.class:4.0.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760) ~[AbstractApplicationContext.class:4.0.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) ~[AbstractApplicationContext.class:4.0.6.RELEASE]
    at org.home.server.core.module.CoreModule.<init>(CoreModule.java:90) ~[na:na]
    at org.home.server.core.PluginStarter.<init>(PluginStarter.java:56) ~[na:na]
    ... 51 common frames omitted
<b>Caused by: java.lang.ExceptionInInitializerError: null
    at org.springframework.data.mapping.model.BasicPersistentEntity.<init>(BasicPersistentEntity.java:85) ~[na:na] </b>
    at org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity.<init>(BasicMongoPersistentEntity.java:67) ~[na:na]
    at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:89) ~[na:na]
    at org.springframework.data.mongodb.core.mapping.MongoMappingContext.createPersistentEntity(MongoMappingContext.java:37) ~[na:na]
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:280) ~[na:na]
    at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:181) ~[na:na]
    at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:141) ~[na:na]
    at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:67) ~[na:na]
    at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getEntityInformation(MongoRepositoryFactory.java:141) ~[na:na]
    at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory.getTargetRepository(MongoRepositoryFactory.java:83) ~[na:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:158) ~[na:na]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224) ~[na:na]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210) ~[na:na]
    at org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean.afterPropertiesSet(MongoRepositoryFactoryBean.java:108) ~[na:na]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612) ~[AbstractAutowireCapableBeanFactory.class:4.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549) ~[AbstractAutowireCapableBeanFactory.class:4.0.6.RELEASE]
    ... 62 common frames omitted
<b>Caused by: java.lang.ClassCastException: org.springframework.core.DefaultParameterNameDiscoverer cannot be cast to org.springframework.core.ParameterNameDiscoverer </b>
    at org.springframework.data.mapping.model.PreferredConstructorDiscoverer.<clinit>(PreferredConstructorDiscoverer.java:41) ~[na:na]
    ... 78 common frames omitted
I|Starter                                 |Context destruction has began.
I|AnnotationConfigWebApplicationContext   |Closing Root WebApplicationContext: startup date [Fri Sep 05 09:15:09 CEST 2014]; root of context hierarchy
D|DefaultListableBeanFactory              |Returning cached instance of singleton bean 'lifecycleProcessor'
D|DefaultListableBeanFactory              |Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1fbb2adf: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,rootConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor]; root of factory hierarchy

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.