Community
Participate
Working Groups
Build Identifier: 2.0.1 Build Identifier: Xtext 2.0.1 Loading a model resource within a second test case will fail because of a "SAXParseException: Content is not allowed in prolog." In a second test case the resource factory is not registered properly and a XMIResource will be created instead of a XtextResource. This bug also directly affects Xtext Unit Testing utilities (http://code.google.com/a/eclipselabs.org/p/xtext-utils/wiki/Unit_Testing). From debugging I could find out that changes in XtextRunner (since 2.0.0) causing the resource factory is not getting registered properly after evaluation of each test case. I'll attach a XtextRunner2 with proposal for a bug fix. See comments within XtextRunner2.java for more details on the bug fix. Reproducible: Always Steps to Reproduce: 1. Create domainmodel example project. 2a. Easiest way: add sources from attached org.eclipse.xtext.example.domainmodel.tests project (zipped archive). 2b. Create at least two test cases. 3. In second test case load some model from a resource, i.e. @Test public void testResourceFactory2() throws Exception { URI uri = URI.createURI("classpath:/TestModels/TestModel1.dmodel"); // XMIResource will be created (wrongly) Resource resource = resourceSet.createResource(uri); try { // this throws an exception caused by a // "SAXParseException: Content is not allowed in prolog." resource.load(null); // uncomment the line @RunWith(XtextRunner2.class) // the XtextRunner2 is fixed, see comments } catch (IOException e) { throw new RuntimeException(e); } EObject eObject = resource.getContents().get(0); } 4. The test fails because of a SAXParseException as described in the comment.
Created attachment 204365 [details] Easiest way to reproduce: use the sources from this archived project.
Created attachment 204366 [details] Proposal for a bug fix of org.eclipse.xtext.junit4.XtextRunner.
I'd reject the suggested change since it is important to store the old registry values in #setupRegistry. However, the standalone setup has to be used to call #register(Injector) for each methodBlock and not only for the first one. Therefore we may have to change the interface of ISetup or we need to provide an additional interface ISetupExtension that's implemented by the generated StandaloneSetups.
(In reply to comment #3) > I'd reject the suggested change since it is important to store the old registry > values in #setupRegistry. Sebastian, maybe I didn't understand your comment but I did not disable the call of #setupRegistry. As I could see from debuggin the XtextRunner#methodBlock of 2.0.0 calls registryConfigurator.setupRegistry() and super.methodBlock(method) in different order and the second one calls <DSL>InjectorProvider.getInjector(). This difference leads to unregistered resource factory. > However, the standalone setup has to be used to call > #register(Injector) for each methodBlock and not only for the first one. > Therefore we may have to change the interface of ISetup or we need to provide > an additional interface ISetupExtension that's implemented by the generated > StandaloneSetups. I'm interested in a proper solution and more details on this.
(In reply to comment #4) > (In reply to comment #3) > > I'd reject the suggested change since it is important to store the old registry > > values in #setupRegistry. > > Sebastian, maybe I didn't understand your comment but I did not disable the > call of #setupRegistry. Sorry, my comment was incomplete: It is important to store the old registry contents prior to invoking the method block. Otherwise it would not be possible to restore the original contents and thereby revert any side-effects that were caused by the method block itself.
I created a new project and used this testcase: @RunWith(XtextRunner.class) @InjectWith(MyDslInjectorProvider.class) public class SampleTest { @Inject XtextResourceSet resourceSet; @Test public void testResourceFactory() throws Exception { URI uri = URI.createURI("sample.mydsl"); // XMIResource will be created (wrongly) Resource resource = resourceSet.createResource(uri); Assert.assertTrue(resource instanceof XtextResource); } @Test public void testResourceFactory2() throws Exception { URI uri = URI.createURI("sample.mydsl"); // XMIResource will be created (wrongly) Resource resource = resourceSet.createResource(uri); Assert.assertTrue(resource instanceof XtextResource); } } Everything worked fine so far. Please reopen if I missed something.
(In reply to comment #6) Now I've an idea what's wrong with the <Dsl>InjectorProvider. The bug is reproducible if your #setupRegistry() in <Dsl>InjectorProvider looks like this: public void setupRegistry() { globalStateMemento = GlobalRegistries.makeCopyOfGlobalState(); } As it worked fine for you, I was wondering what could be the difference. I spent some time on this trying to understand the <Dsl>InjectorProvider after I read your #c5. And my idea was to change #setupRegistry() in <Dsl>InjectorProvider to: public void setupRegistry() { globalStateMemento = GlobalRegistries.makeCopyOfGlobalState(); if (injector != null) new <Dsl>StandaloneSetup().register(injector); } After your last comment I tried the last nightly build Xtext-N201110132135 to see how the generated <Dsl>InjectorProvider might have changed. It looks like this: public void setupRegistry() { globalStateMemento = GlobalRegistries.makeCopyOfGlobalState(); if (injector != null) new MyDslStandaloneSetup().register(injector); } And this realy works fine! I've just double-tested the 2.0.1 (from Xtext-Disto) and the bug is still there. The generated <Dsl>InjectorProvider#setupRegistry() looks like the first one. Does this bug need to be reopened?
(In reply to comment #7) > Does this bug need to be reopened? No, since it's fixed for 2.1 and we don't plan a 2.0.2
Closing all bugs that were set to RESOLVED before Neon.0