javaosgijax-rsamdatu

Amdatu: How to make ExceptionMapper (@Provider) to work?


I'm trying to manage all my exceptions with an ExceptionMapper, as i saw in multiple documentation and examples. However, it doesn't seem to work, at least in my conditions.

I'm in a OSGI environment, using the Felix Witheboard pattern, with Amdatu Wink, so i don't have a web.xml and everything is supposed to be managed by itself. I tried to register my ExceptionMapper as a service as i did with my web services, with no results.

@Component(immediate=true, provide={Object.class})
@Provider
public class SessionTimeoutExeptionHandler implements ExceptionMapper<SessionTimeoutException>{

    public Response toResponse(SessionTimeoutException arg0) {
        Response toReturn = Response.status(Status.FORBIDDEN)
                .entity("session_timeout")
                .build();

        return toReturn;
    };
}

Don't pay attention to the Response itself, i was just playing around.

My code is never called, how am i supposed to setup that provider?


Solution

  • You have to register the Provider in a javax.ws.rs.core.Application. That Application should be registered as a service with a higher service ranking than the default one created by the Amdatu Wink bundle.

    The following is a working example.

    The Exception Mapper itself:

    @Provider
    public class SecurityExceptionMapper implements ExceptionMapper<SecurityException>{
      @Override 
      public Response toResponse(SecurityException arg0) {
        return Response.status(403).build();
      }
    }
    

    The Application:

    import java.util.HashSet;
    import java.util.Set;
    import javax.ws.rs.core.Application;
    import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
    
    public class MyApplication extends Application {
    
      @Override
      public Set<Object> getSingletons() {
        Set<Object> s = new HashSet<Object>();
    
        s.add(new JacksonJsonProvider());
        s.add(new SecurityExceptionMapper());
    
        return s;
      }
    }
    

    Activator setting the service ranking property.

    public class Activator extends DependencyActivatorBase{
      @Override
      public void destroy(BundleContext arg0, DependencyManager arg1) throws Exception {
      }
    
      @Override
      public void init(BundleContext arg0, DependencyManager dm) throws Exception {
    
        Properties props = new Properties();
        props.put(Constants.SERVICE_RANKING, 100);
    
        dm.add(createComponent().setInterface(Application.class.getName(), props).setImplementation(MyApplication.class));
      }
    }