結論
XtextGeneratorStandaloneSetup を継承するクラスを含む jar バンドルを作り、XtextGenerator に与える。
背景
新し目の Xtext は XtextGenerator でコード生成を行う。
そのため、2.7.x 辺りで使われていた手法(以下、従来手法)は使えない。でも、web には 2.7.x での手法を記録したブログが溢れている。困った。
追跡メモ
従来手法では、モデルは StandaloneSetup で追加していた。
XtextGenerator は内部に standaloneSetup というプロパティを持つ。
型は XtextGeneratorStandaloneSetup 。
よって、下記のような Xtend コードを書くことで、EMF パッケージを追加できる。
import org.eclipse.xtext.xtext.generator.XtextGeneratorStandaloneSetup
import com.google.inject.Injector
import org.eclipse.emf.ecore.EPackage
import autosar40.autosartoplevelstructure.AutosartoplevelstructurePackage
class ExtendedXtextGeneratorStandaloneSetup extends XtextGeneratorStandaloneSetup {
override initialize(Injector injector) {
super.initialize(injector)
EPackage.Registry.INSTANCE.put("http://autosar.org/schema/r4.0/autosar40/atls", AutosartoplevelstructurePackage.eINSTANCE)
}
}
これを読むように MWE2 ファイルを修正する。
import org.eclipse.xtext.xtext.generator.*
import org.eclipse.xtext.xtext.generator.model.project.*
var rootPath = ".."
Workflow {
component = XtextGenerator {
configuration = {
project = StandardProjectConfig {
// 中略
}
// この行追加
standaloneSetup = build.ExtendedXtextGeneratorStandaloneSetup {}
language = StandardLanguage {
// 後略
クラスロードに関するハマりどころ
以上は、順当に考えれば行き着く。実は本当のハマりどころは下記だった。
Eclipse プラグインは過去の互換性問題もあって、jar にパックされていないバンドル形式をサポートしている。
一方、MWE2 は OSGi とは無関係に動作するよう考慮されたエンジン 1 で、独自の jar 解釈機構を持っており、jar にパックされていない OSGi バンドルは読めない。
つまり、workspace に上記 ExtendedXtextGeneratorStandaloneSetup
を置いていても、Mwe2Launcher はクラスロードしてくれない。jar バンドルとして export してから、何らかの形で読めるようにする必要がある。2
ちなみに、unpack されたバンドルを読めないのは、EMF バンドルでも同様である。
今どきの配布形態では、特別な理由がない限り jar バンドルにするはずであるが、その辺りの意識がおかしい製品も稀にあるので注意が必要である。3