New feature for PluginClassloader

Openfire support plugins,Between multiple plugins and the plugin should interfere with each other and can run independently.

Like plugin a has resource a.jpg,plugin b can has same name a.jpg resource. should not conflict,My pr 300 and 342 ensure this.

Plugin did not need to consider the problem of resource conflicts.

Call the plugin as part of the server resources outside, it should not affect the server, such as ofmeet call the

ComponentManager componentManager = ComponentManagerFactory.getComponentManager(); to load plugin resource.

I have test all plugins, just hazelcast need serializer.jar and ofmeet call ComponentManager has issue.

Other plugins working fine.

@Tom Evans

@wroot

Here is my pr.

Call the plugin as part of the server resources outside, it should not affect the server, such as ofmeet call the

ComponentManager componentManager = ComponentManagerFactory.getComponentManager(); to load plugin resource.

I have test all plugins, just hazelcast need serializer.jar and ofmeet call ComponentManager has issue.

Other plugins working fine.

I am just noticing this. I need more information on how this PR has broken the ofmeet plugin.

In org.jitsi.videobridge.openfire.PluginImpl

ComponentManagerFactory will load class, and System.getProperty(“whack.componentManagerClass”); return null

String className = System.getProperty(“whack.componentManagerClass”);

if (className != null) {

try {

Class c = Class.forName(className);

componentManager = (ComponentManager)c.newInstance();

return componentManager;

}

catch (Exception e) {

e.printStackTrace();

}

}

And why ofmeet has slf4j too?

SLF4J: Class path contains multiple SLF4J bindings.

SLF4J: Found binding in [jar:file:/Users/jiangwei/Documents/git/Openfire/target/openfire/plugins/ofmeet /lib/slf4j-jdk14-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: Found binding in [jar:file:/Users/jiangwei/Documents/git/Openfire/build/lib/dist/slf4j-log4j12.j ar!/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]

java.lang.NullPointerException: No ComponentManager implementation available.

at org.xmpp.component.ComponentManagerFactory.getComponentManager(ComponentManager Factory.java:65)

at org.jitsi.videobridge.openfire.PluginImpl.initializePlugin(PluginImpl.java:188)

at org.jivesoftware.openfire.plugin.ofmeet.OfMeetPlugin.initializePlugin(OfMeetPlu gin.java:109)

at org.jivesoftware.openfire.container.PluginManager.loadPlugin(PluginManager.java :477)

at org.jivesoftware.openfire.container.PluginManager.access$300(PluginManager.java :76)

at org.jivesoftware.openfire.container.PluginManager$PluginMonitor.run(PluginManag er.java:1072)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)

at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301 (ScheduledThreadPoolExecutor.java:180)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Schedu ledThreadPoolExecutor.java:294)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

** ComponentManager componentManager = ComponentManagerFactory.getComponentManager(); is now broken. What is the solution???**

String className = System.getProperty(“whack.componentManagerClass”);

is for external components. Ofmeet is trying to create an internal component which should have called setComponentManager somewhere

/**

  • Sets the ComponentManager instance that will be used.
  • @param manager the ComponentManager instance.

*/

public static void setComponentManager(ComponentManager manager) {

componentManager = manager;

}

Ok. I found the issue with ComponentManagerFactory.getComponentManager(). It stops working in plugins that have whack.jar. This is new behavour in 3.11 and not sure of the origin. Could be the PR or something else. However, I have bigger issues as Jitsi videobridge has generated a few severe errors.

Looks like ofmeet is going to be stuck with 3.10 for a while.

ofmeet plugin version 0.2.3 by deleolajide · Pull Request #375 · igniterealtime/Openfire · GitHub

I have made an update to remove all redundant and duplicate jitsi videobridge jars like tinder, whack, slf4j. It works fine in 3.10, but there is still an issue with the Plugin class loader code.

2015.11.14 14:48:42 org.jivesoftware.openfire.container.PluginManager - Error loading plugin: C:\Projects\ignite\openfire-dele\target\openfire\plugins\ofmeet

