DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modern Digital Website Security: Prepare to face any form of malicious web activity and enable your sites to optimally serve your customers.

Containers Trend Report: Explore the current state of containers, containerization strategies, and modernizing architecture.

Low-Code Development: Learn the concepts of low code, features + use cases for professional devs, and the low-code implementation process.

E-Commerce Development Essentials: Considering starting or working on an e-commerce business? Learn how to create a backend that scales.

Related

  • The Anatomy of a Microservice, One Service, Multiple Servers
  • Breaking Up a Monolithic Database with Kong
  • Spring Microservices RESTFul API Documentation With Swagger Part 1
  • How to Develop Microservices With Spring Cloud and Netflix Discovery

Trending

  • Migrating Monolith Application to Microservices
  • How to Leverage Kubernetes' New CronJob API for Efficient Task Scheduling
  • Top 11 Project Management Hacks for Software Project Managers
  • Automate JBoss Web Server Deployment With the Red Hat Certified Content Collection for JWS
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Setting Up JAX-RS for Equinox OSGI

Setting Up JAX-RS for Equinox OSGI

Developing microservices and RESTful applications in Java? See how JAX-RS, OSGI, and the Equinox framework can help you master them.

Kees Pieters user avatar by
Kees Pieters
·
Aug. 11, 17 · Tutorial
Like (3)
Save
Tweet
Share
10.9K Views

Join the DZone community and get the full member experience.

Join For Free

After a somewhat busy period, I finally had some time to scratch a few things from my TO DO list, and one of them was to get acquainted with microservices, and most notably REST — in OSGI — with Equinox as my framework of choice. So far, I have made microservice-ish modules 'by hand' using servlets, but it is time to move on, and submit myself to the wonders of JAX-RS! As it turned out, it cost me about one-and-a-half days, in which most of my time was spent trying to figure out the best way to approach this. There are quite a few options:

  1. Apache CFX distributed OSGI
  2. Eclipse ECF with JAX-RS Providers
  3. JAXRS-OSGI Connector
  4. ... and others!

After a few hours of experimenting, I came to the conclusion that the first two options were a bit too convoluted for my modest requirements, so I opted for the third. The promise that the connector would scan bundles for JAX-RS annotated classes seemed enticing, but at the end of the day, I couldn't get the HelloWorld REST Service up and running, and nothing seemed to get registered. The connector did not seem to be actively maintained, so I feared that it was back to the drawing board for me. This was frustrating, as every online tutorial basically told me that all I needed was to simply register a dedicated servlet from a JAX-RS provider (e.g GlassFish) to an OSGI HTTP Service. How difficult can it be? In absence of any log messages, it was a matter of using my head.

It eventually dawned on me that my problems were probably classpath related, and with this, the big 'aha' I had been waiting for finally came: Equinox! The examples were (probably) all made with Apache Karaf, which do not suffer from the strict sandboxing of Equinox OSGI. I absolutely love this aspect of Equinox, but it does come with occasional headaches. Luckily, I didn't have to suffer a JAX-RS-OSGI migraine attack this time, mostly owing to this post in Stack Overflow. The answer from Balazs Zsoldos especially helped me get on the right track. This is probably the reason why the JAX-RS-OSGI connector didn't work as well. So, for those who want a straightforward approach to getting JAX-RS up and running in Equinox OSGI, I offer my solution.

A Recipe

So what did I do?

  1. Create an OSGI bundle with a REST resource (the ubiquitous HelloWorldService).
  2. Get it to work with the GlassFish implementation of Jersey 2.x.

Sounds easy enough... and it is, once you have figured out what needs to be done.

Get the required resources from the GlassFish Jersey website. We will need to add the following bundles to our target:

hk2-locator-2.5.0-b42.jar
javax.annotation-api-1.2.jar
javax.inject-1.jar
javax.inject-2.5.0-b42.jar
javax.ws.rs-api-2.1-m09.jar
jersey-client.jar
jersey-common.jar
jersey-container-servlet.jar
jersey-container-servlet-core.jar
jersey-hk2.jar
jersey-server.jar
jsr250-api-1.0.jar
osgi-resource-locator-1.0.1.jar


