TornadoFXで書いたアプリをJARファイルにまとめる

 **※別の方法を[こちら](https://qiita.com/heyhachi/items/9dfd0082d663a6331afd)でまとめました。**

## 前置き
TornadoFXでアプリを作成したあと、JARファイルを生成する手段をまとめます。Javaでの業務経験がないままいきなりKotlinを触っている人間が書いているので、間違いやあたりまえの内容が書かれているかもしれません。

## 環境
 * Windows10 Pro ver1809
 * IntelliJ IDEA Ultimate 2019.1.2
    * Kotlin v1.3.31-release-IJ2019.1-1
    * TornadoFX v1.7.17.2
 * openjdk version "1.8.0_202"
    * OpenJDK Runtime Environment Corretto-8.202.08.2 (build 1.8.0_202-b08)
    * OpenJDK 64-Bit Server VM Corretto-8.202.08.2 (build 25.202-b08, mixed mode)

## 先に結論
[FXLauncher](https://github.com/edvin/fxlauncher)というGradleプラグインを使うことで可能でした。インストーラーまで作成できるのですが、手元の環境ではインストーラーでインストールしたアプリケーションが起動できませんでした。MacOSは未検証です。

## 手順１
まずはIntelliJでTornadoFXのプロジェクトを作ります。今回はProject SDK 1.8でtornadofx-gradle-projectで進めます。そのままビルドすれば簡単なHello Worldアプリとなっています。

なお、プロジェクト作成後に”Could not determine java version from '11.0.2'.”などと怒られる場合は、[こちらの記事](https://qiita.com/Atsushi_/items/72361cb91f84eb22e149)のgradle-wrapper.propertiesを参考に手を入れると解決しました。

## 手順２
FXLauncherを導入します。[Quick Start](https://github.com/edvin/fxldemo-gradle)の[build.gradle](https://github.com/edvin/fxldemo-gradle/blob/master/build.gradle)を参考に自身のbuild.gradleを編集します。

```gradle

buildscript {
    ext.kotlin_version = "1.2.60"
    ext.tornadofx_version = "1.7.17"
    ext.junit_version = "5.1.0"

    repositories {
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.junit.platform:junit-platform-gradle-plugin:1.1.0"
        classpath 'no.tornado:fxlauncher-gradle-plugin:1.0.20'
    }
}

apply plugin: "kotlin"
apply plugin: "application"
apply plugin: "org.junit.platform.gradle.plugin"
apply plugin: 'java'
apply plugin: 'no.tornado.fxlauncher'

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

repositories {
    mavenLocal()
    mavenCentral()
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots/"
    }
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

    compile "no.tornado:tornadofx:$tornadofx_version"
    compile 'org.controlsfx:controlsfx:8.40.12'

    testCompile "org.junit.jupiter:junit-jupiter-api:$junit_version"
    testRuntime "org.junit.jupiter:junit-jupiter-engine:$junit_version"
}

mainClassName = "com.example.demo.app.MyApp"

fxlauncher {
    applicationVendor 'My Company'
    // Base URL where you will host the application artifacts
    applicationUrl 'http://localhost.localdomain/'
    applicationMainClass mainClassName
    acceptDowngrade false
    // Optional scp target for application artifacts hosted at the above url
    //deployTarget 'w48839@fxldemo.tornado.no:fxldemo'
}


jar {
    manifest {
        attributes(
                "Class-Path": configurations.compile.collect { it.getName() }.join(" "),
                "Main-Class": mainClassName
        )
    }
    from(configurations.compile.collect { entry -> zipTree(entry) }) {
        exclude "META-INF/MANIFEST.MF"
        exclude "META-INF/*.SF"
        exclude "META-INF/*.DSA"
        exclude "META-INF/*.RSA"
    }
}

version = "1.0.0" // これが無いと gradle generateNativeInstaller で怒られる
```

## 手順３
コンソールで以下を実行します。

```shell
gradle generateNativeInstaller
```

無事成功すると"project root/build/fxlauncher/"にjarファイルが出来上がります。インストーラーを作成したい場合はコンソール上で指定されたアプリケーションを別途インストールし、パスを通す必要があります。

* [Inno Setup](http://www.jrsoftware.org/isinfo.php)
* [Wix Toolset](https://wixtoolset.org/)

なお、Inno Setupはバージョン5でないとビルド時にエラーが出るようでした。

前述しましたが、無事インストーラーが出来てもそのインストーラーでインストールしたアプリケーションは以下のようなエラーを吐いて起動しません。

```
java.lang.ClassNotFoundException: com.example.demo.app.MyApp
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at fxlauncher.AbstractLauncher.createApplicationEnvironment(AbstractLauncher.java:170)
	at fxlauncher.Launcher.lambda$start$0(Launcher.java:152)
	at java.lang.Thread.run(Thread.java:748)
```

メインクラスが見つけられていないようなので、何かしらの設定ミスかとは思いますが、まだ解消できていません。"build/fxlauncher/"に出来上がったjarファイル自体は起動できるので、インストーラーのビルドで上手くいっていないようです。ドキュメントを熟読する必要がありますね。