Integrating Jersey (JAX-RS) with Openfire

Hi,

I want to create a plugin that allows access to some features of openfire by a RESTful webservice. I therefore tried to integrate jersey to openfire but did not suceed yet.

The PluginServlet allows the use of custom HttpServlets so I thought this is the right point to start from and as the jersey ServletContainer extends from the java HttpServlet but I have some issues with the url mapping.

This is what I have accomplished so far:

my web-custom.xml:

<?xml version='1.0' encoding='ISO-8859-1'?>

RESTServiceServlet

com.mypackage.RESTServiceServlet

jersey.config.server.provider.packages

com.mypackage

1

RESTServiceServlet

/restservice/*

for debugging purposes I extended the jersey ServletContainer to the RESTServiceServlet mentioned above:

@Override

public Value service(URI baseUri, URI requestUri, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

System.out.println("baseUri: " + baseUri);
System.out.println("requestUri: " + requestUri);
System.out.println("contextPath: " + request.getContextPath());
System.out.println("pathInfo: " + request.getPathInfo());
System.out.println(“translated: " + request.getPathTranslated());
System.out.println(“requestURI: " + request.getRequestURI());
System.out.println(“servletPath:” + request.getServletPath());
System.out.println(””);

return super.service(baseUri, requestUri, request, response);

}

I then added a simple pojo hello world class with

@Path(“hello”)

and then tried to open http://localhost:9090/plugins/restservice/restservice/hello

but I only get a 404 error. The debug output looks like this:

baseUri: http://localhost:9090/plugins/

requestUri: http://localhost:9090/plugins/restservice/restservice/hello

contextPath:

pathInfo: /restservice/restservice/hello

requestURI: /plugins/restservice/restservice/hello

servletPath:/plugins

I think the problem is the mapping but I dont know how to solve it, maybe the @Path is wrong or the mapping in the web-custom.xml?

Any help is appreciated, I’ve been trying for hours

Use the http-bind web service on 7070/7443 instead of the admin web service. See the fastpath webclient for an example on how to do this.

thanks for your reply.

I dont really understand how the fastpath webclient or the http-bind web service is actually helping me. I try to accomplish that i can for instance see the users in a multi user chat room by a http call, something like http://localhost:9090/plugins/restservice/restservice/muc/{roomid} that lists all the usernames… this seems not to be the intention of the fastpath webclient or am I missing something?

However, I found some other posts (http://community.igniterealtime.org/message/203902) regarding a RESTful webservice with jersey and I finally got it run so the method in my hello class is called (as I can see in the console). my setup is as follows:

  1. web-custom.xml
<?xml version='1.0' encoding='ISO-8859-1'?>

RESTServiceServlet

com.***.RESTServiceServlet

RESTServiceServlet

/restservice/*

  1. RESTServiceServlet class

public class RESTServiceServlet extends ServletContainer {

public RESTServiceServlet() {

super(new RESTServiceConfig());

}

@Override

public void init(ServletConfig config) throws ServletException {

super.init(config);

AuthCheckFilter.addExclude(“restservice/*”);

}

@Override

public void destroy() {

super.destroy();

AuthCheckFilter.removeExclude(“restservice/*”);

}

static public class RESTServiceConfig extends ResourceConfig {

public RESTServiceConfig() {

super(Hello.class);

}

}

}

  1. Hello class

@Path("/restservice/restservice/hello")

public class Hello {

// This method is called if TEXT_PLAIN is request

@GET

@Produces(MediaType.TEXT_PLAIN)

public String sayPlainTextHello() {

System.out.println(“sayPlainTextHello”);

return “Hello Jersey”;

}

// This method is called if XML is request

@GET

@Produces(MediaType.TEXT_XML)

public String sayXMLHello() {

System.out.println(“sayXMLHello”);

return “<?xml version=\"1.0\"?>” + " Hello Jersey" + “”;

}

// This method is called if HTML is request

@GET

@Produces(MediaType.TEXT_HTML)

public String sayHtmlHello() {

System.out.println(“sayHtmlHello”);

return “Hello”;

}

}

Maybe this is helpful for somebody else. The only problem I’m facing now is the following exception is shown when I open http://localhost:9090/plugins/restservice/restservice/hello The “???” belong to the page shown!

???

java.lang.NullPointerException

at org.jivesoftware.openfire.admin.decorators.main_jsp._jspService(main_jsp.java:1 95)

at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:547)

at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:480)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)

at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:520)

at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:22 7)

at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:94 1)

at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:409)

at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:186 )

at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:875 )

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)

at org.eclipse.jetty.server.Dispatcher.include(Dispatcher.java:195)

at com.opensymphony.module.sitemesh.filter.PageFilter.applyDecorator(PageFilter.ja va:156)

at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:59)

at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.ja va:1330)

at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:478)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)

at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:520)

at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:22 7)

at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:94 1)

at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:409)

at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:186 )

at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:875 )

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)

at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandler Collection.java:250)

at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.jav a:149)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)

at org.eclipse.jetty.server.Server.handle(Server.java:349)

at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:441)

at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConne ction.java:919)

at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:582)

at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:218)

at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:51 )

at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.jav a:586)

at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java :44)

at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:598 )

at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:533)

at java.lang.Thread.run(Thread.java:662)

Openfire plugins have a problem when declare servlets, you can’t set init-params in the web.xml, if you see the code of the open fire when the PluginServlet generate the other servlets you can see the following:

if (instance instanceof GenericServlet) {

// Initialize the servlet then add it to the map…

((GenericServlet)instance).init(servletConfig);

servlets.put(pluginName + url, (GenericServlet)instance);

}

As you can see, the servlet is initialized with the config of the plugin servlet, so you can’t put in your web-custom.xml the following information:

jersey.config.server.provider.packages

com.mypackage

Due to the package is never scanned so really you don’t have your services enabled.

At least I think that that is the problem, you can solved this issue configuring your jersey in the same way that this post:

or

I hope that helps.

Thank you so much Manuel!

The problem was not the use of some init params as I didn’t use them anyway (as you can see in the web-custom.xml I posted above) but your last link pointed me to the decorators.xml where I had do add my plugin-url to the pages that are not to be shown in the web admin console. This finally resolved my problem.