Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@Priority is not always picked up correctly for JAX-RS providers #4099

Closed
chkal opened this issue Apr 13, 2019 · 3 comments
Closed

@Priority is not always picked up correctly for JAX-RS providers #4099

chkal opened this issue Apr 13, 2019 · 3 comments
Labels
Milestone

Comments

@chkal
Copy link
Contributor

chkal commented Apr 13, 2019

There are still some cases where ordering of JAX-RS providers via @Priority doesn't work correctly. In my case there are two ExceptionMapper instances for the same exception type but with different priorities. Jersey fails to pick up the @Priority, which results in a default priority of Priorities.USER for both mappers and therefore in random ordering at runtime.

IMO the problem actually occurs for all JAX-RS provider types. It occurs with Jersey 2.28. See the following analysis for details:

Custom providers are looked up in the Providers class like this:

List<ServiceHolder<T>> providers = getServiceHolders(injectionManager,
contract,
Comparator.comparingInt(Providers::getPriority),
CustomAnnotationLiteral.INSTANCE);

The getServiceHolders method gets a Comparator which uses Providers.getPriority() to order the providers according to the @Priority annotation.

private static int getPriority(Class<?> serviceClass) {
Priority annotation = serviceClass.getAnnotation(Priority.class);
if (annotation != null) {
return annotation.value();
}
// default priority
return Priorities.USER;
}

Everything is fine so far.

The problem is that Providers.getPriority() isn't always called with the actual provider implementation class but sometimes gets an instance of org.glassfish.jersey.inject.hk2.InstanceSupplierFactoryBridge. This means that Jersey sometimes looks for the @Priority on the wrong class and is ignoring the @Priority on the actual implementation class.

image

The Providers class seems to use ServiceHolder.getImplementationClass() to get the type of the provider class, which doesn't work correctly in all cases.

List<ServiceHolder<T>> serviceHolders = injectionManager.getAllServiceHolders(contract, qualifiers);
serviceHolders.sort((o1, o2) -> objectComparator.compare(o1.getImplementationClass(), o2.getImplementationClass()));
return serviceHolders;

My current guess is that it should use ServiceHolder.getImplementation**Type**() instead. But I'll need to verify that. I'll try to create a failing integration tests for this issue.-

@chkal
Copy link
Contributor Author

chkal commented Apr 13, 2019

Please see #4100 for a possible fix. Although I'm not completely sure if it is the best place for a fix.

@chkal
Copy link
Contributor Author

chkal commented Apr 14, 2019

I created #4101 which contains an integration test which reproduces this issue. I hope this helps.

@jansupol
Copy link
Contributor

@chkal #4103 Should fix the issue.

@jansupol jansupol added the 2.29 label Apr 24, 2019
@senivam senivam added this to the 2.29 milestone Sep 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants