Maven build openHAB plugin: Cannot create a resource for 'http://www.eclipse.org/2008/Xtext'; a registered resource factory is needed

As it bothers me, that it’s currently not easily possible to automatically test openHAB rules, I started on a little side project creating this possibility. The background is, that in a really smart home, there’re a lot of different rules which may or may not be complex to automate a lot of things. These rules usually interact with a lot of different items, which makes it difficult to make small or bigger changes without breaking other stuff at a completely other point.

Having automated tests, which ensures that the user-visible behaviour is still the same, would make changing rules much more robust, I think. This would also not require to test against real devices, as rules can run and live without actually interacting with a device, just the item needs to be there (and probably unlinked from any channel). This all already works and you can find the corresponding code in my openhab-core fork.

However, even if it works running this code from the Eclipse IDE (with the provied launch configuration), it doesn’t work when running with maven :confused:

When I run the following maven command:
/path/to/mvn/bin/mvn integration-test -Dtest.configdir="/path/to/openhab/config/dir" -e

I’ll get the following exception:

Error injecting constructor, org.eclipse.emf.common.util.WrappedException: java.lang.RuntimeException: Cannot create a resource for 'http://www.eclipse.org/2008/Xtext'; a registered resource factory is needed
  at org.eclipse.smarthome.model.services.ItemsGrammarAccess.<init>(Unknown Source)
  at org.eclipse.smarthome.model.services.ItemsGrammarAccess.class(Unknown Source)
  while locating org.eclipse.smarthome.model.services.ItemsGrammarAccess
  while locating org.eclipse.xtext.IGrammarAccess
    for field at org.eclipse.xtext.conversion.impl.AbstractIDValueConverter.grammarAccess(Unknown Source)
  while locating org.eclipse.xtext.conversion.impl.IDValueConverter
  while locating org.eclipse.xtext.conversion.impl.AbstractIDValueConverter
    for field at org.eclipse.xtext.common.services.DefaultTerminalConverters.idValueConverter(Unknown Source)
  while locating org.eclipse.smarthome.model.internal.valueconverter.ItemValueConverters
  while locating org.eclipse.xtext.conversion.IValueConverterService
    for field at org.eclipse.xtext.linking.impl.LinkingHelper.valueConverter(Unknown Source)
  while locating org.eclipse.xtext.linking.impl.LinkingHelper
    for field at org.eclipse.xtext.linking.lazy.LazyLinkingResource.linkingHelper(Unknown Source)
  while locating org.eclipse.xtext.linking.lazy.LazyLinkingResource
  while locating org.eclipse.xtext.resource.XtextResource
