b_camphart
b_camphart

Reputation: 76

Getting unsupported major.minor version error when packaging tornadofx app

I've been developing a Tornadofx app for a couple months now. It runs just fine within the IDE (intellij ultimate, win 10), but now that I need to create an actual executable jar for other people to run it, I cannot seem to get it to work.

I'm using the openfx gradle plugin to automatically gather the javafx dependencies and provide the application/run task, which I've been utilizing during development. The documentation there also has you include org.beryx.jlink as a plugin for this final packaging process. This being a tornadofx app, I've written the entire thing in Kotlin. The problem I'm having now is that when I run the jlink, jlinkZip, or jpackage tasks (which I'm assuming would provide me with a distributable build), I'm receiving the error "Unsupported major.minor version 56.0."

I did some digging, thought, "maybe I need to update my jdk from 12 to 14" so I installed openjdk14 and now the error is "Unsupported major.minor version 58.0." So, clearly the problem is that my jdk is too updated...? I'm not sure. However, I don't know what version of the jdk I need to get this to build. I'm just not sure where to go from here. Some other research I've done has stated that jlink doesn't work with kotlin, but that the 'org.beryx.jlink' gradle plugin is "Badass jlink" and can work with Kotlin.

For further background, I have multiple sub-modules and a separately built internal core library, so there are a lot of pieces to build and put together. However, each submodule build.gradle looks something like this:

apply from: "$rootDir/kotlin-module.gradle"
apply from: "$rootDir/local-repositories.gradle" // helps resolve the local version of the core module.

dependencies {
    implementation "<--anonymized core module-->"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3"
    testImplementation 'io.cucumber:cucumber-java8:5.5.0'
    testImplementation 'io.cucumber:cucumber-junit:5.5.0'

    implementation project(":application")
    implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.61"
}

configurations {
    cucumberRuntime {
        extendsFrom testImplementation
    }
}

task cucumber() {
    dependsOn assemble, compileTestJava
    doLast {
        javaexec {
            main = "io.cucumber.core.cli.Main"
            classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
            args = ['--plugin', 'pretty', '--add-plugin', 'html:build/cucumber/html-report', '--glue', '<-- root package name -->', 'src/test/resources/features', '--strict']
        }
    }
}

while the kotlin-module.gradle file looks like this:

apply plugin: 'kotlin'

group '<-- anonymized group name -->'
version '0.1.0'

repositories {
    mavenCentral()
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.6.0'
    testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}

compileKotlin {
    kotlinOptions.jvmTarget = "13" // version issue here?
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "13" // version issue here?
}

test {
    useJUnitPlatform()
}

The actual submodule that includes javafx and tornadofx looks like this:

plugins {
    id 'java'
    id 'application'
    id 'org.jetbrains.kotlin.jvm'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'org.beryx.jlink' version '2.12.0'
    id 'edu.sc.seis.launch4j' version '2.4.6'
    id 'no.tornado.fxlauncher' version '1.0.20'
}

apply from: "$rootDir/kotlin-module.gradle"
apply from: "$rootDir/local-repositories.gradle"

repositories {
    jcenter()
}

dependencies {
    implementation "<--anonymized core module-->"

    implementation project(":application")
    implementation project(":data")
    implementation project(":gui")
    implementation "no.tornado:tornadofx:1.7.19"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-javafx:1.3.3"
    testImplementation 'io.cucumber:cucumber-java8:5.5.0'
    testImplementation 'io.cucumber:cucumber-junit:5.5.0'

    implementation "de.jensd:fontawesomefx-commons:11.0"
    implementation "de.jensd:fontawesomefx-controls:11.0"
    implementation "de.jensd:fontawesomefx-fontawesome:4.7.0-11"
    implementation "de.jensd:fontawesomefx-materialicons:2.2.0-11"
    implementation "de.jensd:fontawesomefx-emojione:2.2.7-11"
}

javafx {
    version = "14"
    modules = [ 'javafx.controls', 'javafx.fxml'/*, 'javafx.web', 'javafx.swing'*/ ]
}

jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = '<-- name of root module -->'
    }
}

mainClassName = '<-- package.path.to.kotlin.class.extending.tornadofx.Application -->'

launch4j {
    mainClassName = '<-- package.path.to.kotlin.class.extending.tornadofx.Application -->'
}

configurations {
    cucumberRuntime {
        extendsFrom testImplementation
    }
}

task cucumber() {
    dependsOn assemble, compileTestJava
    doLast {
        javaexec {
            main = "io.cucumber.core.cli.Main"
            classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
            args = ['--plugin', 'pretty', '--glue', '<-- root package name -->', 'src/test/resources/features', '--strict']
        }
    }
}

And finally, the parent build.gradle file:

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.70'
}

group '<-- anonymized group name -->'
version '0.1.0'

repositories {
    mavenCentral()
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"

    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.6.0'
    testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}

compileKotlin {
    kotlinOptions.jvmTarget = "13" // version issue here?
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "13" // version issue here?
}

test {
    useJUnitPlatform()
}

I'm really hoping someone has some insight into what else I can do to get this to build. This is really confusing to me because I've been building it and running it within the IDE no problem this entire time.

Upvotes: 0

Views: 577

Answers (2)

David Miller
David Miller

Reputation: 787

I noticed that org.beryx.jlink plugin only works with Java 11, and with Java 14 I got this error:

Execution failed for task ':createMergedModule'.
> Unsupported major.minor version 58.0

And so to make it work I ran java 11 jlink. In my build.gradle (gradle-6.3) I used this:

jlink {    
   javaHome = '/usr/lib/jvm/jdk-11.0.6+10'
   ......
}

and specified this for jpackage to pick up the java 14 version:

jpackage {
     jpackageHome = '/usr/lib/jvm/jdk-14+36'
     ......
}

Also used this version:

plugins {
    id "org.beryx.jlink" version "2.17.4"
}

Hope this helps.

Upvotes: 1

Cisco
Cisco

Reputation: 22952

Gradle 6.3 is the latest release (as of this comment) and is also the first release to support Java 14. Simply upgrade your Gradle wrapper:

./gradlew wrapper --gradle-version=6.3

https://docs.gradle.org/6.3/release-notes.html

Upvotes: 2

Related Questions