Create a new bundle in your workspace (assuming you are developing with the Eclipse IDE), and include your REST Resource (for instance, at paragraph 6.3 of Vogella's tutorial on the same subject) .

Add the following dependencies to your MANIFEST.MF file:

javax.servlet,
 javax.ws.rs,
 javax.ws.rs.core,
 org.condast.commons.http,
 org.condast.wph.core.definition,
 org.glassfish.jersey,
 org.glassfish.jersey.inject.hk2,
 org.glassfish.jersey.server,
 org.glassfish.jersey.servlet,
 org.osgi.framework,
 org.osgi.service.component.annotations


Create a ServletWrapper around the GlassFish ServletContainer. This ensures that your bundle will be added to CLASSPATH of the Jersey server:

import javax.servlet.Servlet;
import javax.ws.rs.ApplicationPath;

import org.foo.commons.http.AbstractServletWrapper;
import org.condast.wph.rest.resources.ControlResource;
import org.condast.wph.rest.resources.HelloResource;
import org.condast.wph.rest.resources.TerminalResource;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;

public class RestServlet extends AbstractServletWrapper {

    public static final String S_CONTEXT_PATH = "rest";

    public RestServlet() {
        super(S_CONTEXT_PATH);
    }

    @Override
    protected Servlet onCreateServlet(String contextPath) {
        RestApplication resourceConfig = new RestApplication();
        return new ServletContainer(resourceConfig);
    }

    @ApplicationPath(S_CONTEXT_PATH)
    private class RestApplication extends ResourceConfig {

        //Loading classes is the safest way...
        //in equinox the scanning of packages may not work
        private RestApplication() {
            register(HelloResource.class);
            register(TerminalResource.class);
            register(ControlResource.class);
        }
    }
}


The AbstractServletWrapper is a trivial implementation of the javax.servlet.Servlet interface and wraps the org.glassfish.jersey.servlet.ServletContainer that is created in
the onCreateServlet method.

  • Register the classes in the ResourceConfig (lines 25-35). All other options will fail because the Jersey server will not be able to scan them! Many tutorials will, for instance, demonstrate how the package name can be included, but this will not work. In Equinox, the Jersey server needs access to the actual classes!
  • Register the ServletWrapper as an HttpService. I opted to do this by means of the plugin extension framework (extension org.eclipse.eqiunox.http.registry), but this can of course also be done declaratively or programmatically. Remember to have the correct service up and running when launching your application!
  • Launch your application with at least the following bundles (if you are using Jetty):
  • javax.annotation-api;
    javax.servlet;
    javax.transaction;
    javax.ws.rs-api;
    org.apache.felix.gogo.command;
    org.apache.felix.gogo.runtime;
    org.apache.felix.gogo.shell;
    org.eclipse.equinox.console;
    org.eclipse.equinox.ds@1;
    org.eclipse.equinox.util;
    org.eclipse.osgi.services;
    org.eclipse.osgi;
    org.glassfish.hk2.external.javax.inject;
    org.glassfish.hk2.osgi-resource-locator;
    org.eclipse.equinox.http.jetty;
    org.eclipse.jetty.continuation;
    org.eclipse.jetty.http;
    org.eclipse.jetty.io;
    org.eclipse.jetty.security;
    org.eclipse.jetty.server;
    org.eclipse.jetty.servlet;
    org.eclipse.jetty.util;
    
    Note: Jetty starts your application on a default port, usually 8080. You can change this by passing the VM argument:
    -Dorg.osgi.service.http.port=8080

    Now you should be able to see your REST service on localhost:<jetty port>/rest/hello

    Conclusion

    I absolutely love the strict modularization of Equinox OSGI, but you tend to forget that other frameworks are often less restrictive. The online tutorials may, therefore, not get you what you are looking for and, even worse, you may get very few clues on what is going wrong. Luckily, in this particular case, I managed to circumvent this well-known pitfall. Hopefully, it may help other as well!

    REST Web Protocols application microservice Connector (mathematics) GlassFish Framework Eclipse Implementation Classpath (Java)

    Opinions expressed by DZone contributors are their own.

    Related

    • The Anatomy of a Microservice, One Service, Multiple Servers
    • Breaking Up a Monolithic Database with Kong
    • Spring Microservices RESTFul API Documentation With Swagger Part 1
    • How to Develop Microservices With Spring Cloud and Netflix Discovery

    Comments

    Partner Resources

    X

    ABOUT US

    • About DZone
    • Send feedback
    • Careers
    • Sitemap

    ADVERTISE

    • Advertise with DZone

    CONTRIBUTE ON DZONE

    • Article Submission Guidelines
    • Become a Contributor
    • Core Program
    • Visit the Writers' Zone

    LEGAL

    • Terms of Service
    • Privacy Policy

    CONTACT US

    • 3343 Perimeter Hill Drive
    • Suite 100
    • Nashville, TN 37211
    • support@dzone.com

    Let's be friends: