Deploying Jersey in an openfire plugin

Hello community,

I have a plugin with functionality that I wish to expose through a REST api. I have chosen to try Jersey which I have successfully used in other Servlet containers such as Jetty. I am adding the necessary configuracion for Jersey in the web-custom.xml file of my plugin (which normally goes in the web.xml file of a webapp). Here it is as follows:

Jersey REST Service

com.sun.jersey.spi.container.servlet.ServletContainer

com.sun.jersey.config.property.packages

myproject.openfire.rest

1

Jersey REST Service

/rest/*

The problem is that openfire doesn’t seem to find/load the Jersey classes, and thus I get the following error:

INFO: Scanning for root resource and provider classes in the Web app resource paths:

/WEB-INF/lib

/WEB-INF/classes

2010.06.09 16:44:58 [org.jivesoftware.openfire.container.PluginServlet.registerServlets(PluginServl et.java:168)

]

com.sun.jersey.spi.service.ServiceConfigurationError: com.sun.jersey.spi.container.WebApplicationProvider: The class com.sun.jersey.server.impl.container.WebApplicationProviderImpl implementing the provider interface com.sun.jersey.spi.container.WebApplicationProvider is not found. The provider implementation is ignored…

I can solve this by placing the Jersey jar files in the openfire/lib folder (instead of in myplugin/lib), but that’s really messy. Moreover, even after that it still cannot find my REST resources classes, and I get this error:

“SEVERE: The ResourceConfig instance does not contain any root resource classes.”

2010.06.09 16:48:03 [java.util.logging.Logger.log(Logger.java:458)

] The ResourceConfig instance does not contain any root resource classes.

2010.06.09 16:48:03 [org.jivesoftware.openfire.container.PluginServlet.registerServlets(PluginServl et.java:168)

]

com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.

at com.sun.jersey.server.impl.application.WebApplicationImpl.processRootResources( WebApplicationImpl.java:1070)

at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicati onImpl.java:918)

at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicati onImpl.java:589)

at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer .java:429)

The package I specified in the param-value field in the web-custom.xml is the correct one, and as I said, the above configuration works just fine on Jetty or Tomcat.

Any help would be highly, highly appreciated!

Many thanks,

Diana.

I have developed a Rest Web Service based on Jersey. I have tested it out on Tomcat.

I do intend to integrate this service into Openfire as a plugin. I am interested im knowing what steps you took to getting this to work

inside Openfire. I have read up about how to develop a plugin for Openfire and I know what steps are involved, and I would like to help.

I think you may have not have the right versions of jars and their dependencies. Let me know what your application looks like and

we can try to figure out to how to get your plugin working.

Hello,

I making extension of fastpath plugin and need REST Service for it. I had same problems as you discribe.

I spent for this one full day , and at the end solve it. Probably this is not best solution, but for me it works fine.

First of all i want mention that servlets which you define at *web-custom.xml *is not loading in usual way because it is a plugin servlets. They loading by *org.jivesoftware.openfire.container.PluginServlet ,*by registerServlets method. This method parsing of plugin web-custom.xml file, but it processing just servlet classes and url pattern of it and not reading any aditional servlet init-param. As we know to define Jersey servlet we need to specefy packages to search REST resources.

So my solution:

  1. Create Jersey servlet wrapper class to define it at web-custom.xml instead of Jersey servlet.

package org.jivesoftware.openfire.fastpath.service

import org.jivesoftware.admin.AuthCheckFilter;

import com.sun.jersey.api.core.PackagesResourceConfig;
import com.sun.jersey.spi.container.servlet.ServletContainer;

_/**

  • Auto configured Jersey Servlet. All Resource classes should be at the same package or deeper.
  • @author Dmitriy Savascool
    */
    public class JerseyServletWrapper extends ServletContainer {
    private static final long serialVersionUID = 4882550115022577579L;_

_ public JerseyServletWrapper() {
super(new PackagesResourceConfig(JerseyServletWrapper.class.getPackage().getName()));
AuthCheckFilter.addExclude(“fastpath/rest/*”);
}_

}

  1. Define this servlet wrapper at *web-custom.xml *without any init params (they will not be parsed anyway)
  • FastpathStatusService org.jivesoftware.openfire.fastpath.service.JerseyServletWrapper< /servlet-class> *

_
FastpathStatusService
/rest/*
_

  1. And final:

(a) All REST resources classes should be placed at the same package with wrapper servlet or deeper.

(b) At Resource class path variable should starts from plugin name , later servlet url-pattern , and just at the end - path of the your resouce. In my case:

@Path("/fastpath/rest/status/")
public class StatusResource {

  •      ...*
    

I hope this will be useful to someone

There is also another variant. it is hardcoded , but if required - configuration params can be loaded from properties file.

public class JerseyServletWrapper extends ServletContainer {

private static final String SERVLET_URL = “fastpath/rest/*”;

private static final String SCAN_PACKAGE_KEY = “com.sun.jersey.config.property.packages”;

private static final String SCAN_PACKAGE_DEFAULT = JerseyServletWrapper.class.getPackage()

.getName();

private static final String RESOURCE_CONFIG_CLASS_KEY = “com.sun.jersey.config.property.resourceConfigClass”;

private static final String RESOURCE_CONFIG_CLASS = “com.sun.jersey.api.core.PackagesResourceConfig”;

private static Map<String, Object> config;

private static PackagesResourceConfig prc;

static{

config = new HashMap<String, Object>();

config.put(RESOURCE_CONFIG_CLASS_KEY, RESOURCE_CONFIG_CLASS);

config.put(SCAN_PACKAGE_KEY, SCAN_PACKAGE_DEFAULT);

prc = new PackagesResourceConfig(SCAN_PACKAGE_DEFAULT);

prc.setPropertiesAndFeatures(config);

prc.getClasses().add(StatusResource.class);

}

public JerseyServletWrapper() {

super(prc);

}

@Override

public void init() throws ServletException {

super.init();

AuthCheckFilter.addExclude(SERVLET_URL);

}

@Override

public void destroy() {

super.destroy();

AuthCheckFilter.removeExclude(SERVLET_URL);

}

}

Previous sample of servlet wrapper works fine at eclipse during development and debug , but not works when run server using \bin\openfire.bat. This modification alow to run correctly

I am also making the same application . Can someone please help .

I use Jersey in MUC Service Plugin. You can see here, how it was implemented:

https://github.com/igniterealtime/Openfire/blob/master/src/plugins/mucservice/sr c/java/org/jivesoftware/openfire/plugin/servlet/JerseyWrapper.java

Actually I have to implement a REST based web service that can accept XMPP messages from client and provide a response to them .

Do MUC service plugin suffice that requiremnt?

Thanks for your reply.

No, but you can figure out there, how you can integrate Jersey in your plugin.

Can you please suggest which OpenFire plugin i can use to achieve this functionality?

I’m not sure, but I guess Jitsi Videobridge Plugin have partly that. It use websockets.

ok thanks

What you have discussed in this url ?

I use 1.X version of Jersey and not the 2.X, because i had some issues that i could not solve.