Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xpect creates two language injectors which can lead to singleton violations wrt. injected instances #233

Open
lbeurerkellner opened this issue May 8, 2018 · 0 comments

Comments

@lbeurerkellner
Copy link

In the getInjector method of AbstractLanguageInfo Xpect first creates a default injector in order to obtain instances of the moduleClasses. However, later on it goes on and creates another injector, which is used to inject the actual instance components using a slightly modified runtime module.

I suppose the original intention behind this code is that the first "default" injector is only used briefly and then dismissed. However, this assumption does not hold true when used in combination with eager singletons (cf. Guice Eager Singletons).

When creating a new Xtext language (using the wizard), the generated abstract runtime module Abstract<language name>RuntimeModule declares an eager-singleton binding for the main validator of the language:

(...)
// contributed by org.eclipse.xtext.xtext.generator.validation.ValidatorFragment2
@SingletonBinding(eager=true)
public Class<? extends <language name>Validator> bind<language name>Validator() {
	return <language name>Validator.class;
}
(...)

In Guice terms this means that whenever a new injector is created based on such a module, the validator instance is created immediately and all its fields and methods are injected. As a consequence, an AbstractInjectableValidator, as it is common in Xtext, is registered with the global EMF EValidatorRegistrar (cf. AbstractInjectableValidator.java:45 in eclipse/xtext-core).

In the abovementioned code, this registration is performed twice, first for the validator instance of the default injector, and later for the validator instance of the actual injector. However, since the EValidatorRegistrar maintains uniqueness among validators based on class name / FQN, this second registration is ignored. Thus, when running validation in an Xpect test, the validator instances in use were actually injected by the default injector and therefore depend on their own set of singletons. In particular, this provokes an inconsistency between other components (e.g. the parser) and the validators with regard to singleton assumptions (e.g. the identities of grammar rule elements via grammar access do not match).

I would suspect that this situation is generally unintended and invalid, but please let me know if I understand anything incorrectly. Furthermore, I mostly came here to start a discussion, as I am not sure how to solve the issue described here. I am looking forward to hear from you about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant