Open Kapil-Bhattarai opened 5 years ago
@edvin Would you submit a draft PR (new GitHub feature released less than 24 hours ago) so we can subscribe to it and be notified when there's an update or it is merged?
We'll probably do a release or two before it's merged, but I'll make sure everybody knows as soon as something is ready to test. Unfortunately, I don't have much time these days, so things are moving slow.
Hi @edvin, sorry for bothering you. Can you (even roughly) estimate when a Java 11+ compatible version of TornadoFX will get released? Will such release still be compatible with Java 8, or will we need (for projects meant to run on both platforms) to use different releases?
Thanks
I can't, really. I have no time these days, and it will be like this for a couple of months more I suspect. The Java 11 version will not be backwards compatible, due to changes in both the JDK and the decoupled JavaFX. The upgrade path will be pretty simple though, a matter of swapping out the runtime and changing a few function calls due to depreciations being largely removed in the Java 11 version.
There are reflection accesses which won't be doable with the module system:
java.lang.reflect.InaccessibleObjectException: Unable to make protected javafx.collections.ObservableList javafx.scene.Parent.getChildren() accessible: module javafx.graphics does not "opens javafx.scene" to module tornadofx
java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)
java.base/java.lang.reflect.Method.setAccessible(Method.java:192)
tornadofx/tornadofx.FXKt.getChildrenReflectively(FX.kt:662)
So with Oracle seemingly having archived jdk8 (you have to log in to an Oracle account to download it now), how can a Kotlin programmer get involved in making this release happen? Is there a todo list we could tackle?
Most of what I have tested seems to work, so any help in actually testing it and pointing out issues would be great. We might be ready to do a snapshot release and let more people start testing!
@edvin if you could mark an RC release and push it on Central, I'd gladly test it on Alchemist (@vuksaa get ready)
OK, will get to it soon, in the middle of moving so I need a few days.
Would also give it a spin with our app.
FYI
repositories {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}
dependencies {
compile 'no.tornado:tornadofx:2.0.0-SNAPSHOT'
}
Thanks a lot for that repository! It now works with Java 11.
@simplesteph, is this package still compiled with Java 8 compatibility? I'd like to depend on a single tornadofx distribution for a software meant to run on both J8 and J11+.
@DanySK as mentioned above this is not possible.
@opensource21 I am mostly referring to providing code compiled with version 52.0. I actually guess it's not possible to do something else, AFAIK Kotlin can only compile Java 6 or Java 8 bytecode.
I believe we should invest some time (if someone has already, much better, but I missed details) into understanding if it is possible to provide a version of TornadoFX that works for both JavaFX8 and JavaFX11. The changes I personally made (but I was working on a JDK10 branch created by someone else) should not compromise compatibility with JFX8.
Of course this would require special care client side to override dependencies. And of course it would be not recommended nor supported Tornado-side. Yet, if no JDK9+ specific APIs are used (I do not know if they are, but given the kotlin stdlib covers most use cases it's fair to suppose they are not), and if there are no API changes besides the ones I worked on (which were mostly reflection issues), then there is some chance that TornadoFX 2.0.0 works on JavaFX8 as well.
@vuksaa I need you to give the snapshot a try on Alchemist. Make sure everything works with Java 11, if it does, take a chance and force Java 8, see what happens. I can help ironing out issues.
There are source incompatibilities. Take a look at DataGrid.kt. The current (8) master uses
import com.sun.javafx.scene.control.skin.CellSkinBase
While the jdk10 branch uses
import javafx.scene.control.skin.CellSkinBase
I see. No way then. Thanks!
Has there been progress with testing? I'd love to use a current version of OpenJFX! ☺
So far I am running without problems - if you'd like to take a look it's here . It set up for Java Modules with Java & FX 12, Gradle with Kotlin DSL, and fairly heavy coroutine use (including a ported version of TornadoFX's Command) so it's "bleeding edge" in a few ways. The UI itself is still fairly simple so I can't say you won't run into your own issues, but if you just need to get setup then I hope it is helpful.
Looks also good to me on jdk 11 + openjfx 12.0.2
Thank you! I'll give the snapshot version a try, then! 😀
Just finished porting my somewhat large (multi-module gradle) project to jdk11+. Some points I ran across:
javafx.application.Application
Image(resources["/logo.png"])
with a modular setup. Was failing with a NullPointerException, ie the resource could not be found. I tried several different path formats, and even using Image("file:logo.png")
did nothing.What finally helped me get it working was the openjfx samples
The "application" plugin was not necessary in IntelliJ, I only needed a run configuration that executed my main function.
The new TornadoFX version seems to work just fine from what I've found, after getting the kinks worked out of the whole jdk11 module and dependency mess.
Thank you for this valuable feedback. I'm close to porting a large app myself, but need help in porting changes from the J8 branch to the new branch. Once the port is complete we'll do a 2.0 release as soon as possible. It breaks my heart that I don't have time to work on this as much as I had before, and I always think that "now" will be the time that I can reengage, but projects keep coming in the way :(
About support of both Java 8 and 9+, this probably can be achieved with JEP-238 (multirelease JARs), but it will require some more work.
I'm not sure that will be worth it. I think we'll migrate to the 2.0 branch and keep adding bug fixes to the Java 8 branch once we've made the switch, but we'll keep the deployments separate. Less headache :)
Also, as far as I understand, consumers still will be able to use 1.7.x and place version 2.x.x classes to release 9 path by repacking TornadoFX JARs to single one, if they realy need it.
Any updates on a plan for tornadofx to support Java 11?
I'm currently using the 2.0.0-SNAPSHOT version without issue.
The jdk10 branch (which supports Java 11) was updated with all the changes from the main branch just recently, so feedback on this is what we need right now :)
Can you create a new snapshot version we can import?
On Sat, Oct 19, 2019 at 8:23 AM Edvin Syse notifications@github.com wrote:
The jdk10 branch (which supports Java 11) was updated with all the changes from the main branch just recently, so feedback on this is what we need right now :)
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/edvin/tornadofx/issues/899?email_source=notifications&email_token=AAPGH6JQYINME2QSUEMO2FDQPKRVHA5CNFSM4GRGZ2Z2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBXGS5Q#issuecomment-544106870, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAPGH6PBPR7MWEBM5AD54ZTQPKRVHANCNFSM4GRGZ2ZQ .
-- Ing. Dott. Danilo Pianini, PhD
Site: http://www.danilopianini.org/ Phone: +39 320 41 36 573 Hangouts: danilo.pianini@gmail.com
Yes :) Just pushed a new snapshot release with all the goodness @ruckustboom merged from master :) Now we have feature parity with TornadoFX 1, so unless there are serious issues with this snapshot we might push 2.0 real soon!
Please look at the two tickets I just created
Also look at the PR :)
On Sat, Oct 19, 2019 at 8:10 PM Edvin Syse notifications@github.com wrote:
Yes :) Just pushed a new snapshot release with all the goodness @ruckustboom https://github.com/ruckustboom merged from master :) Now we have feature parity with TornadoFX 1, so unless there are serious issues with this snapshot we might push 2.0 real soon!
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/edvin/tornadofx/issues/899?email_source=notifications&email_token=AAERLFSNHNWKNBDMK3TFST3QPNEPRA5CNFSM4GRGZ2Z2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBXZBSA#issuecomment-544182472, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAERLFRSNHLBS2MZ6F4U2WTQPNEPRANCNFSM4GRGZ2ZQ .
If it try to use combobox
on snapshot 2.0.0 version i get ClassNotFoundException: com.sun.javafx.scene.control.skin.ComboBoxBaseSkin
. Other functionality works pretty good
@VolodyaG That would be because ComboBoxBaseSkin
is in package javafx.scene.control.skin
in JavaFX 9+. Are you sure that you're using the correct SDK to compile? I had similar issues while unintentionally using JDK8 for my project with JavaFX11 dependencies.
@nlbuescher looks like you are right. Right now it works without any issues on java 11 with openjfx 13
Im using a tableview
and get the following error:
Oct 28, 2019 1:02:06 PM tornadofx.DefaultErrorHandler uncaughtException
SEVERE: Uncaught error
java.lang.reflect.InaccessibleObjectException: Unable to make field private double javafx.scene.control.TableView.contentWidth accessible: module javafx.controls does not "opens javafx.scene.control" to unnamed module @32dd6b31
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:176)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:170)
at tornadofx.adapters.TornadoFXNormalTable$contentWidthField$2.invoke(TornadoFXTables.kt:66)
at tornadofx.adapters.TornadoFXNormalTable$contentWidthField$2.invoke(TornadoFXTables.kt:51)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at tornadofx.adapters.TornadoFXNormalTable.getContentWidthField(TornadoFXTables.kt)
at tornadofx.adapters.TornadoFXNormalTable.getContentWidth(TornadoFXTables.kt:70)
at tornadofx.SmartResizeKt.resizeCall(SmartResize.kt:378)
at tornadofx.SmartResize.call(SmartResize.kt:46)
at tornadofx.SmartResize.call(SmartResize.kt:44)
at javafx.controls/javafx.scene.control.TableView$7.invalidated(TableView.java:915)
at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.controls/javafx.scene.control.TableView.setColumnResizePolicy(TableView.java:895)
at Tornado$root$1.invoke(Main.kt:42)
at Tornado$root$1.invoke(Main.kt:32)
at tornadofx.ItemControlsKt.tableview(ItemControls.kt:1186)
at Tornado.<init>(Main.kt:39)
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 java.base/java.lang.Class.newInstance(Class.java:584)
at tornadofx.FXKt.find(FX.kt:437)
at tornadofx.FXKt.find$default(FX.kt:426)
at tornadofx.App.start(App.kt:83)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:834)
Code...
class Person(name: String, age: Int) {
val nameProperty = SimpleStringProperty()
var name by nameProperty
val ageProperty = SimpleIntegerProperty()
var age by ageProperty
init {
this.name = name
this.age = age
}
}
class Tornado: View() {
private val persons = FXCollections.observableArrayList(
Person("Craig Tadlock", 41),
Person("Bob Wiley", 22),
Person("Alice Frank", 34)
)
override val root = tableview(persons) {
column("NAME", Person::name)
column("AGE", Person::age)
columnResizePolicy = SmartResize.POLICY
}
}
class TornadoApp : App(Tornado::class)
fun main() {
Application.launch(TornadoApp::class.java)
}
This error only happens when the line columnResizePolicy = SmartResize.POLICY
is in place. The code is trying to access a private field contentWidthField
which is not allowed. No idea the appropriate resolution to this.
I think I had the same problem as @ctadlock with the latest build of tornadofx running on Adopt Open JDK 11 and JavaFX 11.
Mine is a large project transitioning to Java 11, so I couldn't immediately pin down exactly what caused it. I was using the Maven Repo for implementation("no.tornado:tornadofx:2.0.0-SNAPSHOT")
which must have updated to the later build of 2.0.0-SNAPSHOT and it was working well, until one day it didn't. I pulled down the tornadojx source from github and rebuilt from hash 7f06a351 and it works again.
I love TornadoFX and know 2.0.0 is a work in progress, so please let me know if there is anything else I can provide to help fix the issue.
Here is my stack trace:
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected javafx.collections.ObservableList javafx.scene.Parent.getChildren() accessible: module javafx.graphics does not "opens javafx.scene" to unnamed module @32330971
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:192)
at tornadofx.FXKt.getChildrenReflectively(FX.kt:684)
at tornadofx.FXKt.getChildList(FX.kt:675)
at tornadofx.FXKt.addChildIfPossible(FX.kt:613)
at tornadofx.FXKt.addChildIfPossible$default(FX.kt:499)
at tornadofx.LayoutsKt.vbox(Layouts.kt:432)
at tornadofx.LayoutsKt.vbox$default(Layouts.kt:144)
Im using a
tableview
and get the following error:Oct 28, 2019 1:02:06 PM tornadofx.DefaultErrorHandler uncaughtException SEVERE: Uncaught error java.lang.reflect.InaccessibleObjectException: Unable to make field private double javafx.scene.control.TableView.contentWidth accessible: module javafx.controls does not "opens javafx.scene.control" to unnamed module @32dd6b31 at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280) at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:176) at java.base/java.lang.reflect.Field.setAccessible(Field.java:170) at tornadofx.adapters.TornadoFXNormalTable$contentWidthField$2.invoke(TornadoFXTables.kt:66) at tornadofx.adapters.TornadoFXNormalTable$contentWidthField$2.invoke(TornadoFXTables.kt:51) at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) at tornadofx.adapters.TornadoFXNormalTable.getContentWidthField(TornadoFXTables.kt) at tornadofx.adapters.TornadoFXNormalTable.getContentWidth(TornadoFXTables.kt:70) at tornadofx.SmartResizeKt.resizeCall(SmartResize.kt:378) at tornadofx.SmartResize.call(SmartResize.kt:46) at tornadofx.SmartResize.call(SmartResize.kt:44) at javafx.controls/javafx.scene.control.TableView$7.invalidated(TableView.java:915) at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112) at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147) at javafx.controls/javafx.scene.control.TableView.setColumnResizePolicy(TableView.java:895) at Tornado$root$1.invoke(Main.kt:42) at Tornado$root$1.invoke(Main.kt:32) at tornadofx.ItemControlsKt.tableview(ItemControls.kt:1186) at Tornado.<init>(Main.kt:39) 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 java.base/java.lang.Class.newInstance(Class.java:584) at tornadofx.FXKt.find(FX.kt:437) at tornadofx.FXKt.find$default(FX.kt:426) at tornadofx.App.start(App.kt:83) at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428) at java.base/java.security.AccessController.doPrivileged(Native Method) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427) at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174) at java.base/java.lang.Thread.run(Thread.java:834)
Code...
class Person(name: String, age: Int) { val nameProperty = SimpleStringProperty() var name by nameProperty val ageProperty = SimpleIntegerProperty() var age by ageProperty init { this.name = name this.age = age } } class Tornado: View() { private val persons = FXCollections.observableArrayList( Person("Craig Tadlock", 41), Person("Bob Wiley", 22), Person("Alice Frank", 34) ) override val root = tableview(persons) { column("NAME", Person::name) column("AGE", Person::age) columnResizePolicy = SmartResize.POLICY } } class TornadoApp : App(Tornado::class) fun main() { Application.launch(TornadoApp::class.java) }
UPDATE
This error only happens when the line
columnResizePolicy = SmartResize.POLICY
is in place. The code is trying to access a private fieldcontentWidthField
which is not allowed. No idea the appropriate resolution to this.
@ctadlock @gmatrangola After the implementation of JPMS, a field or method can only be accessed if its public and is a part of package which is explicitly exported from their module. This is true even in case of reflection and allows for strong encapsulation. ControlsFX has a WIKI page explaining the same.
In both your case, TornadoFX is trying to reflectively access fields/methods whose packages are not explicitly exported or are non-public. The exception is self explanatory. To overcome the issue, you need to pass the following JVM arguments to the java
command:
--add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED
and
--add-opens=javafx.graphics/javafx.scene=ALL-UNNAMED
Is there a list of issues that should be done to get release 2.0? Maybe Edvin could mark them with some label or tag.
I believe we're about there. What we need right now is actually somebody stepping up and taking over the release procedures, since I'm still going to be busy for quite some time. We could most probably start with a 2.0.0 with the current code base.
Does anybody have a working gradle.build example? I am trying to set it up and I am having problems with getting it to work. For example what should be jvmTarget, still 1.8? Any suggestions are greatly appreciated.
@arturhefczyc
build.gradle.kts
:
import java.nio.file.Files
import java.nio.file.OpenOption
import java.nio.file.StandardOpenOption
import java.util.stream.Collectors
plugins {
kotlin("jvm") version "1.3.70"
application
}
group = "delta"
version = "0.0.1.0-SNAPSHOT"
val tornadofxVersion: String by project // gradle.properties
repositories {
mavenCentral()
jcenter()
maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") }
}
application {
mainClassName = "delta.ApplicationMain"
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation("no.tornado", "tornadofx", tornadofxVersion)
testImplementation("io.kotlintest:kotlintest-runner-junit5:3.3.0")
}
tasks {
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
test {
useJUnitPlatform()
}
startScripts {
doLast {
// set JAVA_EXE=java.exe
windowsScript.toPath().let { path ->
val newLines = Files.lines(path)
.map { it.replace("java.exe", "javaw.exe") }
.collect(Collectors.toList())
.let { Files.write(path, it) }
}
// exec "$JAVACMD" "$@"
unixScript.toPath().let { path ->
val newValue = "nohup \"\$JAVACMD\" \"\$@\" </dev/null >$applicationName.log 2>&1 &"
Files.lines(path)
.map { it.replace("exec \"\$JAVACMD\" \"$@\"", newValue) }
.collect(Collectors.toList())
.let { Files.write(path, it) }
}
}
}
}
@SchweinchenFuntik thank you
Was 2.0 released or is it still in snapshot phase? What is the latest version of the snapshot?
We are using JDK 11 (it is not manageable to move up on the versions of the JDK, at the moment), and the latest Kotlin. I am looking for a TornadoFx release working on that architecture.
2.0 is not yet released, but the latest build is available at oss.sonatype.org, see details in the README.
@edvin any ETA for 2.0.0 release? It's holding back a large project of mine that needs to get released on Central. What is needed?
add-opens
@ctadlock @gmatrangola After the implementation of JPMS, a field or method can only be accessed if its public and is a part of package which is explicitly exported from their module. This is true even in case of reflection and allows for strong encapsulation. ControlsFX has a WIKI page explaining the same.
In both your case, TornadoFX is trying to reflectively access fields/methods whose packages are not explicitly exported or are non-public. The exception is self explanatory. To overcome the issue, you need to pass the following JVM arguments to the
java
command:--add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED
and
--add-opens=javafx.graphics/javafx.scene=ALL-UNNAMED
not work for me;
--add-opens=javafx.controls/javafx.scene.control=tornadofx --add-opens=javafx.graphics/javafx.scene=tornadofx
works for me
smartResize() work not properly on java11/14 tornadofx2.0.0-snapshot like below
jdk8 works very well on tornadofx 1
@gmatrangola have you met this problem?
No, not yet. There is a Java 11 branch called jdk10 which will eventually become the official Java 11 compatible release, but I’m too pressed for time to complete it right now myself. It is working for everything I’ve tested it against, but it still needs more testing.