Help us understand the problem. What is going on with this article?

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

※別の方法をこちらでまとめました。

前置き

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というGradleプラグインを使うことで可能でした。インストーラーまで作成できるのですが、手元の環境ではインストーラーでインストールしたアプリケーションが起動できませんでした。MacOSは未検証です。

手順1

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

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

手順2

FXLauncherを導入します。Quick Startbuild.gradleを参考に自身のbuild.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 で怒られる

手順3

コンソールで以下を実行します。

gradle generateNativeInstaller

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

なお、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ファイル自体は起動できるので、インストーラーのビルドで上手くいっていないようです。ドキュメントを熟読する必要がありますね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした