Guice error in tests after adding Formatter [SOLVED] [message #1838986] |
Wed, 10 March 2021 18:11  |
Eclipse User |
|
|
|
"It's always to do things properly, and now I'm properly stuck."
I've been working on a set of two stacked grammars (renamed to MyBaseDsl and MyExtendedDsl below). I've added some validation logic and associated unit tests, and it all worked. I then proceeded to implement some tooling to import stuff from somewhere else and generate the DSL representation of what I imported, and that worked as well (*). I wasn't happy with the generated output, so I adapted the MWE2 workflow to generate a formatter stub and implemented some formatting rules. They work both in the editor and during the import process. Now I wanted to add some unit tests both for the formatter and the import logic - and discovered I can't execute any of the unit tests successfully any more. I'm basically getting the same Guice error for all of the existing tests:
org.junit.jupiter.engine.execution.JupiterEngineExecutionContext close
SEVERE: Caught exception while closing extension context: org.junit.jupiter.engine.descriptor.ClassExtensionContext@6f6a7463
com.google.inject.CreationException: Guice creation errors:
1) No implementation for mydsl.formatting2.MyBaseDslFormatter was bound.
at org.eclipse.xtext.service.MethodBasedModule.configure(MethodBasedModule.java:58)
1 error
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:435)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:154)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
at com.google.inject.Guice.createInjector(Guice.java:95)
at com.google.inject.Guice.createInjector(Guice.java:72)
at com.google.inject.Guice.createInjector(Guice.java:62)
at mydsl.MyBaseDslStandaloneSetupGenerated.createInjector(MyBaseDslStandaloneSetupGenerated.java:29)
at mydsl.MyBaseDslStandaloneSetupGenerated.createInjectorAndDoEMFRegistration(MyBaseDslStandaloneSetupGenerated.java:23)
at mydsl.MyBaseDslStandaloneSetup.doSetup(MyBaseDslStandaloneSetup.java:13)
at mydsl.MyExtendedDslStandaloneSetupGenerated.createInjectorAndDoEMFRegistration(MyExtendedDslStandaloneSetupGenerated.java:21)
at mydsl.tests.MyExtendedDslInjectorProvider.internalCreateInjector(MyExtendedDslInjectorProvider.java:40)
at mydsl.tests.MyExtendedDslInjectorProvider.getInjector(MyExtendedDslInjectorProvider.java:28)
at mydsl.tests.MyExtendedDslInjectorProvider.setupRegistry(MyExtendedDslInjectorProvider.java:65)
at org.eclipse.xtext.testing.extensions.InjectionExtension$RegistryReset.setup(InjectionExtension.java:71)
at org.eclipse.xtext.testing.extensions.InjectionExtension$RegistryReset.<init>(InjectionExtension.java:65)
at org.junit.jupiter.engine.execution.ExtensionValuesStore.lambda$getOrComputeIfAbsent$4(ExtensionValuesStore.java:86)
at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.get(ExtensionValuesStore.java:205)
at org.junit.jupiter.engine.execution.ExtensionValuesStore$StoredValue.evaluate(ExtensionValuesStore.java:182)
at org.junit.jupiter.engine.execution.ExtensionValuesStore$StoredValue.access$100(ExtensionValuesStore.java:171)
at org.junit.jupiter.engine.execution.ExtensionValuesStore.lambda$closeAllStoredCloseableValues$1(ExtensionValuesStore.java:65)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:176)
at java.base/java.util.concurrent.ConcurrentHashMap$ValueSpliterator.forEachRemaining(ConcurrentHashMap.java:3605)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at org.junit.jupiter.engine.execution.ExtensionValuesStore.closeAllStoredCloseableValues(ExtensionValuesStore.java:68)
at org.junit.jupiter.engine.descriptor.AbstractExtensionContext.close(AbstractExtensionContext.java:74)
at org.junit.jupiter.engine.execution.JupiterEngineExecutionContext.close(JupiterEngineExecutionContext.java:53)
at org.junit.jupiter.engine.descriptor.JupiterTestDescriptor.cleanUp(JupiterTestDescriptor.java:222)
at org.junit.jupiter.engine.descriptor.JupiterTestDescriptor.cleanUp(JupiterTestDescriptor.java:57)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$cleanUp$9(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.cleanUp(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:87)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:84)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
I'm seeing these errors both when running the unit tests within Eclipse as well as during the Maven build.
I've tried to reproduce these issues with a fresh set of plug-ins, but so far I haven't succeeded. I've tried to debug the issue, but all I've been able to establish is that the RuntimeModule of the "base DSL" is actually called and that it does provide a reference to the corresponding formatter implementation. I've already wiped and re-generated the manifest files and the generated test injection providers to ensure that I didn't introduce some dependency/visibility problems by accident, but no luck. How would you suggest to narrow down this issue?
I somehow need to repair these plug-ins - starting over is not an option. Unfortuately, I have no idea what is causing the issue and how to narrow down possible causes.
Thanks
Volker
Xtext 2.25.0.v20210301-1429
(*) I may have forgotten to actually check whether the unit tests where executable at that point - I don't really remember.
[Updated on: Thu, 11 March 2021 05:59] by Moderator
|
|
|
|
|
|
|
|
Re: Guice error in tests after adding Formatter [message #1839012 is a reply to message #1839005] |
Thu, 11 March 2021 05:58  |
Eclipse User |
|
|
|
Christian Dietrich wrote on Thu, 11 March 2021 04:19it looks like the runtime modules dont inherit from each other
You're right, they don't - neither in my broken set of plug-ins nor in the newly created example where the tests work...
I'm trying to wrap my head around this - let me try to sum up what I understood so far:
The generated extended injection provider uses an anonymous subclass of the extended StandaloneSetup. For createInjectorAndDoEMFRegistration(), the extended StandaloneSetup first calls the base StandaloneSetup. The base StandaloneSetup uses an injector configured with the base RuntimeModule, while the extended StandaloneSetup should - in theory - use the extended runtime module. If I understand the intent of this approach correctly, that should make it unnecessary for the modules to have an inheritance relationship. The injector configured using the extended RuntimeModule should simply be registered after the one using the base RuntimeModule.
Problem is - that's not happening, and now I know why. A classic case of PEBKAC. Since my base language only serves as a type and rule library and only has a very basic root element (literally BaseDummy: 'Foo' bar=STRING;), the BaseFormatter is generated empty. That of course makes it invalid because it is neither abstract nor does it provide an implemention of format(Object, IFormattableDocument). Yesterday-me probably saw this error, thought "naw, this formatter won't ever be used" and hit the quick fix to make the class abstract. Needless to say, this was one of my less brilliant ideas... In my newly created plug-ins I simply left the default "Hello Xtext!" grammar in place, and that has enough meat not to generate an empty formatter.
(It didn't help that the message "No implementation for %s was bound." is used for multiple error conditions. A simple "You're trying to instantiate an abstract class, dummy" would have saved me a day... But that may just be my Guice frustration speaking...)
|
|
|
Powered by
FUDForum. Page generated in 0.05717 seconds