OmixVisualization / qtjambi

QtJambi is a wrapper for using Qt in Java.
http://www.qtjambi.io
Other
365 stars 43 forks source link

QtJambi does not build from sources using JDK 21 #168

Closed wolfseifert closed 11 months ago

wolfseifert commented 1 year ago

Describe the bug QtJambi does not build from sources using JDK 21 because JDK 21 adds some methods to java.util.List and java.util.Deque.

To Reproduce Steps to reproduce the behavior:

  1. Use JDK 21
  2. ant all [javac] /home/wolfgang/qtjambi/src/java/modules/qtjambi/Qt6/io/qt/core/QStack.java:44: Fehler: Die Typen Deque<E#1> und List<E#2> sind inkompatibel. [javac] public class QStack extends QList implements Deque [javac] ^ [javac] Klasse QStack erbt nicht verwandte Standardwerte für reversed() von Typen Deque und List [javac] Dabei sind E#1,E#2,T Typvariablen: [javac] E#1 erweitert Object, deklariert in Schnittstelle Deque [javac] E#2 erweitert Object, deklariert in Schnittstelle List [javac] T erweitert Object, deklariert in Klasse QStack [javac] 1 Fehler

Expected behavior QtJambi should build from sources using latest LTS JDK 21.

System (please complete the following information):

Patch The following patch.txt could help to fix the issue. It also fixes a problem with the ant build.

To make the QtJambi build a success I also had to patch one of the generated classes while building...

omix commented 1 year ago

I think, this is expected for QList:

public QList<T> reversed(){
    QList<T> result = new QList<>(elementMetaType());
    result.reserve(size());
    for(T t : this) {
        result.add(0, t);
    }
    return result;
}

And this for QStack:

public QStack<T> reversed(){
    QStack<T> result = new QStack<>(elementMetaType());
    result.reserve(size());
    for(T t : this) {
        result.add(0, t);
    }
    return result;
}
omix commented 1 year ago

To make the QtJambi build a success I also had to patch one of the generated classes while building... What classes did you adapt? I only see QSignalSpy as a possible candidate.

omix commented 1 year ago

Why did you patch src/java/modules/qtjambi/build.xml? The change doen't make a difference.

wolfseifert commented 1 year ago

Yes, QSignalSpy was the guy.

Ant says that mkdir is not allowed inside trycatch. This will only happen if extjars does not exist yet.

omix commented 1 year ago

ok, I added the code. and will publish it for Qt 6.6 as soon as it is available.

wolfseifert commented 1 year ago

Also QtJambi 6.6.0 does not build from sources using JDK 21 because of QSignalSpy. After patching QSignalSpy at build time I had success. I then published QtJambi 6.6.0 into my local sonatype and started it using from my application code. When doing this I found out, that the application code also needs to run on Java 21 now because of java.util.SequencedCollection loaded at runtime. So compiling QtJambi 6.6.0 with JDK 21 means to force user code to use Java 21. This is something to be thought of and I wanted to mention here.

omix commented 1 year ago

I don't understand what's wrong with QSignalSpy when generating with Java21. the reversed() is generated as it is required. What's additionally wrong with it?

omix commented 1 year ago

Nevertheless, reversed() does not work as expected. It throws IndexOutOfBoundsException because QList.add(0, value) does not work. That's an error and I'll fix it.

omix commented 1 year ago

I'm compiling the generated Java code with JDK21 without any issue.

omix commented 1 year ago

I found out, that the application code also needs to run on Java 21 now because of java.util.SequencedCollection loaded at runtime. So compiling QtJambi 6.6.0 with JDK 21 means to force user code to use Java 21. This is something to be thought of and I wanted to mention here.

I can confirm this and it's not avoidable. QList class code refers to java.util.SequencedCollection because it overrides one of its methods.

wolfseifert commented 1 year ago

I get this compile-impl: [echo] Compiling java classes: /home/wolfgang/qtjambi/src/java/qtjambi.test excludes: [copy] Copying 13 files to /home/wolfgang/qtjambi/6.6.0/build/java-src/qtjambi.test [echo] Compiling java classes: /home/wolfgang/qtjambi/6.6.0/build/generator/java/qtjambi.test:/home/wolfgang/qtjambi/src/java/modules/qtjambi.test classpath: qtjambi-6.6.0.jar [javac] Compiling 1 source file to /home/wolfgang/qtjambi/6.6.0/build/java/qtjambi.test [javac] /home/wolfgang/qtjambi/6.6.0/build/generator/java/qtjambi.test/io/qt/test/QSignalSpy.java:665: Fehler: removeLast() in QSignalSpy kann nicht removeLast() in List implementieren [javac] public final void removeLast() { [javac] ^ [javac] Rückgabetyp void ist nicht mit @io.qt.NonNull List<@io.qt.Nullable Object> kompatibel [javac] Dabei ist E eine Typvariable: [javac] E erweitert Object, deklariert in Schnittstelle List [javac] /home/wolfgang/qtjambi/6.6.0/build/generator/java/qtjambi.test/io/qt/test/QSignalSpy.java:657: Fehler: removeFirst() in QSignalSpy kann nicht removeFirst() in List implementieren [javac] public final void removeFirst() { [javac] ^ [javac] Rückgabetyp void ist nicht mit @io.qt.NonNull List<@io.qt.Nullable Object> kompatibel [javac] Dabei ist E eine Typvariable: [javac] E erweitert Object, deklariert in Schnittstelle List [javac] 2 Fehler [subant] Leaving directory: /home/wolfgang/qtjambi/src/java/modules/qtjambi.test BUILD FAILED

To fix this issue wile building I removed public final void removeFirst() { list().removeFirst(); } public final void removeLast() { list().removeLast(); } after generation and before compilation

omix commented 1 year ago

In fact, removeFirst/Last() in QSignalSpy must not be void but. This is a relict of Qt5 and should have been changed in Qt6.

omix commented 1 year ago

Ok, I found a way to let a JDK21-compiled qtjambi library be compatible for <=JDK20. Therefore, I removed reversed() from QList. It defaults to List.reversed(). QStack overrides Deque.reversed(). removeFirst()/removeLast() get as return type T.

omix commented 11 months ago

QtJambi 6.6.1 has not different sources for JDK >=21 and <21. QStack does not extend Deque interface when compiling with JDK 21. By this the binaries remain compatible to previous Java versions. In those rare cases where developers used QStack as Deque they need to change their code to using QStack.asDeque() instead.