Caused by: org.eclipse.emf.common.util.WrappedException: java.lang.RuntimeException: Cannot create a resource for 'http://www.eclipse.org/2008/Xtext'; a registered resource factory is needed
        at org.eclipse.xtext.parser.BaseEPackageAccess.loadResource(BaseEPackageAccess.java:57)
        at org.eclipse.xtext.parser.BaseEPackageAccess.loadGrammarFile(BaseEPackageAccess.java:44)
        at org.eclipse.xtext.service.GrammarProvider.getGrammar(GrammarProvider.java:61)
        at org.eclipse.smarthome.model.services.ItemsGrammarAccess.internalFindGrammar(ItemsGrammarAccess.java:781)
        at org.eclipse.smarthome.model.services.ItemsGrammarAccess.<init>(ItemsGrammarAccess.java:759)
        at sun.reflect.GeneratedConstructorAccessor49.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
        at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:85)
        at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
        at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
        at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
        at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
        at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
        at com.google.inject.Scopes$1$1.get(Scopes.java:65)
        at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
        at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:54)
        at com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53)
        at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:110)
        at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:94)
        at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
        at com.google.inject.internal.InjectorImpl$3.get(InjectorImpl.java:737)
        at com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53)
        at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:110)
        at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:94)
        at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
        at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:54)
        at com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53)
        at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:110)
        at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:94)
        at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
        at com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53)
        at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:110)
        at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:94)
        at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
        at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:54)
        at com.google.inject.internal.InjectorImpl$4$1.call(InjectorImpl.java:978)
        at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
        at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:974)
        at org.eclipse.xtext.resource.XtextResourceFactory.createResource(XtextResourceFactory.java:20)
        at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.createResource(ResourceSetImpl.java:434)
        at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.createResource(ResourceSetImpl.java:423)
        at org.eclipse.xtext.resource.SynchronizedXtextResourceSet.createResource(SynchronizedXtextResourceSet.java:32)
        at org.eclipse.smarthome.model.core.internal.ModelRepositoryImpl.validateModel(ModelRepositoryImpl.java:262)
        at org.eclipse.smarthome.model.core.internal.ModelRepositoryImpl.addOrRefreshModel(ModelRepositoryImpl.java:95)
        at org.openhab.rulestest.RuleTest.injectTestModels(RuleTest.java:76)
        at org.openhab.rulestest.RuleTest.setUp(RuleTest.java:44)
        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:483)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.apache.maven.surefire.junitcore.JUnitCore.run(JUnitCore.java:55)
        at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.createRequestAndRun(JUnitCoreWrapper.java:137)
        at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.executeEager(JUnitCoreWrapper.java:107)
        at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.execute(JUnitCoreWrapper.java:83)
        at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.execute(JUnitCoreWrapper.java:75)
        at org.apache.maven.surefire.junitcore.JUnitCoreProvider.invoke(JUnitCoreProvider.java:161)
        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:483)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:202)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:155)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:81)
        at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:107)
        at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.run(HeadlessTestApplication.java:21)
        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:483)
        at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethodWithException(EclipseAppContainer.java:587)
        at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:198)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
        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:483)
        at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:656)
        at org.eclipse.equinox.launcher.Main.basicRun(Main.java:592)
        at org.eclipse.equinox.launcher.Main.run(Main.java:1498)
        at org.eclipse.equinox.launcher.Main.main(Main.java:1471)
Caused by: java.lang.RuntimeException: Cannot create a resource for 'http://www.eclipse.org/2008/Xtext'; a registered resource factory is needed
        at org.eclipse.xtext.resource.XtextResourceSet.getResource(XtextResourceSet.java:262)
        at org.eclipse.xtext.resource.SynchronizedXtextResourceSet.getResource(SynchronizedXtextResourceSet.java:25)
        at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getEObject(ResourceSetImpl.java:220)
        at org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl$EObjectInputStream.readEPackage(BinaryResourceImpl.java:2061)
        at org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl$EObjectInputStream.readEClass(BinaryResourceImpl.java:2110)
        at org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl$EObjectInputStream.loadEObject(BinaryResourceImpl.java:2495)
        at org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl$EObjectInputStream.loadResource(BinaryResourceImpl.java:2219)
        at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLResourceImpl.java:219)
        at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1563)
        at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1342)
        at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoad(ResourceSetImpl.java:259)
        at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:274)
        at org.eclipse.xtext.resource.XtextResourceSet.getResource(XtextResourceSet.java:265)
        at org.eclipse.xtext.resource.SynchronizedXtextResourceSet.getResource(SynchronizedXtextResourceSet.java:25)
        at org.eclipse.xtext.parser.BaseEPackageAccess.loadResource(BaseEPackageAccess.java:52)
        ... 105 more

multiple times, which (that’s my suggestion) relates to the code, which injects models (an items file and a rules file) in order to recognize when the openHAB engine is “ready”.

As I’m new to the whole eclipse plugin stuff and as I’m not that familar with integrating this into a maven build (and as it is working in the IDE), I’m stuck and ask for help. Does anyone have an idea what I’m doing wrong?

A second question: The launch configuration selects round about 150 plugins, which are required to run the tests (as a whole openHAB context is started up), which I need to (at least it seems so) add as dependencies to the tycho build. Is there any better idea how to do that? :slight_smile:

Thanks for any help!

After the build system now was changed from tycho to bnd, the build also works from maven :smiley:
-> https://github.com/openhab/openhab-core/pull/471