Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Reinstate BaseSpan interface for backwards compatibility #238

Closed
wants to merge 2 commits into from

Conversation

yurishkuro
Copy link
Member

Fixes #237

Signed-off-by: Yuri Shkuro <ys@uber.com>
@coveralls
Copy link

Coverage Status

Coverage remained the same at 81.842% when pulling 21925aa on v0.31.0-base-span into 85fab98 on v0.31.0.

Copy link
Collaborator

@carlosalberto carlosalberto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! (and nice to have a full note on why it's needed ;) )

As a small question: maybe it's worth adding a @deprecated annotation to the interface? Else, LGTM :)

Signed-off-by: Yuri Shkuro <ys@uber.com>
@yurishkuro
Copy link
Member Author

As a small question: maybe it's worth adding a @deprecated

Doh! Forgot to hit Cmd-S.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 81.842% when pulling 803eddb on v0.31.0-base-span into 85fab98 on v0.31.0.

@tedsuo
Copy link
Member

tedsuo commented Jan 4, 2018

If no one blocks, I propose we merge this tomorrow afternoon (Friday jan 5th).

@pavolloffay
Copy link
Member

pavolloffay commented Jan 5, 2018

I have compiled jaegertracing/jaeger-client-java#313 with tchannel 0.7.7 and OT-API with this PR (local diff https://pastebin.com/tLAu1WxM).

and I sill get other compatibility issues (CNDF) for other classes see: https://pastebin.com/7eLFbhxs (output of ./gradlew test). I am still not sure what this PR solves.

UPDATE:
I forgot to pin OT version in xdock module: now tests pass

@pavolloffay
Copy link
Member

pavolloffay commented Jan 5, 2018

I was very curious why this actually works and is necessary because tchannel does not use BaseSpan https://github.com/uber/tchannel-java/blob/tchannel-0.7.7/tchannel-core/src/main/java/com/uber/tchannel/tracing/Tracing.java it's not imported in the whole repository, therefore it should work without this PR.

However, there is an anonymous class on line 107 https://github.com/uber/tchannel-java/blob/tchannel-0.7.7/tchannel-core/src/main/java/com/uber/tchannel/tracing/Tracing.java#L107 and compiler decided to cast parameters when setting the tag to BaseSpan - in Tags.ERROR.set(span, true);

See decompiled code:
screenshot of decompiling java and android applications

So with this PR there is BaseSpan symbol present. Then why does it not produce ClassCastException? Becase in 0.30.0 AbstractTag.set accepts generic BaseSpan<?> https://github.com/opentracing/opentracing-java/blob/master/opentracing-api/src/main/java/io/opentracing/tag/AbstractTag.java#L29 and if the last section from https://docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html holds. Then there is AbstractTag.set(object, ...) which is then internally casted to Span. But this is also weird because at runtime there is 0.31.0 which does not use wildcard in AbstractSpan

This is some kind of hack which uses "bridge method" (part of type erasure), I am still not sure why/how it works.

@tedsuo
Copy link
Member

tedsuo commented Jan 5, 2018

Thanks for the detailed review @pavolloffay! After running this by a number of people, I feel like it should go in.

@pavolloffay
Copy link
Member

My comment #238 (comment) is not entirely correct.

So why does it actually work?

Tchannel code does not import BaseSpan explicitly but java compiler adds cast to BaseSpan in all AbstractTag.set(AbstractSpan) calls. It can be seen in the screenshot above.

This fix works in jaeger-client because the branch https://github.com/uber/tchannel-java/blob/tchannel-0.7.7/tchannel-core/src/main/java/com/uber/tchannel/tracing/Tracing.java#L111 - if(response.isError()) is never executed so JVM is happy even with incompatible class introduced in this PR. If the code executes it produces:

java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:294)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoSuchMethodError: io.opentracing.tag.BooleanTag.set(Lio/opentracing/BaseSpan;Ljava/lang/Boolean;)V
	at sk.loffay.ot.test.TracedClass.invoke(TracedClass.java:20)
	at sk.loffay.ot.test.module2.Main.main(Main.java:17)
	... 6 more

So this fix helps only if the code is actually never executed and introduces even more difficult runtime issues. If somebody wants to play with it https://github.com/pavolloffay/ot-compatibility-test

Copy link
Member

@pavolloffay pavolloffay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tedsuo
Copy link
Member

tedsuo commented Jan 8, 2018

Good catch.

@yurishkuro
Copy link
Member Author

let's release without this. I spoke to our teams, we will coordinate a new release of Jaeger and TChannel libs to go in sync. Most services internally do not register these dependencies explicitly, but via internal wrapper libs, so we mostly need to bump deps in those.

@yurishkuro yurishkuro closed this Jan 8, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants