Embulk0.10.41(古い)のプラグインの作成方法のメモ。
|
|
従来のEmbulk0.9に対し、Embulk0.11/1.0ではプラグインの作成方法が大きく変わる。
(Rubyに依存しなくなり、よく使うクラスのモジュールやパッケージも変更されている。また、プラグインの公開方法もMavenのリポジトリーを使う)
そのため、今からプラグインを作るなら0.11/1.0対応版にしたいところだが、まだ0.11は公開されていないようなので、0.10を使うことになる。
ただし、 0.10で0.11/1.0方式のプラグインを作ること自体は可能だが、作ったプラグインを実行する正式な方法は提供されていない。
また、Embulkは公式にはJava8のみに対応していて、例えばJava11には未対応。
Java11で実行するにはさらにひと手間かかる。
Embulkプラグインを作る従来の方法は、embulk newでプロジェクトおよび雛形を作成することだった。
Embulk0.11/1.0方式のプラグインを作る場合、そういったコマンドは使わず、普通にJavaプロジェクトやbuild.gradleを用意する。
まず、プロジェクトのディレクトリーを作成する。
例えば
アウトプットプラグインの場合、「embulk-output-固有名」にするのが良さそう。
$ mkdir embulk-output-example1
Gradleのgradlewコマンドを用意する。
gradle-embulk-plugins(EmbulkのGradleプラグイン)のREADME.mdによると、0.5.3でGradle6や7に対応しているらしいのだが、Embulkで参考になるサイトは6系を使っていることが多いので、ここでは6系の最新である6.9.3にしておく。
(Gradle6と7の違いは、主にdependenciesの書き方に関わる)
$ cd embulk-output-example1 $ どこかに置かれている/gradlew wrapper --gradle-version=6.9.3 〜 $ ./gradlew --version 〜 ------------------------------------------------------------ Gradle 6.9.3 ------------------------------------------------------------ 〜
build.gradleの内容は、gradle-embulk-pluginsのGitHubにあるREADME.mdが参考になる。
org.embulk.embulk-pluginsによると、org.embulk.embulk-pluginsの最新バージョンは0.5.5。
dependenciesの各ライブラリーのバージョンはMaven Central Repositoryで確認できる。
plugins { id "java" id "maven-publish" id "org.embulk.embulk-plugins" version "0.5.5" } group = "com.hishidama.embulk" version = "0.1.0-SNAPSHOT" description = "An Embulk plugin to output example." sourceCompatibility = 8 targetCompatibility = 8 repositories { mavenCentral() } embulkPlugin { mainClass = "com.hishidama.embulk.output.example1.Example1OutputPlugin" category = "output" type = "example1" } dependencies { compileOnly "org.embulk:embulk-api:0.10.41" compileOnly "org.embulk:embulk-spi:0.10.41" compile "org.embulk:embulk-util-config:0.3.2" // compile "YOUR_JAR_DEPENDENCY_GROUP:YOUR_JAR_DEPENDENCY_MODULE:YOUR_JAR_DEPENDENCY_VERSION" testCompile "org.embulk:embulk-api:0.10.41" testCompile "org.embulk:embulk-spi:0.10.41" testCompile "org.embulk:embulk-junit4:0.10.41" testCompile 'javax.xml.bind:jaxb-api:2.3.1' // for Java11 } publishing { publications { maven(MavenPublication) { artifactId = 'embulk-output-example1' from components.java } } }
sourceCompatibilityとtargetCompatibilityでJavaのバージョンを指定できる。
Embulkは正式にはJava8しかサポートしていないが、Java11でも作れる。
$ mkdir -p src/main/java $ mkdir -p src/test/java
Eclipseには、対応するバージョンのJDKを「Installed JREs」に追加しておく必要がある。
追加されていないのにインポートすると、ビルド時にエラーになる。
YAMLファイルに記述されたパラメーター(オプション)を取得するのに使うのが、PluginTaskインターフェース。
旧来のnewコマンドで作られた雛形をEmbulk0.10に書き換えると、以下のようになる。
Embulk0.10では、TaskやConfigのパッケージが以前とは変わっている。
Optionalも以前はcom.google.commonのものが使われていたが、Java8のOptionalに変わっている。
import org.embulk.util.config.Config; import org.embulk.util.config.ConfigDefault; import org.embulk.util.config.Task;
public interface PluginTask extends Task { // configuration option 1 (required integer) @Config("option1") public int getOption1(); // configuration option 2 (optional string, null is not allowed) @Config("option2") @ConfigDefault("\"myvalue\"") public String getOption2(); // configuration option 3 (optional string, null is allowed) @Config("option3") @ConfigDefault("null") public Optional<String> getOption3(); }
このPluginTaskインターフェースでは、ゲッターメソッドだけを定義する。
具象クラスの作成やYAMLファイルから読み込んだ値の設定はEmbulkがやってくれる。
@ConfigアノテーションでYAMLファイル内のパラメーター名を指定する。
ゲッターメソッドの戻り値の型でデータの型を指定する。
省略可能なパラメーターの場合は@ConfigDefaultアノテーションを付けてデフォルト値を指定する。省略時にnullにしたい場合は戻り型をOptionalにする。
ConfigSourceからPluginTaskのインスタンスを取得するには、ConfigMapperを使用する。
TaskSourceからPluginTaskのインスタンスを取得するには、TaskMapperを使用する。
import org.embulk.util.config.ConfigMapper; import org.embulk.util.config.ConfigMapperFactory; import org.embulk.util.config.TaskMapper;
protected static final ConfigMapperFactory CONFIG_MAPPER_FACTORY = ConfigMapperFactory.builder() .addDefaultModules() .build(); protected static final ConfigMapper CONFIG_MAPPER = CONFIG_MAPPER_FACTORY.createConfigMapper(); protected static final TaskMapper TASK_MAPPER = CONFIG_MAPPER_FACTORY.createTaskMapper();
// PluginTask task = config.loadConfig(PluginTask.class); // 従来の方法 PluginTask task = CONFIG_MAPPER.map(config, PluginTask.class);
// PluginTask task = taskSource.loadTask(PluginTask.class); // 従来の方法 PluginTask task = TASK_MAPPER.map(taskSource, PluginTask.class);
OutputPluginのtransactionメソッドは出力のトランザクションを処理する。
@Override
public ConfigDiff transaction(ConfigSource config, Schema schema, int taskCount, Control control) {
PluginTask task = CONFIG_MAPPER.map(config, PluginTask.class);
// retryable (idempotent) output:
// return resume(task.toTaskSource(), schema, taskCount, control);
// non-retryable (non-idempotent) output:
control.run(task.toTaskSource());
// return Exec.newConfigDiff(); // 従来の方法
return CONFIG_MAPPER_FACTORY.newConfigDiff();
}
冪等な処理(何度リトライしても問題ない処理)の場合はresumeメソッドを呼び出せばいいらしい。
そうでない場合はcontrol.run()を呼び出すらしい。
例えばRDBのテーブルへのinsertであれば1回しか実行できない(2回目以降は一意制約違反になる)ので冪等ではないし、
同じ結果になるupsert(データが既存ならupdate、無いならinsert)であれば何度実行しても構わないので冪等な処理だ。
例えばRDBで「トランザクション開始→insert→コミット(失敗した際はロールバックする)」であれば、何度でも実行できるので冪等な処理だろう。
AbstractJdbcOutputPluginの場合、
前処理を行ってからcontrol.run()を呼び出し、後処理をしてからConfigDiffを返すようになっている。
(前処理・後処理はbeginとかcommitというメソッド名になっているが、RDBへのinsertのトランザクションの開始やコミットのことではない)
OutputPluginのresumeメソッドは、引数がtransactionメソッドとちょっと違うだけ。
@Override public ConfigDiff resume(TaskSource taskSource, Schema schema, int taskCount, Control control) { PluginTask task = TASK_MAPPER.map(taskSource, PluginTask.class); control.run(task.toTaskSource()); return CONFIG_MAPPER_FACTORY.newConfigDiff(); }
AbstractJdbcOutputPluginの場合、transactionメソッドと同様に、前処理を行ってからcontrol.run()を呼び出し、 後処理をしてからConfigDiffを返すようになっている。
resumeをサポートしない場合は例外を返しておけばいいようだ。
throw new UnsupportedOperationException("example1 output plugin does not support resuming");
OutputPluginのcleanupメソッドは、後処理を行う。
@Override public void cleanup(TaskSource taskSource, Schema schema, int taskCount, List<TaskReport> successTaskReports) { PluginTask task = TASK_MAPPER.map(taskSource, PluginTask.class); 〜 }
AbstractJdbcOutputPluginの場合、 一時的に作ったテーブルがあれば、それを削除している。
OutputPluginのopenメソッドは、TransactionalPageOutputインスタンスを生成して返す。
@Override public TransactionalPageOutput open(TaskSource taskSource, Schema schema, int taskIndex) { return new Example1PageOutput(schema); }
TransactionalPageOutputの具象クラスは自分で用意する。(この例ではExample1PageOutput)
import org.embulk.spi.Column; import org.embulk.spi.ColumnVisitor; import org.embulk.spi.Exec; import org.embulk.spi.Page; import org.embulk.spi.PageReader; import org.embulk.spi.Schema; import org.embulk.spi.TransactionalPageOutput;
private static class Example1PageOutput implements TransactionalPageOutput { private final PageReader pageReader;
public Example1PageOutput(Schema schema) { // this.pageReader = new PageReader(schema); // 従来の方法 this.pageReader = Exec.getPageReader(schema); }
@Override public void add(Page page) { Schema schema = pageReader.getSchema(); List<Column> columns = schema.getColumns(); pageReader.setPage(page); while (pageReader.nextRecord()) { // TODO input/parserから渡された値を出力する for (Column column : columns) { column.visit(new ColumnVisitor() { @Override public void booleanColumn(Column column) { boolean value = pageReader.getBoolean(column); } @Override public void longColumn(Column column) { long value = pageReader.getLong(column); } @Override public void doubleColumn(Column column) { double value = pageReader.getDouble(column); } @Override public void stringColumn(Column column) { String value = pageReader.getString(column); } @Override public void timestampColumn(Column column) { // 新方式ではjava.timeのInstantを使う java.time.Instant value = pageReader.getTimestampInstant(column); } @Override public void jsonColumn(Column column) { org.msgpack.value.Value value = pageReader.getJson(column); } }); } } }
@Override public void finish() { // TODO 出力をフラッシュする }
@Override public void close() { pageReader.close(); }
@Override public void abort() { }
@Override public TaskReport commit() { // return Exec.newTaskReport(); // 従来の方法 return CONFIG_MAPPER_FACTORY.newTaskReport(); } }
タスクが成功するとcommit、失敗するとabortが呼ばれる。
closeはcommit/abortの前後に2回呼ばれるようだ。
自作プラグインをJUnitで実行するときに便利なクラスを作ってみた。
ビルドされたjarファイル類は公開リポジトリ―には置いていないので、現時点ではgit cloneしてMavenローカルリポジトリーにpublishする必要がある。
$ cd 〜/hm-embulk-tester $ ./gradlew publishToMavenLocal
使う側のbuild.gradleは以下のような感じ。
〜 repositories { mavenLocal() mavenCentral() } dependencies { 〜 testCompile "org.embulk:embulk-junit4:0.10.41" testCompile "io.github.hishidama.embulk:hm-embulk-tester:0.1.+" // https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api testCompile 'javax.xml.bind:jaxb-api:2.3.1' // Java11の場合 }
example1という名前のExample1OutputPluginクラスを実行するコードは、以下のような感じ。
import java.util.Arrays; import java.util.List; import org.embulk.config.ConfigSource; import org.junit.Test; import com.hishidama.embulk.tester.EmbulkPluginTester; import com.hishidama.embulk.tester.EmbulkTestParserConfig;
@Test public void test() { try (EmbulkPluginTester tester = new EmbulkPluginTester()) { tester.addOutputPlugin("example1", Example1OutputPlugin.class); tester.setInputTaskSize(2); List<String> inputList = Arrays.asList("abc,11", "def,22"); EmbulkTestParserConfig parser = tester.newParserConfig("csv"); parser.addColumn("c1", "string"); parser.addColumn("c2", "long"); ConfigSource out = tester.newConfigSource("example1"); tester.runOutput(inputList, parser, out); } }
Embulk0.11/1.0方式で作ったプラグインをembulkコマンドで実行する方法は(Embulk0.10.41時点では)提供されていない。
(従来の方式では、runの引数の-Lで自作プラグインの場所を指定するだけで実行できた)
が、ローカルのMavenリポジトリ―に置かれたモジュールを取り込む方法は用意されているので、それを使って実行することが出来る。
ただ、依存ライブラリーも全てローカルのMavenリポジトリ―に置いておく必要があるので、手間がかかる。
Dai MIKURUBEさんのEmbulk v0.11 でなにが変わるのか: ユーザーの皆様へを参考に、実行環境を準備する。
環境変数M2_REPOを定義する。(Mavenのローカルリポジトリーの場所を指定する)
Windowsの例 > set M2_REPO=%USERPROFILE%\.m2\repository 実質的には > set M2_REPO=C:\Users\hishidama\.m2\repository
JRubyのダウンロードサイトからjruby-completeのjarファイルをダウンロードする。
そして、ユーザーのホームディレクトリー(Windowsの場合は%USERPROFILE%)の下に「.embulk/
embulk.properties
」というファイルを作って、ダウンロードしたjruby-completeのjarファイルの場所を記載する。
jruby=file://C:/Users/hishidama/bin/embulk/0.10.41/jruby-complete-9.4.0.0.jar
Embulk本体と同じバージョンのembulk.gemをインストールする。
また、msgpack.gemもインストールする。
embulk gem install msgpack -v 1.1.0 embulk gem install embulk -v 0.10.41
ちなみに、embulk.propertiesにjrubyの指定を書かなかった場合、コマンドラインから指定することも出来る。
embulk -X jruby=file://C:/Users/hishidama/bin/embulk/0.10.41/jruby-complete-9.4.0.0.jar gem install msgpack -v 1.1.0 embulk -X jruby=file://C:/Users/hishidama/bin/embulk/0.10.41/jruby-complete-9.4.0.0.jar gem install embulk -v 0.10.41
自作プラグインをMavenのローカルリポジトリーに格納する。
cd 〜/embulk-output-example1 ./gradlew publishToMavenLocal
また、依存ライブラリーもMavenローカルリポジトリーに入っている必要がある。
依存ライブラリーはGradleのディレクトリーに入っているのでそこからコピーすればいいのだが、ディレクトリー構成が違うので、手でコピーするのは面倒くさい。
mvnコマンドを使って、一括してMavenローカルリポジトリーにダウンロードすることが出来る。
cd 〜/embulk-output-example1 mvn install -f build/publications/maven/pom-default.xml
参考: oker1007さんのEmbulk v0.11.0, v1.0に向けたMavenプラグインのCI環境構築とMavenプラグインの導入方法 (2021/5/28版)
javaコマンドでプラグインを実行する。
●Java8 java -jar 〜/embulk-0.10.41.jar -X plugins.output.example1=maven:com.hishidama.embulk:example1:0.1.0-SNAPSHOT run config.yml ●Java11(Windowsの例) java -cp "〜/jaxb-api-2.3.1.jar;〜/embulk-0.10.41.jar" org.embulk.cli.Main -X plugins.output.example1=maven:com.hishidama.embulk:example1:0.1.0-SNAPSHOT run config.yml ●Java11(ブートクラスパスを使う方法) java -Xbootclasspath/a:〜/jaxb-api-2.3.1.jar -jar 〜/embulk-0.10.41.jar -X plugins.output.example1=maven:com.hishidama.embulk:example1:0.1.0-SNAPSHOT run config.yml
in: type: file path_prefix: 〜 parser: type: csv columns: - {name: text, type: string} out: type: example1
自作プラグインを使う場合、そのjarファイルの場所をEmbulk本体に教えてやる必要がある。
Embulk0.10にはMavenローカルリポジトリーからjarファイルを読み込む機能がある。(依存ライブラリーも全て読み込む)
これを使う場合、「plugins.カテゴリー.名前
」というプロパティー(Embulk system property)で自作プラグインの場所を指定する。
example1という名前(type)のアウトプットプラグイン(カテゴリーがoutput)の場合、プロパティー名は「plugins.output.example1
」となる。
(config.ymlに「out: type: example1
」という記述があると、「plugins.output.example1
」プロパティーが使われるというわけだ)
プロパティーに指定する値は「maven:グループ名:名前:バージョン
」。
グループ名が「com.hishidama.embulk」、プラグインの名前(type)がexample1、バージョンが0.1.0-SNAPSHOTの場合、「maven:com.hishidama.embulk:example1:0.1.0-SNAPSHOT
」となる。
(名前の部分はアーティファクトIDの「embulk-output-example1」を書く方が自然な気がするが、そうはなっていない)
なお、プロパティーは引数の-Xで指定する他に、embulk.propertiesで指定する方法が使える。
jruby=file://C:/Users/hishidama/bin/embulk/0.10.41/jruby-complete-9.4.0.0.jar
plugins.output.example1=maven:com.hishidama.embulk:example1:0.1.0-SNAPSHOT
実行する際に-Xでplugins.output.example1を指定する必要が無くなる。
java -jar 〜/embulk-0.10.41.jar run config.yml
「embulk run config.yml
」のような従来の実行方法を使うと、警告が出る。
================================== [ NOTICE ] ================================== Embulk will not be executable as a single command, such as 'embulk run'. It will happen at some point in v0.11.*. Get ready for the removal by running Embulk with your own 'java' command line. Running Embulk with your own 'java' command line has already been available. For instance in Java 1.8 : java -XX:+AggressiveOpts -XX:+UseConcMarkSweepGC -jar embulk-X.Y.Z.jar run ... java -XX:+AggressiveOpts -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xverify:none -jar embulk-X.Y.Z.jar guess ... See https://github.com/embulk/embulk/issues/1496 for the details. ================================================================================
embulkコマンドは非推奨になったらしい。
java -jarでEmbulk本体のjarファイルを指定して実行する。
org.embulk.config.ConfigException: OutputPlugin 'example1' is not found.
自作プラグインを使うには「plugins.カテゴリー.名前
」というプロパティーを指定する必要がある。
また、その他の原因(依存ライブラリーが見つからないとか)でプラグインが初期化できない場合もこのエラーになる。
(依存ライブラリーが見つからない場合でも「'example1' is not found
」というメッセージが出るのは混乱の元だが^^;)
自作プラグインをMavenローカルリポジトリーから読み込む場合、依存ライブラリーも全てMavenローカルリポジトリーから読み込まれる。
依存ライブラリーがMavenローカルリポジトリーから見つからない場合は以下のようなエラーになる。
2023-01-06 12:01:52.086 +0900 [WARN] (0001:transaction): Plugin maven:com.hishidama.embulk:example1:0.1.0-SNAPSHOT specified in "plugins.output.example1" was not found. Falling back to "plugins.default.output.example1". org.embulk.deps.maven.MavenArtifactNotFoundException: Maven artifact "org.embulk:embulk-util-config:jar:0.3.2" is not found: at "C:\Users\hishidama\.m2\repository" ("C:\Users\hishidama\.m2\repository"). at org.embulk.deps.maven.MavenArtifactFinderImpl.findMavenArtifact(MavenArtifactFinderImpl.java:111) at org.embulk.deps.maven.MavenArtifactFinderImpl.findMavenPluginJarsWithDirectDependencies(MavenArtifactFinderImpl.java:84) at org.embulk.plugin.maven.MavenPluginRegistry.findPluginPaths(MavenPluginRegistry.java:110) at org.embulk.plugin.maven.MavenPluginRegistry.lookup(MavenPluginRegistry.java:65) at org.embulk.plugin.maven.MavenPluginSource.newPlugin(MavenPluginSource.java:33) at org.embulk.plugin.PluginManager.newPlugin(PluginManager.java:82) at org.embulk.spi.ExecSessionInternal.newPlugin(ExecSessionInternal.java:358) at org.embulk.spi.ExecInternal.newPlugin(ExecInternal.java:50) at org.embulk.exec.BulkLoader$ProcessPluginSet.(BulkLoader.java:442) at org.embulk.exec.BulkLoader.doRun(BulkLoader.java:516) at org.embulk.exec.BulkLoader.access$000(BulkLoader.java:36) at org.embulk.exec.BulkLoader$1.run(BulkLoader.java:353) at org.embulk.exec.BulkLoader$1.run(BulkLoader.java:350) at org.embulk.spi.ExecInternal.doWith(ExecInternal.java:26) at org.embulk.exec.BulkLoader.run(BulkLoader.java:350) at org.embulk.EmbulkEmbed.run(EmbulkEmbed.java:278) at org.embulk.EmbulkRunner.runInternal(EmbulkRunner.java:288) at org.embulk.EmbulkRunner.run(EmbulkRunner.java:153) at org.embulk.cli.EmbulkRun.runInternal(EmbulkRun.java:107) at org.embulk.cli.EmbulkRun.run(EmbulkRun.java:24) at org.embulk.cli.Main.main(Main.java:55) Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not find artifact org.embulk:embulk-util-config:jar:0.3.2 at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:423) at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:225) at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:202) at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:257) at org.embulk.deps.maven.MavenArtifactFinderImpl.findMavenArtifact(MavenArtifactFinderImpl.java:108) ... 20 common frames omitted Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact org.embulk:embulk-util-config:jar:0.3.2 at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:413) ... 24 common frames omitted 2023-01-06 12:01:52.095 +0900 [INFO] (0001:transaction): Embulk system property "plugins.default.output.example1" is not set. org.embulk.config.ConfigException: OutputPlugin 'example1' is not found.
Java11のjavaコマンドで実行すると、JAXBExceptionクラスが見つからないというエラーが出る。
java -jar 〜/embulk-0.10.41.jar run config.yml
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException at org.apache.bval.jsr303.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:268) at org.apache.bval.jsr303.ConfigurationImpl.prepare(ConfigurationImpl.java:258) at org.apache.bval.jsr303.ConfigurationImpl.doPrivBuildValidatorFactory(ConfigurationImpl.java:248) at org.apache.bval.jsr303.util.SecureActions$5.run(SecureActions.java:131) at org.apache.bval.jsr303.util.SecureActions$5.run(SecureActions.java:129) at org.apache.bval.jsr303.ConfigurationImpl.run(ConfigurationImpl.java:337) at org.apache.bval.jsr303.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:244) at org.embulk.deps.config.ModelManagerDelegateImpl.(ModelManagerDelegateImpl.java:42) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at org.embulk.deps.config.ModelManagerDelegate.of(ModelManagerDelegate.java:15) at org.embulk.config.ModelManager. (ModelManager.java:8) at org.embulk.EmbulkEmbed.createModelManager(EmbulkEmbed.java:525) at org.embulk.EmbulkEmbed. (EmbulkEmbed.java:86) at org.embulk.EmbulkEmbed. (EmbulkEmbed.java:46) at org.embulk.EmbulkEmbed$Bootstrap.initialize(EmbulkEmbed.java:185) at org.embulk.cli.EmbulkRun.runInternal(EmbulkRun.java:91) at org.embulk.cli.EmbulkRun.run(EmbulkRun.java:24) at org.embulk.cli.Main.main(Main.java:55) Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException at org.embulk.deps.SelfContainedJarAwareURLClassLoader.defineClassFromEmbulkSelfContainedJarFiles(SelfContainedJarAwareURLClassLoader.java:216) at org.embulk.deps.SelfContainedJarAwareURLClassLoader.access$000(SelfContainedJarAwareURLClassLoader.java:32) at org.embulk.deps.SelfContainedJarAwareURLClassLoader$1.run(SelfContainedJarAwareURLClassLoader.java:62) at org.embulk.deps.SelfContainedJarAwareURLClassLoader$1.run(SelfContainedJarAwareURLClassLoader.java:58) at java.base/java.security.AccessController.doPrivileged(Native Method) at org.embulk.deps.SelfContainedJarAwareURLClassLoader.findClass(SelfContainedJarAwareURLClassLoader.java:57) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ... 21 more
JAXBはJava11で標準ライブラリーから外された。
EmbulkはJAXBを使っているらしいので、Java11でそのまま実行するとこのエラーが出る。
解決策としては、クラスパスにjaxb-apiのjarファイルを追加してやればいいのだが、javaコマンドでは-cpと-jarを同時に指定できない(-cpが無視される)。
-jarを使うのを辞めるか、苦肉の策としてブートクラスパスを使う方法がある。
jaxb-apiのjarファイルは、build.gradleのdependenciesに定義を入れておけば、Gradleのディレクトリーにダウンロードされているはず。
●Windowsの例 java -cp "〜/embulk-0.10.41.jar;〜/jaxb-api-2.3.1.jar" org.embulk.cli.Main run config.yml
ブートクラスパスを使う例 java -Xbootclasspath/a:〜/jaxb-api-2.3.1.jar -jar 〜/embulk-0.10.41.jar run config.yml