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

Include meaningful diagnostics when getAtInject fails due to linkage errors #1279

Closed
wants to merge 1 commit into from

Conversation

jglick
Copy link

@jglick jglick commented Oct 21, 2019

Before:

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
	at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
	at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
	at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
	at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
	at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
	at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
	at java.lang.reflect.Executable.declaredAnnotations(Executable.java:599)
	at java.lang.reflect.Executable.declaredAnnotations(Executable.java:597)
	at java.lang.reflect.Executable.getAnnotation(Executable.java:570)
	at java.lang.reflect.Method.getAnnotation(Method.java:622)
	at com.google.inject.spi.InjectionPoint.getAtInject(InjectionPoint.java:492)
	at com.google.inject.spi.InjectionPoint.getInjectionPoints(InjectionPoint.java:690)
	at com.google.inject.spi.InjectionPoint.forInstanceMethodsAndFields(InjectionPoint.java:380)
	at com.google.inject.internal.MembersInjectorStore.createWithListeners(MembersInjectorStore.java:93)
	at com.google.inject.internal.MembersInjectorStore.access$000(MembersInjectorStore.java:37)
	at com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:45)
	at com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:42)
	at com.google.inject.internal.FailableCache$1.load(FailableCache.java:37)
	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3568)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2350)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2313)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2228)
Caused: com.google.common.util.concurrent.UncheckedExecutionException
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2234)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3965)
	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3969)
	at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4829)
	at com.google.common.cache.LocalCache$LocalManualCache.getUnchecked(LocalCache.java:4834)
	at com.google.inject.internal.FailableCache.get(FailableCache.java:48)
	at com.google.inject.internal.MembersInjectorStore.get(MembersInjectorStore.java:68)
	at com.google.inject.internal.ConstructorInjectorStore.createConstructor(ConstructorInjectorStore.java:74)
	at com.google.inject.internal.ConstructorInjectorStore.access$000(ConstructorInjectorStore.java:29)
	at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:37)
	at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:33)
	at com.google.inject.internal.FailableCache$1.load(FailableCache.java:37)
	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3568)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2350)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2313)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2228)
Caused: com.google.common.util.concurrent.UncheckedExecutionException
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2234)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3965)
	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3969)
	at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4829)
	at com.google.common.cache.LocalCache$LocalManualCache.getUnchecked(LocalCache.java:4834)
	at com.google.inject.internal.FailableCache.get(FailableCache.java:48)
	at com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:50)
	at com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:136)
	at com.google.inject.internal.InjectorImpl.initializeBinding(InjectorImpl.java:533)
	at com.google.inject.internal.AbstractBindingProcessor$Processor$1.run(AbstractBindingProcessor.java:160)
	at com.google.inject.internal.ProcessedBindingData.initializeBindings(ProcessedBindingData.java:44)
	at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:123)
	at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
	at com.google.inject.Guice.createInjector(Guice.java:96)
	at com.google.inject.Guice.createInjector(Guice.java:73)
	at …

After:

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
	at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
	at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
	at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
	at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
	at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
	at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
	at java.lang.reflect.Executable.declaredAnnotations(Executable.java:599)
	at java.lang.reflect.Executable.declaredAnnotations(Executable.java:597)
	at java.lang.reflect.Executable.getAnnotation(Executable.java:570)
	at java.lang.reflect.Method.getAnnotation(Method.java:622)
	at com.google.inject.spi.InjectionPoint.getAtInject(InjectionPoint.java:493)
	at com.google.inject.spi.InjectionPoint.getInjectionPoints(InjectionPoint.java:695)
	at com.google.inject.spi.InjectionPoint.forInstanceMethodsAndFields(InjectionPoint.java:380)
	at com.google.inject.internal.MembersInjectorStore.createWithListeners(MembersInjectorStore.java:93)
	at com.google.inject.internal.MembersInjectorStore.access$000(MembersInjectorStore.java:37)
	at com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:45)
	at com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:42)
	at com.google.inject.internal.FailableCache$1.load(FailableCache.java:37)
	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3568)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2350)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2313)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2228)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3965)
	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3969)
	at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4829)
	at com.google.common.cache.LocalCache$LocalManualCache.getUnchecked(LocalCache.java:4834)
	at com.google.inject.internal.FailableCache.get(FailableCache.java:48)
	at com.google.inject.internal.MembersInjectorStore.get(MembersInjectorStore.java:68)
	at com.google.inject.internal.ConstructorInjectorStore.createConstructor(ConstructorInjectorStore.java:75)
	at com.google.inject.internal.ConstructorInjectorStore.access$000(ConstructorInjectorStore.java:29)
	at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:37)
	at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:33)
	at com.google.inject.internal.FailableCache$1.load(FailableCache.java:37)
	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3568)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2350)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2313)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2228)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3965)
	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3969)
	at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4829)
	at com.google.common.cache.LocalCache$LocalManualCache.getUnchecked(LocalCache.java:4834)
	at com.google.inject.internal.FailableCache.get(FailableCache.java:48)
	at com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:50)
	at com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:137)
	at com.google.inject.internal.InjectorImpl.initializeBinding(InjectorImpl.java:533)
	at com.google.inject.internal.AbstractBindingProcessor$Processor$1.run(AbstractBindingProcessor.java:160)
	at com.google.inject.internal.ProcessedBindingData.initializeBindings(ProcessedBindingData.java:44)
	at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:123)
Caused: com.google.inject.CreationException: Unable to create injector, see the following errors:

1) Failed to retrieve @Inject from xxx.Redacted.xxx()
  at …

1 error
	at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466)
	at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
	at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
	at com.google.inject.Guice.createInjector(Guice.java:99)
	at com.google.inject.Guice.createInjector(Guice.java:73)
	at …

The enriched error message made it possible to identify the JAR (out of hundreds of candidates) which needed to be recompiled against an updated dependency.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@jglick
Copy link
Author

jglick commented Oct 28, 2019

(Still trying to figure out if my employer @cloudbees has a corporate CLA or what.)

@jglick
Copy link
Author

jglick commented Oct 29, 2019

@googlebot I signed it!

1 similar comment
@jglick
Copy link
Author

jglick commented Nov 4, 2019

@googlebot I signed it!

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@sameb
Copy link
Member

sameb commented Apr 19, 2023

While I appreciate the PR, Guice does a lot of reflection. It's not a winning battle to try/catch every place where inconsistent underlying jars/classes can cause linkage errors.

@sameb sameb closed this Apr 19, 2023
@jglick
Copy link
Author

jglick commented Apr 19, 2023

No, not every place, but this is one place where an error is actually likely and reported terribly.

@sameb
Copy link
Member

sameb commented Apr 20, 2023

Understood. Google lives in monorepo built-from-head world, so this particular kind of pain isn't something I see day-to-day.

I'm concerned that papering over a few specific calls is unlikely to continue working over time.

Would you be able to add tests, presumably writing a class using ByteBuddy or ASM to emulate the linkage error, so we can validate this catches and reports the problem correctly?

If we're going to do this, we should make sure we handle the following cases:

  • bad cxtor param type
  • bad field type
  • bad injected method param type
  • bad scope annotation type
  • bad qualifier annotation type

@jglick
Copy link
Author

jglick commented Apr 20, 2023

add tests, presumably writing a class using ByteBuddy or ASM to emulate the linkage error

Sounds tricky, assuming there are no existing tests of that sort to use as models. If I can find time to work on this, I will try to write up such a test and reopen accordingly (I guess combined with #1283). Thank you for advice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants