edvin / tornadofx

Lightweight JavaFX Framework for Kotlin
Apache License 2.0
3.68k stars 271 forks source link

Questions regarding setup with OpenJDK 14 #1309

Closed bastianraschke closed 3 years ago

bastianraschke commented 3 years ago

First thanks for the great TornadoFX project ❤️

I use Ubuntu 20.04 and have OpenJDK 8, 11 and 14 installed.

My project uses:

In IntelliJ I configured the OpenJDK 14 as SDK for this project.

Now my questions:

  1. The README says it is not compatible with Java 9+ but why it works with OpenJDK 14?
  2. The README also mentions that it is necessary to set kotlinOptions.jvmTarget = "1.8", but the guide says if I use OpenJDK with the OpenJFX Gradle plugin I need to set it to kotlinOptions.jvmTarget = "11". In my case I should set it to kotlinOptions.jvmTarget = "14" right?
  3. I read the JavaFX version is tied to the JDK version - why I can use JavaFX 15.0.1 with OpenJDK 14?

Thank you very much for your help, Bastian

SchweinchenFuntik commented 3 years ago

javaFX 9+ https://github.com/edvin/tornadofx/tree/jdk10#snapshots-are-published-to-sonatype

bastianraschke commented 3 years ago

Hey @SchweinchenFuntik,

I know this branch and also read #899. But I did not add any repository except:

repositories {
    mavenLocal()
    mavenCentral()
}

So I think I use the stable TornadoFX 1.7.20 without Java 9+ support - but it seems to work with OpenJDK 14. This confuses me.

SchweinchenFuntik commented 3 years ago

The README says it is not compatible with Java 9+ but why it works with OpenJDK 14?

only part works, here the problem is not in tornadofx but in java 9 - jiswag (java modulation)

The README also mentions that it is necessary to set kotlinOptions.jvmTarget = "1.8", but the guide says if I use OpenJDK with the OpenJFX Gradle plugin I need to set it to kotlinOptions.jvmTarget = "11". In my case I should set it to kotlinOptions.jvmTarget = "14" right?

kotlinOptions.jvmTarget != javaTarget. This tells the Kotlin compiler which version of Java it compiles to, version 8 is in principle suitable for version 11 as well. It's just that the README is not updated as often

I read the JavaFX version is tied to the JDK version - why I can use JavaFX 15.0.1 with OpenJDK 14?

in theory you can use it, but you need to be careful. I would recommend using either the minimal version or compiling the app with the JDK. Java's backward compatibility is very good, so you can run Java 14 on Java 15 (with JavaFX it's the same), but you need to follow the changes, test and keep feedback from users

SchweinchenFuntik commented 3 years ago

So I think I use the stable TornadoFX 1.7.20 without Java 9+ support - but it seems to work with OpenJDK 14. This confuses me

you run something complex. JavaFX changed the classpaths, they used to be in the private package sun. *, In newer versions this has changed

bastianraschke commented 3 years ago

Okay thanks for that information. It sounds my approach is really a bad idea in terms of stability.

I really just want a setup that is easy and stable. I have no problems to use the OpenJDK 8. But if I do (and set the kotlinOptions.jvmTarget = "1.8" like recommended in the README), I got the error:

java.lang.UnsupportedClassVersionError: org/openjfx/gradle/JavaFXPlugin has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.

So I followed the guide and thought why not use OpenJDK 14 instead of 11 because it already contains the jpackage tool I need. Also JavaFX 11.0.2 was not suitable for me because rendering the GUI was completly broken on my Notebook without dedicated GPU (Intel Core i7-10510U): I found out the problem is first fixed in OpenJFX 13-ea+9. So I switched to JavaFX 14 or 15.

I really just want a setup that is stable as much as possible and I really struggle with the different constraints - what would you recommend to me to achieve maximum stability?

  1. Use OpenJDK 14 with jvmTarget = "14" and JavaFX 14.0.2.1
  2. Use OpenJDK 11 with jvmTarget = "11" and JavaFX 13-ea+9+
  3. Use the unstable snapshot branch with offical Java 10+ support?
SchweinchenFuntik commented 3 years ago

I really just want a setup that is stable as much as possible and I really struggle with the different constraints - what would you recommend to me to achieve maximum stability?

1

java.lang.UnsupportedClassVersionError: org/openjfx/gradle/JavaFXPlugin has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52

most likely you ran on the wrong jdk (most likely on jdk8). kotlinOptions.jvmTarget = "1.8" - does not apply to the JDK version, more precisely, this is the minimum JDK version that you want to support

SchweinchenFuntik commented 3 years ago

I really just want a setup that is stable as much as possible and I really struggle with the different constraints - what would you recommend to me to achieve maximum stability?

1

java.lang.UnsupportedClassVersionError: org/openjfx/gradle/JavaFXPlugin has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52

most likely you ran on the wrong jdk (most likely on jdk8). kotlinOptions.jvmTarget = "1.8" - does not apply to the JDK version, more precisely, this is the minimum JDK version that you want to support

example build.gradle.kts

import org.jetbrains.kotlin.daemon.common.OSKind.Companion.current
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.lang.ProcessHandle.current

plugins {
    kotlin("jvm") version "1.4.21"
    application
    id("org.openjfx.javafxplugin") version "0.0.9"
    id("org.beryx.runtime") version "1.12.1"
}

