Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 370456

Summary: NPE in during linking from an XtextBuilderParticipant when build delta is empty
Product: [Modeling] TMF Reporter: Laurent <laurent.hubert>
Component: XtextAssignee: Project Inbox <tmf.xtext-inbox>
Status: CLOSED FIXED QA Contact:
Severity: major    
Priority: P3 CC: sebastian.zarnekow, sven.efftinge
Version: 2.2.1Flags: sebastian.zarnekow: juno+
Target Milestone: M7   
Hardware: Macintosh   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard:

Description Laurent CLA 2012-02-02 10:43:37 EST
Build Identifier: Version: 3.7.1 Build id: M20110909-1335

2 different implementations of IResourceDescriptions may be used depending on whether it is called in an XtextBuilderParticipant or not. This is documented and partly handled in ...builder.clustering.ClusteringBuilderState.doUpdate(...), which registers the CurrentDescriptions adapter in the resourceSet.

XtextBuilder.doBuild() calls AbstractBuilderState.update(), which is supposed to call ClusteringBuilderState.doUpdate(...), but it doesn't when buildData isEmpty().

XtextBuilder.doBuild() then triggers the builder participants.  Linking in these builders may then fail because the resourceSet has not been properly initialized by ClusteringBuilderState.doUpdate(...).

The safe fix is to execute duUpdate(...) any way, but I am not sure how expensive it can be (it will be cheaper than when there is a change anyway).
Another fix is to execute doUpdate(...) until step 2, where the resourceSet is properly initialized.  This would means to insert the following code just after the allocation of CurrentDescriptions:
  if (buildData.isEmpty())
    return ImmutableList.of();

To avoid useless event propagation, it is in also possible to avoid to notifyListeners in AbstractBuilderState.update(...) when result.isEmpty().

Reproducible: Always
Comment 1 Sven Efftinge CLA 2012-04-03 04:23:56 EDT
I'd prefer to not invoke the participants in case there's nothing to build (i.e. buildData.isEmpty()).
What is your participant trying to do in such cases?
Comment 2 Laurent CLA 2012-04-06 04:05:11 EDT
I have reported this bug 2 months ago... I do not remember exactly why I would have preferred the participants to be called even when there are no xtext resources that have changed. (Nevertheless, it does not means that there is nothing to build : some other non-xtext resources may have changed and there changes may impact the way the xtext resources should be compiled).

However, because it was not possible to do so, I currently have the following lines in my participants.
  /* circumvent bug Bug 370456 */
  if (context.getDeltas().isEmpty())
    return;
Furthermore, when our configuration file changes, we need to trigger a clean to ensure all files are rebuilt (while we could do finer treatments if the participants were called on empty build deltas).

I understand that this use case is probably not the most common, and avoiding to call the participants on empty deltas would allow to return earlier and to have things run faster in most cases.
Comment 3 Sven Efftinge CLA 2012-04-07 02:20:31 EDT
(In reply to comment #2)
> I have reported this bug 2 months ago... I do not remember exactly why I would
> have preferred the participants to be called even when there are no xtext
> resources that have changed. (Nevertheless, it does not means that there is
> nothing to build : some other non-xtext resources may have changed and there
> changes may impact the way the xtext resources should be compiled).

If they are affected, they should be included in the buildData.
Whether a resource is affected is handled in your language's ResourceDescription.Manager.isAffected method.
Comment 4 Sebastian Zarnekow CLA 2012-04-07 03:09:02 EDT
I think the scenario may be:

Java files change in WS
Xtext builder is triggered due to that change (pending deltas)
no affected resources
BuildContext is incomplete
Comment 5 Laurent CLA 2012-04-10 01:09:51 EDT
(In reply to comment #3)
> If they are affected, they should be included in the buildData.
> Whether a resource is affected is handled in your language's
> ResourceDescription.Manager.isAffected method.

I though we could only have XText and Java resources in the buildData, not, for example, some XML resources or some binary files. If it is possible to have any kind of resource in the buildData, then it indeed means that the participant never needs to be called on empty buildData.
Comment 6 Sven Efftinge CLA 2012-04-12 04:06:36 EDT
(In reply to comment #5)
> (In reply to comment #3)
> > If they are affected, they should be included in the buildData.
> > Whether a resource is affected is handled in your language's
> > ResourceDescription.Manager.isAffected method.
> 
> I though we could only have XText and Java resources in the buildData, not, for
> example, some XML resources or some binary files. If it is possible to have any
> kind of resource in the buildData, then it indeed means that the participant
> never needs to be called on empty buildData.

Yes, it's possible. You'll have to register an impl of IResourceServiceProvider.
Example:

<extension point="org.eclipse.xtext.extension_resourceServiceProvider">
        <resourceServiceProvider
            class="foo.bar.MyXmlServiceProvider"
            uriExtension="xml">
        </resourceServiceProvider>
    </extension>
Comment 7 Sven Efftinge CLA 2012-04-12 04:07:54 EDT
(In reply to comment #4)
> I think the scenario may be:
> 
> Java files change in WS
> Xtext builder is triggered due to that change (pending deltas)
> no affected resources
> BuildContext is incomplete

Java changes are contained in the buildData.
Comment 8 Laurent CLA 2012-04-12 04:41:56 EDT
(In reply to comment #6)
> (In reply to comment #5)
> Yes, it's possible. You'll have to register an impl of
> IResourceServiceProvider.
> Example:
> 
> <extension point="org.eclipse.xtext.extension_resourceServiceProvider">
>         <resourceServiceProvider
>             class="foo.bar.MyXmlServiceProvider"
>             uriExtension="xml">
>         </resourceServiceProvider>
>     </extension>

Thank you, I didn't know that. This will help us.
With this feature, I see no more reason to call the participants on empty buildData.
Comment 9 Sven Efftinge CLA 2012-04-12 05:10:46 EDT
the participants and the builder are no longer called on buildData.isEmpty()
pushed to master
Comment 10 Eclipse Webmaster CLA 2017-10-31 11:07:33 EDT
Requested via bug 522520.

-M.
Comment 11 Eclipse Webmaster CLA 2017-10-31 11:19:02 EDT
Requested via bug 522520.

-M.