Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Guice error in tests after adding Formatter [SOLVED]
Guice error in tests after adding Formatter [SOLVED] [message #1838986] Wed, 10 March 2021 23:11 Go to next message
Volker Wegert is currently offline Volker WegertFriend
Messages: 182
Registered: July 2009
Senior Member
"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 10:59]

Report message to a moderator

Re: Guice error in tests after adding Formatter [message #1838994 is a reply to message #1838986] Thu, 11 March 2021 06:56 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
how is the inheritance hierarchy of your modules and where are bindings for the formatter and where not


1) No implementation for mydsl.formatting2.MyBaseDslFormatter was bound.
at org.eclipse.xtext.service.MethodBasedModule.configure(MethodBasedModule.java:58)


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Guice error in tests after adding Formatter [message #1838995 is a reply to message #1838994] Thu, 11 March 2021 07:46 Go to previous messageGo to next message
Volker Wegert is currently offline Volker WegertFriend
Messages: 182
Registered: July 2009
Senior Member
Thanks for looking into this!

Christian Dietrich wrote on Thu, 11 March 2021 01:56
how is the inheritance hierarchy of your modules


"core" plug-in:
org.eclipse.xtext.service.AbstractGenericModule
  org.eclipse.xtext.service.DefaultRuntimeModule
    mydsl.AbstractMyBaseDslRuntimeModule
      mydsl.MyBaseDslRuntimeModule
    mydsl.AbstractMyExtendedDslRuntimeModule
      mydsl.MyExtendedDslRuntimeModule


IDE plug-in:
org.eclipse.xtext.service.AbstractGenericModule
  org.eclipse.xtext.ide.DefaultIdeModule
    mydsl.ide.AbstractMyBaseDslIdeModule
      mydsl.ide.MyBaseDslIdeModule
	mydsl.ide.AbstractMyExtendedDslIdeModule
	  mydsl.ide.MyExtendedDslIdeModule


UI plug-in:
org.eclipse.xtext.service.AbstractGenericModule
  org.eclipse.xtext.ui.DefaultUiModule
    mydsl.ui.AbstractMyBaseDslUiModule
	  mydsl.ui.MyBaseDslUiModule
	mydsl.ui.AbstractMyExtendedDslUiModule
	  mydsl.ui.MyExtendedDslUiModule


Christian Dietrich wrote on Thu, 11 March 2021 01:56
and where are bindings for the formatter and where not


mydsl.AbstractMyBaseDslRuntimeModule        --> mydsl.formatting2.MyBaseDslFormatter
mydsl.AbstractMyExtendedDslRuntimeModule --> mydsl.formatting2.MyExtendedDslFormatter
mydsl.ide.AbstractMyBaseDslIdeModule        --> no binding 
mydsl.ide.AbstractMyExtendedDslIdeModule --> no binding
mydsl.ui.AbstractMyBaseDslUiModule          --> no binding
mydsl.ui.AbstractMyExtendedDslUiModule   --> no binding


No additional bindings are present in any of the non-abstract pre-generated module implementations - they are completely unchanged.

FWIW, the formatter inheritance hierarchy looks like this:
org.eclipse.xtext.formatting2.AbstractFormatter2
  mydsl.formatting2.MyBaseDslFormatter
    mydsl.formatting2.MyExtendedDslFormatter


To me, it looks exactly like in the "clean" example where I can not reproduce the issue...

EDIT: I had an extraneous package level (.ma.) in there - removed for consistency with initial posting.

[Updated on: Thu, 11 March 2021 08:52]

Report message to a moderator

Re: Guice error in tests after adding Formatter [message #1839000 is a reply to message #1838995] Thu, 11 March 2021 08:24 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
org.eclipse.xtext.service.AbstractGenericModule
org.eclipse.xtext.service.DefaultRuntimeModule
mydsl.AbstractMyBaseDslRuntimeModule
mydsl.MyBaseDslRuntimeModule
mydsl.ma.AbstractMyExtendedDslRuntimeModule
mydsl.ma.MyExtendedDslRuntimeModule

looks bogus.
how to the grammar look like inheritance wise?
which injector provider do you use in test?


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Guice error in tests after adding Formatter [message #1839004 is a reply to message #1839000] Thu, 11 March 2021 09:05 Go to previous messageGo to next message
Volker Wegert is currently offline Volker WegertFriend
Messages: 182
Registered: July 2009
Senior Member
Christian Dietrich wrote on Thu, 11 March 2021 03:24
org.eclipse.xtext.service.AbstractGenericModule
org.eclipse.xtext.service.DefaultRuntimeModule
mydsl.AbstractMyBaseDslRuntimeModule
mydsl.MyBaseDslRuntimeModule
mydsl.ma.AbstractMyExtendedDslRuntimeModule
mydsl.ma.MyExtendedDslRuntimeModule

looks bogus.


Please ignore the .ma. intermediate package - I forgot to remove that. (Or is it relevant that I've used different packages for the two DSLs?)
Which aspect of it looks bogus - do you expect the extended runtime module to inherit from the base runtime module?

Christian Dietrich wrote on Thu, 11 March 2021 03:24
how to the grammar look like inheritance wise?


Base DSL:
grammar mydsl.MyBaseDsl with org.eclipse.xtext.common.Terminals
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate base "http://foobar/Base"


Extended DSL:
grammar mydsl.MyExtendedDsl with mydsl.MyBaseDsl
generate extended "http://foobar/Extended"


I have definitely not made any changes to this when adding the formatter, and it was working before that.

Christian Dietrich wrote on Thu, 11 March 2021 03:24
which injector provider do you use in test?


The generated injection provider of the extended grammar, that in turn uses the mydsl.MyExtendedDslRuntimeModule
Re: Guice error in tests after adding Formatter [message #1839005 is a reply to message #1839004] Thu, 11 March 2021 09:19 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
it looks like the runtime modules dont inherit from each other
am not sure if this is a bug or a feature.
so you would have to repeat the binding.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Guice error in tests after adding Formatter [message #1839012 is a reply to message #1839005] Thu, 11 March 2021 10:58 Go to previous message
Volker Wegert is currently offline Volker WegertFriend
Messages: 182
Registered: July 2009
Senior Member
Christian Dietrich wrote on Thu, 11 March 2021 04:19
it 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...)

Previous Topic:Include * in Xtext grammar
Next Topic:Duck Typing
Goto Forum:
  


Current Time: Thu Apr 18 00:12:17 GMT 2024

Powered by FUDForum. Page generated in 0.02154 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top