将Xtext 2.21.0 Eclipse项目迁移至Maven时的语法引用问题
问题背景
将Eclipse 2020-03环境下的Xtext 2.21.0项目迁移至Maven后,自定义DSL出现语法引用解析失败问题,原项目在Eclipse中运行正常。尝试升级至Eclipse 2023-09、Java 17及Xtext 2.32.0时,出现注入变量为空的问题,同时不确定是否需要在Mwe2工作流中处理Eclipse的plugin.xml配置。
报错信息
529 ERROR XtextGeneratorLanguage - [XtextLinkingDiagnostic: null:1 无法解析对Grammar 'abc.generator.ServiceGenerator'的引用。, XtextLinkingDiagnostic: null:4 无法解析对EPackage 'http://www.generator.abc/ServiceGenerator'的引用。, XtextLinkingDiagnostic: null:117 STRING无法解析为规则, XtextLinkingDiagnostic: null:249 INT无法解析为规则, TransformationDiagnostic: null:248 数据类型规则只能使用其他数据类型规则、词法分析器规则和关键字。(错误代码: InvalidDatatypeRule)] 531 ERROR Mwe2Launcher - 运行工作流abc.generator.GenerateRawNotificationGenerator时出现问题: 解析'file:/C:/Users/xxx/Desktop/eclipse_plugin_pom/abc.generator/../abc.generator/src/abc/generator/VarDefinitionGenerator.xtext'时出错: XtextLinkingDiagnostic: null:1 无法解析对Grammar 'abc.generator.ServiceGenerator'的引用。 XtextLinkingDiagnostic: null:4 无法解析对EPackage 'http://www.generator.abc/ServiceGenerator'的引用。 XtextLinkingDiagnostic: null:117 STRING无法解析为规则 XtextLinkingDiagnostic: null:249 INT无法解析为规则 TransformationDiagnostic: null:248 数据类型规则只能使用其他数据类型规则、词法分析器规则和关键字。(错误代码: InvalidDatatypeRule)
关键配置文件
1. Mwe2工作流文件
module abc.generator.GenerateRawNotificationGenerator import org.eclipse.xtext.xtext.generator.* import org.eclipse.emf.mwe.utils.StandaloneSetup import org.eclipse.xtext.xtext.generator.model.project.* var rootPath = ".." Workflow { component = XtextGenerator { configuration = { project = StandardProjectConfig { baseName = "abc.generator" rootPath = rootPath runtimeTest = { enabled = true } eclipsePlugin = { enabled = true } eclipsePluginTest = { enabled = true } createEclipseMetaData = true } code = { encoding = "windows-1252" lineDelimiter = "\r\n" fileHeader = "/*\n * generated by Xtext \${version}\n */" } } language = StandardLanguage { name = "abc.generator.ServiceGenerator" fileExtensions = "services" serializer = { generateStub = false } validator = { composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" } } language = StandardLanguage { name = "abc.generator.VarDefinitionGenerator" fileExtensions = "vardefinition" serializer = { generateStub = false } validator = { composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" } } } }
2. ServiceGenerator语法头
grammar abc.generator.ServiceGenerator with org.eclipse.xtext.common.Terminals generate serviceGenerator "http://www.generator.abc/ServiceGenerator" import "http://www.eclipse.org/emf/2002/Ecore" as ecore
3. VarDefinitionGenerator语法头
grammar abc.generator.VarDefinitionGenerator with abc.generator.ServiceGenerator generate varDefinitionGenerator "http://www.generator.abc/VarDefinitionGenerator" import "http://www.generator.abc/ServiceGenerator" import "http://www.eclipse.org/emf/2002/Ecore" as ecore
4. Eclipse plugin.xml
<?xml version="1.0" encoding="windows-1252"?> <?eclipse version="3.0"?> <plugin> <extension point="org.eclipse.emf.ecore.generated_package"> <package uri = "http://www.generator.abc/ServiceGenerator" class = "abc.generator.serviceGenerator.ServiceGeneratorPackage" genModel = "model/generated/ServiceGenerator.genmodel" /> </extension> <extension point="org.eclipse.emf.ecore.generated_package"> <package uri = "http://www.generator.abc/VarDefinitionGenerator" class = "abc.generator.varDefinitionGenerator.VarDefinitionGeneratorPackage" genModel = "model/generated/VarDefinitionGenerator.genmodel" /> </extension> </plugin>
解决方案
1. 明确Mwe2中的语言依赖关系
由于VarDefinitionGenerator继承自ServiceGenerator,需在Mwe2工作流中为后者添加依赖声明,确保生成顺序与依赖解析正确。修改第二个StandardLanguage配置:
language = StandardLanguage { name = "abc.generator.VarDefinitionGenerator" fileExtensions = "vardefinition" // 添加依赖,指定依赖的语言 dependencies = { language = "abc.generator.ServiceGenerator" } serializer = { generateStub = false } validator = { composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" } }
2. 配置StandaloneSetup加载EPackage
在Workflow开头添加StandaloneSetup组件,确保EPackage和生成的类能被正确扫描加载:
Workflow { // 添加StandaloneSetup组件,放在XtextGenerator之前 component = StandaloneSetup { scanClassPath = true platformUri = rootPath registerGeneratedPackages = true } component = XtextGenerator { // 原XtextGenerator配置保持不变 // ... } }
3. 确保EPackage自动注册
在两个StandardLanguage配置中添加ecoreGenerator配置,让生成的Package类自动注册EPackage:
language = StandardLanguage { name = "abc.generator.ServiceGenerator" fileExtensions = "services" serializer = { generateStub = false } validator = { composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" } // 添加EPackage自动注册配置 ecoreGenerator = { registerPackage = true } }
4. 处理plugin.xml生成逻辑
由于Mwe2中createEclipseMetaData = true,会自动生成Eclipse插件相关的plugin.xml,包括EPackage注册。不需要手动维护plugin.xml,删除手动添加的文件,让Mwe2自动生成即可。若需自定义,可通过Mwe2的eclipsePlugin配置调整。
5. 验证Maven构建顺序
执行Maven命令时,先清理并生成源码:
mvn clean generate-sources
确保ServiceGenerator的代码先于VarDefinitionGenerator生成,类路径包含所有生成的类文件。
关于版本升级的注入变量问题
若升级至Xtext 2.32.0 + Java 17:
- 替换依赖中的
javax.inject为jakarta.inject - 确保Xtext Maven插件版本与Xtext版本匹配
- 检查代码中
@Inject注解的导入路径,改为jakarta.inject.Inject
内容的提问来源于stack exchange,提问作者Cosmin Polifronie

