opentracing-contrib / java-jaxrs

OpenTracing Java JAX-RS instrumentation
Apache License 2.0
37 stars 33 forks source link

@Traced annotation doesn't work for classes when using CDI #138

Open adreviko opened 4 years ago

adreviko commented 4 years ago

Hi, I've encountered an issue that @Traced annotation doesn't work for JAX-RS resources on class level when using CDI with Jersey application.

The reason for this lies in Weld-made proxies which strip the class level annotations from the bean instance and therefore are not passed to the ResourceInfo via .getResourceClass() method.

Actually if you use CDI in your code the only reason why the tracing for JAX-RS REST resources works at all is because the @Traced annotation is always null and by default if withTraceNothing() is not set in ServerTracingDynamicFeature builder it acts as if tracing is enabled for all resource calls.

If withTraceNothing() is set in the ServerTracingDynamicFeature builder then it doesn't matter whether you add the annotation to the class level or not it will always be null. This isn't true for .getResourceMethod() which keeps the annotations correctly.

I've solved this with extending the ServerTracingDynamicFeature and overriding the closestTracingAnnotation(ResourceInfo resourceInfo) method like so:

@Override
protected Traced closestTracedAnnotation(ResourceInfo resourceInfo) {
    Traced tracedAnnotation = resourceInfo.getResourceMethod().getAnnotation(Traced.class);
    if (tracedAnnotation == null) {
        tracedAnnotation = resourceInfo.getResourceClass().getSuperclass().getAnnotation(Traced.class);
    }

    return tracedAnnotation;
}

This seems cumbersome to me. Please let me know if there is a possible fix for this.

Thank you for your reply and with kind regards, Anna

pavolloffay commented 4 years ago

Is there a way to get the wrapped instance from the proxy?

adreviko commented 4 years ago

I'm not really sure about that. I've found some discussions here: https://issues.redhat.com/browse/CDI-10?focusedCommentId=13128346&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel and here https://developer.jboss.org/thread/272778 and so far from what I've read only the .getResourceClass().getSuperclass() helps but it is a sort of a hack. There would also be an option of checking whether the class is synthetic or not (if it is then it's a Weld proxy) and adding an @Inherited meta annotation to the implementation of the @Traced annotation which is in the microprofile repository.