java.lang.LinkageError: loader constraint violation: when resolving method “org.eclipse.jetty.servlet.ServletHolder.(Ljavax/servlet/Servlet;)V” the class loader** (instance of org/jivesoftware/openfire/container/PluginClassLoader) of the current class, org/jivesoftware/openfire/plugin/ofmeet/OfMeetPlugin, and the class loader (instance of org/jivesoftware/openfire/starter/JiveClassLoader) for the method’s defining class, org/eclipse/jetty/servlet/ServletHolder, have different Class objects for the type javax/servlet/Servlet** used in the signature

at org.jivesoftware.openfire.plugin.ofmeet.OfMeetPlugin.initializePlugin(OfMeetPlu gin.java:196)

I will revisit this later in the future when this PR gets sorted out

I suspect you should remove servlet-api-3.1.jar as well, and others like libidn.jar, dom4j.jar, xpp3.jar, because these are available through Openfire core.

Thanks for the tip @CSH, unfortunately, it is becoming more complicated than just removing the jar files. smack.jar has org.xmlpull.xxxxx embedded which is also available through Openfire core. In addition, I still have SEVERE errors coming out of Jitsi videobridge. I am not loving this PR at all

Many of the plugins I develop for a living are like the Jitsivideobridge plugin integrating Openfire with many other Java applications. I need the Plugin ClassLoader to be tolerant of duplicate classes as I can’t afford to repackage the container jar files for various reasons.

Hi @Dele Olajide,

I think if “the Plugin ClassLoader to be tolerant of duplicate classes” the different plugins we need to check the compatibility of each other.

I do not need to consider the compatibility modify PluginClassloader aim is to make the different between plug ins.

What do you think?

I appreciate that you are trying to improve compatibility and increase security between plugins, but a side effect of your change is that there is an issue between the Jive ClassLoader and the PluginClassLoader and this is causing problems for me in ofmeet plugin unless this was caused by another PR different from yours and which case, I apologise.

I am quite happy with the current behaviour of the plugin classLoader in OF 3.10.2. It provides enough isolation between plugins for me and when I want to reuse classes between plugins, I use the “parent” feature.

I develop openfire plugins for a living and have not seen any reason so far to change the current behaviour. This PR as it currently stands in OF 3.11 will generate me a lot of unwanted and undesired additional work and could force me to maintain my own fork of Openfire and compatible plugins going forward.

What is the compelling reason for this change?

I’m sorry for this,I will looking for a better way to do it.

Give me a few days.

@Dele Olajide can you provider smark version or source in ofmeet plugin?

Now I found this exception:

java.lang.LinkageError: loader constraint violation: when resolving method “org.jivesoftware.openfire.SessionPacketRouter.route(Lorg/dom4j/Element;)V” the class loader (instance of org/jivesoftware/openfire/container/PluginClassLoader) of the current class, org/jivesoftware/smack/XMPPConnection$OpenfirePacketWriter, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for resolved class, org/jivesoftware/openfire/SessionPacketRouter, have different Class objects for the type lement;)V used in the signature

at org.jivesoftware.smack.XMPPConnection$OpenfirePacketWriter.sendPacket(XMPPConnection.java:544)

at org.jivesoftware.smack.XMPPConnection.sendPacket(XMPPConnection.java:352)

at org.jivesoftware.smack.Roster.reload(Roster.java:192)

at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:225)

at org.jitsi.impl.protocol.xmpp.XmppProtocolProvider.register(XmppProtocolProvider.java:151)

at org.jitsi.jicofo.util.RegisterThread.run(RegisterThread.java:38)

But I can’t find class in witch jar file.

Hi wmz7year -

Thanks for your ongoing contributions. I appreciate your efforts to make Openfire better!

Note that plugins are designed to use the internal Openfire APIs and as such must be trusted to cooperate with other internal components (such as not shutting down the JVM, polluting the file system, etc.). If you prefer to have a more secure alternative for building extensions for Openfire, I suggest you consider the External Component API (via Whack). There are several helpful resources for writing external components, such as the following:

Component Developer Guide

Ignite Realtime: Whack API

Another public resource that might be helpful:

part 1 - http://oneminutedistraction.wordpress.com/2010/09/28/developing-xmpp-components- the-setup/

part 2 - http://oneminutedistraction.wordpress.com/2010/10/08/developing-xmpp-components- the-service-2/

part 3 - http://oneminutedistraction.wordpress.com/2010/10/20/developing-xmpp-components- some-tips/