Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Exception when referencing between Resources in same ResourceSet
Exception when referencing between Resources in same ResourceSet [message #1809794] Tue, 23 July 2019 13:43 Go to next message
Marie-Saphira Flug is currently offline Marie-Saphira FlugFriend
Messages: 21
Registered: January 2019
Junior Member
Hello,

I'm adding two (in this small example, otherwise a lot more) objects to my "main" Model programmatically (with MyDslFactory). One of them is saved in a different Resource which is in the same ResourceSet as the original one (I checked). The other one is saved in the "main" Model and contains a reference to the first object. Here an example grammar with model files:
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"

Model:
	elements+=Element*;

Element:
	First | Second;

First:
	'first' name=ID;

Second:
	'second' item=Reference;

Reference:
	'refers' reference=[First];

initial model (example.mydsl):
first object
second refers object

how the model should look like afterwards (example.mydsl):
first object
second refers object
second refers newObject

and newObject.mydsl :
first newObject

I'm able to create and save 'newObject' to a new resource 'newObject.mydsl' but when I try to save the "main" model with the added 'second refers newObject' I get a RuntimeException:
java.lang.RuntimeException: No EObjectDescription could be found in Scope Reference.reference for Model.elements[0]->First'newObject'
Semantic Object: Model.elements[2]->Second.item->Reference
URI: file:/C:/Users/flug/runtime-EclipseXtext/example/example.mydsl
EStructuralFeature: myDsl::Reference.reference

Here the code I'm executing (see also the whole project attached)
	public static void createNewObject(IPath path) {
		Injector injector = MydslActivator.getInstance().getInjector(MydslActivator.ORG_XTEXT_EXAMPLE_MYDSL_MYDSL);
		XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
		resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
		URI modelURI = URI.createFileURI(path.toString());
		Resource resource = resourceSet.getResource(modelURI, true);
		Model model = (Model) resource.getContents().get(0);
		
		Model modelForObject = MyDslFactory.eINSTANCE.createModel();
		First newObject = MyDslFactory.eINSTANCE.createFirst();
		newObject.setName("newObject");
		modelForObject.getElements().add(newObject);	
		
		URI objectURI = modelURI.trimSegments(1).appendSegment("newObject.mydsl");
		Resource objectResource = resourceSet.createResource(objectURI);
		objectResource.getContents().add(modelForObject);
		try {
			objectResource.save(Collections.EMPTY_MAP);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		Reference reference = MyDslFactory.eINSTANCE.createReference();
		reference.setReference(newObject);
		Second second = MyDslFactory.eINSTANCE.createSecond();
		second.setItem(reference);
		model.getElements().add(second);
		
		try {
			resource.save(Collections.EMPTY_MAP);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


To trigger the exception you have to start 'org.xtext.example.mydsl' as an eclipse plugin, add the 'example' project attached to your workspace (or create a new file and copy the "initial model" above), right click on 'example.mydsl' -> 'Create New Object'. The Exception won't be visibly thrown (at least not for me). To actually read it I have to set a breakpoint at the second save() call and "walk" to the exception in debug mode (tips for printing it in the console are very much appreciated).

So my question is: Why is the Reference not working and how do I get it to work?

Please ask for further explanations if my question isn't clear enough. Thanks in advance for your help.
Saphira
Re: Exception when referencing between Resources in same ResourceSet [message #1809795 is a reply to message #1809794] Tue, 23 July 2019 13:47 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
in eclipse the "resourceSet" works only if you make use of XtextLiveScopeResourceSetProvider to obtain a resourcset or at least make use of LiveScopeResourceSetInitializer

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Tue, 23 July 2019 13:47]

Report message to a moderator

Re: Exception when referencing between Resources in same ResourceSet [message #1809799 is a reply to message #1809795] Tue, 23 July 2019 14:15 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

@Christian: I'm not sure that you've written what you really mean.

In Eclipse, ResourceSets are widely used in many modeling applications following an initial new ResourceSetImpl, and wherever sensible you should add new facilities to an existing ResourceSet, rather than creating a new one.

Xtext introduced the XtextResourceSet and SynchronizedXtextResourceSet that do good things for the Xtext tooling, but which are largely hidden from the modeling side of Xtext-based applications.

I'm never quite sure what injection does so I can only suspect that your

Quote:
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);


is creating a new ResourceSet rather than accessing an old one. It is certainly using an XtextResourceSet where I would expect a pre-existing ResourceSet would be more appropriate.

Regards

Ed Willink
Re: Exception when referencing between Resources in same ResourceSet [message #1809800 is a reply to message #1809795] Tue, 23 July 2019 14:17 Go to previous messageGo to next message
Marie-Saphira Flug is currently offline Marie-Saphira FlugFriend
Messages: 21
Registered: January 2019
Junior Member
Hi Christian,
thanks for your quick reply. I tried
XtextResourceSet resourceSet = (XtextResourceSet) injector.getInstance(XtextLiveScopeResourceSetProvider.class).get(project);

which didn't change anything. Then I tried injecting it to my handler (org.xtext.example.mydsl.ui.MyDslExecutableExtensionFactory:org.xtext.example.mydsl.ui.handlers.CreateNewObjectHandler) and
	@Inject
	XtextLiveScopeResourceSetProvider provider;

but it was null. Sorry I'm not that familliar with Injection. Is there a documentation for the XtextLiveScopeResourceSetProvider somewhere?
Thanks a lot,
Saphira
Re: Exception when referencing between Resources in same ResourceSet [message #1809804 is a reply to message #1809800] Tue, 23 July 2019 15:53 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
You can ask the injector for the stuff

Alternatively you should change the handler declaration to

class="xxx.MyDslExecutableExtensionFactory:xxx.MyHandler"
In the Plugin. XML to get injection running
See other usages of mydslexecutableextensionfactor in mydsl Ui Plugin.xml


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Exception when referencing between Resources in same ResourceSet [message #1809962 is a reply to message #1809804] Fri, 26 July 2019 14:35 Go to previous messageGo to next message
Marie-Saphira Flug is currently offline Marie-Saphira FlugFriend
Messages: 21
Registered: January 2019
Junior Member
Hi,
do you mean
 XtextResourceSet resourceSet = (XtextResourceSet) injector.getInstance(XtextLiveScopeResourceSetProvider.class).get(project); 

by Quote:
You can ask the injector for the stuff
? Using this still won't change anything.

So I changed my handler declaration and the injection works fine. But I still get the same error.
Re: Exception when referencing between Resources in same ResourceSet [message #1809965 is a reply to message #1809962] Fri, 26 July 2019 15:12 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
yes the uri stuff you do is terrible suspiciously too

public class MyDslHandler extends AbstractHandler {
	@Inject
	XtextLiveScopeResourceSetProvider rsp;
	
	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		ISelection selection = HandlerUtil.getCurrentSelection(event);
        if (selection instanceof IStructuredSelection) {
            IStructuredSelection structuredSelection = (IStructuredSelection) selection;
            Object firstElement = structuredSelection.getFirstElement();
            if (firstElement instanceof IFile) {
            	IFile file = (IFile) firstElement;
            	URI modelURI = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
            	XtextResourceSet resourceSet = (XtextResourceSet) rsp.get(file.getProject());
            	resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
            	Resource resource = resourceSet.getResource(modelURI, true);
            	Model model = (Model) resource.getContents().get(0);
            	
            	Model modelForObject = MyDslFactory.eINSTANCE.createModel();
            	First newObject = MyDslFactory.eINSTANCE.createFirst();
            	newObject.setName("newObject");
            	modelForObject.getElements().add(newObject);	
            	
            	URI objectURI = modelURI.trimSegments(1).appendSegment("newObject."+file.getFileExtension());
            	Resource objectResource = resourceSet.createResource(objectURI);
            	objectResource.getContents().add(modelForObject);
            	try {
            		objectResource.save(Collections.EMPTY_MAP);
            	} catch (IOException e) {
            		e.printStackTrace();
            	}
            	
            	Reference reference = MyDslFactory.eINSTANCE.createReference();
            	reference.setReference(newObject);
            	Second second = MyDslFactory.eINSTANCE.createSecond();
            	second.setItem(reference);
            	model.getElements().add(second);
            	
            	try {
            		resource.save(Collections.EMPTY_MAP);
            	} catch (IOException e) {
            		e.printStackTrace();
            	}
            	// TODO Auto-generated method stub
            }
        }
        return null;
	}

}



Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Exception when referencing between Resources in same ResourceSet [message #1809967 is a reply to message #1809965] Fri, 26 July 2019 15:52 Go to previous message
Marie-Saphira Flug is currently offline Marie-Saphira FlugFriend
Messages: 21
Registered: January 2019
Junior Member
Thanks a lot! Sorry that you had to spell it out. Didn't know that you need a PlatformResourceURI.

The XtextLiveScopeResourceSetProvider seems to be important (there are a few posts here asking about it), but I didn't find it when I was looking through Xtext documentation. Maybe it could be mentioned here?
Previous Topic:Model meta elements and their instances?
Next Topic:Creating multiple XText Eclipse editors for one extension
Goto Forum:
  


Current Time: Fri Apr 19 00:53:33 GMT 2024

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

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

Back to the top