1

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?

JSlain
  • 566
  • 3
  • 20

1 Answers1

1

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));
  }
}
Paul Bakker
  • 1,024
  • 7
  • 9
  • So i just can't use the default Amdatu Wink's Application and add my own Provider to it? To have the same behaviour, i'ld need to copy/paste the default Admatu Wink's Application class to my code, modify it and register a second Application service (mine) with a higher priority? – JSlain Jan 06 '15 at 14:07
  • Yes, this is currently the only way. Although it's pretty easy (the default Application is really trivial) it can probably be even easier, so I also created an issue to improve this: https://amdatu.atlassian.net/browse/AMDATUWEB-34 – Paul Bakker Jan 06 '15 at 14:52
  • I also thought this should be configurable, since we're in a modular world. Thanks anyway for opening the issue! – JSlain Jan 06 '15 at 16:25