group = "group"
version = "1.0"

val appName = "appName"
val javafxVersion: String by rootProject.extra // gradle.properties
val kotlinxCoroutines: String by rootProject.extra

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

javafx {
    version = javafxVersion
    modules("javafx.controls", "javafx.fxml", "javafx.media", "javafx.swing", "javafx.web")
    configuration = "compileOnly"
}

application {
    mainClassName = "package.MainClassName"
}

runtime {
    imageDir.fileValue(project.file("$buildDir/$appName-${javafx.platform.classifier}"))
    imageZip.fileValue(project.file("$buildDir/distributions/$appName-${javafx.platform.classifier}.zip"))
    launcher {
        noConsole = true; runInBinDir = true
    }

    options.addAll("--strip-debug", "--compress", "2", "--no-header-files", "--no-man-pages")
    modules.addAll("java.desktop", "jdk.unsupported", "java.scripting", "java.logging", "java.xml", "java.sql", "jdk.localedata")
    modules.addAll("java.naming", "java.se", "jdk.charsets", "jdk.xml.dom")
    jpackage {
        val currentOs = org.gradle.internal.os.OperatingSystem.current()
        val imgType = when {
            currentOs.isWindows -> "ico"
            else -> "png"
        }
        imageOptions.addAll(listOf("--icon", "src/main/resources/icon/OSMD.$imgType"))
        installerOptions.addAll(listOf("--resource-dir", "src/main/resources", "--vendor", "Komfort-Jug", "--vendor", "$version"))
        if (currentOs.isWindows) {
            installerOptions.addAll(listOf("--win-per-user-install", "--win-dir-chooser", "--win-menu", "--win-shortcut", "--vendor", "Komfort Jug"))
        }
    }
}

dependencies {
    implementation("no.tornado", "tornadofx", "2.0.0-SNAPSHOT") 
    implementation("org.jetbrains.kotlinx", "kotlinx-coroutines-javafx", kotlinxCoroutines
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        jvmTarget = "11"
    }
}

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

I cut a little build script from my application (java and javafx 15)

bastianraschke commented 3 years ago

java.lang.UnsupportedClassVersionError: org/openjfx/gradle/JavaFXPlugin has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52

most likely you ran on the wrong jdk (most likely on jdk8). kotlinOptions.jvmTarget = "1.8" - does not apply to the JDK version, more precisely, this is the minimum JDK version that you want to support

Yes like I wrote ("I have no problems to use the OpenJDK 8. But if I do [...]") for testing I set the SDK to OpenJDK 8 in IntelliJ and got the error because the JavaFXPlugin requires a higher Java version than Java 8. This confused be because TornadoFX requires Java 8 and the plugin recommended in the TornadoFX guide does not work with OpenJDK 8.

I'm not totally sure why TornadoFX claims it does not support Java higher than 8 and it works for me. I unterstood that JavaFX was decoupled after Java 8 for modularisation reasons, so the JavaFX code was moved to the OpenJFX project, got a new package path (not com.sun.* anymore but javafx.*) and I need to get the OpenJFX components via the JavaFXPlugin Gradle plugin. So in IntelliJ I configure OpenJDK 14 and my project seems to work.

According to the source code e.g. of the Nodes.kt file for current TornadoFX and the JDK10-TornadoFX the import of TableColumnHeader for example changed because of the package path change after decoupling. So if I call a method that needs the TableColumnHeader import, e.g. EventTarget.isInsideRow() with current TornadoFX and OpenJDK 14 the import could not be found and the app crashes:

java.lang.NoClassDefFoundError: com/sun/javafx/scene/control/skin/TableColumnHeader
    at tornadofx.NodesKt.isInsideRow(Nodes.kt:488)

I guess this is the concrete problem why the README claims TornadoFX is not yet compatible with Java 9/10 right? Most stuff seems to work but all the code that uses com.sun.* imports crashes instantly when using with a JDK higher than 8? But why is the project even compiling if some imports could not be found?

SchweinchenFuntik commented 3 years ago

Yes like I wrote ("I have no problems to use the OpenJDK 8. But if I do [...]") for testing I set the SDK to OpenJDK 8 in IntelliJ and got the error because the JavaFXPlugin requires a higher Java version than Java 8. This confused be because TornadoFX requires Java 8 and the plugin recommended in the TornadoFX guide does not work with OpenJDK 8.

org.openjfx.javafxplugin - only for java fx 9+. for javafx 8 you need to take jdk from javafx.

I guess this is the concrete problem why the README claims TornadoFX is not yet compatible with Java 9/10 right?

Yes

But why is the project even compiling if some imports could not be found?

well, a question for the compiler) because the library code has already been compiled, and is working on the old runtime, but the new runtime of these classes is not present and the VM could not find / load them, so you have a crash in the runtime. Here it is worth reading how Jvm works

SchweinchenFuntik commented 3 years ago

I guess this is the concrete problem why the README claims TornadoFX is not yet compatible with Java 9/10 right?

even JavaFX itself claims that the versions of the libraries are not compatible, the breakdown is not due to modules, but due to fundamental changes in OpeJavaFX itself

bastianraschke commented 3 years ago

This makes sense with the already compiled library.

Thanks a lot for your answers :+1:

SchweinchenFuntik commented 3 years ago

if you have no questions, close. I also suggest connecting to the slack

bastianraschke commented 3 years ago

Alright.