Help with plugin development

Sorry if this is basic, I’m new to Openfire and Java. I was trying to get a development environment set up and use the rest api plugin, but am having trouble.

I was following along on these instructions and the example plugin worked, but not the rest api plugin https://gist.github.com/fabiomontefuscolo/42b144cc5803051281fc9a1be3286bf7.

I cloned the openfire github and checked out the 4.5.1 commit. Then in the openfire directory, I cloned the rest api plugin from github (renamed dir to “restapi”), and checked out the 1.4.0 commit. (I also tried this with the latest commits on both repos)

I ran mvn clean and mvn compile in the openfire directory, and the same in the rest api directory.

I ran the command:

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 \
	-Dlog4j.configurationFile=${WORKSPACE_FOLDER}/distribution/target/distribution-base/lib/log4j2.xml \
	-server \
	-DopenfireHome="${WORKSPACE_FOLDER}/distribution/target/distribution-base" \
	-DpluginDirs="${WORKSPACE_FOLDER}/restapi" \
	-Drestapi.classes="target/classes" \
	-Drestapi.webRoot="src/web" \
	-Dopenfire.lib.dir="${WORKSPACE_FOLDER}/distribution/target/distribution-base/lib" \
	-classpath "${WORKSPACE_FOLDER}/distribution/target/distribution-base/lib/startup.jar" \
	-jar "${WORKSPACE_FOLDER}/distribution/target/distribution-base/lib/startup.jar"

Openfire starts successfully and the rest plugin loads, but when I visit the rest api settings page http://localhost:9090/plugins/restapi/rest-api.jsp it is blank and there is an error in the the logs:

2020.03.10 22:24:09 org.apache.jasper.JspC - org.apache.jasper.JasperException: Unable to compile class for JSP:

An error occurred at line: [17] in the generated java file: [/Users/daraeman/Documents/openfire/restapi/classes/org/apache/jsp/devAI23.java]
Only a type can be imported. org.jivesoftware.openfire.plugin.rest.RESTServicePlugin resolves to a package

An error occurred at line: [36] in the jsp file: [/rest-api.jsp]
RESTServicePlugin cannot be resolved to a type
33:
34:     final PluginManager pluginManager = admin.getXMPPServer().getPluginManager();
35:
36:     RESTServicePlugin plugin = (RESTServicePlugin) XMPPServer.getInstance().getPluginManager()
37:             .getPlugin("restapi");
38:
39:     // Handle a save


An error occurred at line: [36] in the jsp file: [/rest-api.jsp]
RESTServicePlugin cannot be resolved to a type
33:
34:     final PluginManager pluginManager = admin.getXMPPServer().getPluginManager();
35:
36:     RESTServicePlugin plugin = (RESTServicePlugin) XMPPServer.getInstance().getPluginManager()
37:             .getPlugin("restapi");
38:
39:     // Handle a save


Stacktrace:

==> error.log <==
2020.03.10 22:24:09 org.jivesoftware.openfire.container.PluginServlet - Generation completed with [1] errors in [750] milliseconds
org.apache.tools.ant.BuildException: Generation completed with [1] errors in [750] milliseconds
	at org.apache.jasper.JspC.execute(JspC.java:1543) ~[apache-jsp-8.5.40.jar:8.5.40]
	at org.jivesoftware.openfire.container.PluginServlet.handleDevJSP(PluginServlet.java:638) ~[xmppserver-4.5.1.jar:4.5.1]
	at org.jivesoftware.openfire.container.PluginServlet.service(PluginServlet.java:126) [xmppserver-4.5.1.jar:4.5.1]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:873) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1623) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.jivesoftware.admin.PluginFilter.doFilter(PluginFilter.java:226) [xmppserver-4.5.1.jar:4.5.1]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.jivesoftware.admin.AuthCheckFilter.doFilter(AuthCheckFilter.java:234) [xmppserver-4.5.1.jar:4.5.1]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129) [sitemesh-2.4.2.jar:?]
	at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77) [sitemesh-2.4.2.jar:?]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.jivesoftware.util.LocaleFilter.doFilter(LocaleFilter.java:73) [xmppserver-4.5.1.jar:4.5.1]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.jivesoftware.util.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:49) [xmppserver-4.5.1.jar:4.5.1]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.jivesoftware.admin.PluginFilter.doFilter(PluginFilter.java:226) [xmppserver-4.5.1.jar:4.5.1]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.jivesoftware.admin.AuthCheckFilter.doFilter(AuthCheckFilter.java:234) [xmppserver-4.5.1.jar:4.5.1]
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1602) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:540) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) [jetty-security-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1700) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480) [jetty-servlet-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1667) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:152) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.Server.handle(Server.java:505) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:370) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:267) [jetty-server-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305) [jetty-io-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103) [jetty-io-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117) [jetty-io-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333) [jetty-util-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310) [jetty-util-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168) [jetty-util-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126) [jetty-util-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366) [jetty-util-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:698) [jetty-util-9.4.18.v20190429.jar:9.4.18.v20190429]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:804) [jetty-util-9.4.18.v20190429.jar:9.4.18.v20190429]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_181]

I tried to make sure everything is all correct, but just cannot seem to get it to work. Any thoughts on what I’m doing wrong?

The problem that your environment has, is that a JSP page contains a reference to a class (RESTServicePlugin) that it cannot find. I’m not sure if it is not in the plugin code, or if classloading is going wrong.

I have not used the method that you’re using to start Openfire and load a plugin development environment on the class. I don’t know if it works. Try compiling the plugin (mvn clean package), rename the restapi-openfire-assembly.jar file that will be in the target directory to restapi.jar, and upload that to Openfire.

If that has a different result, then you know that the approach in the tutorial that you followed has a flaw. If not, then the problem is probably in your code somewhere.

1 Like

Thanks for the help! Renaming the plugin and uploading worked.

I’m not sure why the other way was working for the example plugin, but not for the rest api plugin. Either way this gives me a good starting point. :+1:

1 Like