Javafx, moduły i zewnętrzne bilbioteki (driftFX) - IllegalAccessException

0

Cześć,

Mam aplikację w JavieFX i chciałbym użyć bilioteki driftFX tak żeby móc przechwycić kontekst do renderowania na jakimś Node bezpośrednio przez OpenGL w GPU. Mam takie zależności:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<repositories>
    <repository>
        <id>eclipsefx</id>
        <url>https://repo.eclipse.org/content/groups/efxclipse/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>17.0.2</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>17.0.2</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.fx</groupId>
        <artifactId>org.eclipse.fx.drift</artifactId>
        <version>1.0.0.rc4</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

Oraz taki config w pomie do builda:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>16</source>
                <target>16</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-maven-plugin</artifactId>
            <version>0.0.7</version>
            <executions>
                <execution>
                    <!-- Default configuration for running with: mvn clean javafx:run -->
                    <id>default-cli</id>
                    <configuration>
                        <mainClass>com.example.windowedapp/com.example.windowedapp.HelloApplication</mainClass>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

No i prawilnie dodane module-info.java:

module com.example.windowedapp {
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.graphics;
    requires org.eclipse.fx.drift;
}

Po odpaleniu paru linijek jak zaleca producent dostaję jednak wyjątek IllegalAccessException:

Caused by: java.lang.IllegalAccessError: superclass access check failed: class org.eclipse.fx.drift.impl.NGDriftFXSurface (in module org.eclipse.fx.drift) cannot access class com.sun.javafx.sg.prism.NGNode (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.sg.prism to module org.eclipse.fx.drift

Czyli tak jakby ten kod biblioteki miał blokowany dostęp do klas JavaFX. Próbowałem kombinacji z różnymi wersjami JavaFX/Drifta i samego JDK (od 11 w górę) ale oczywiście przez moduły z 9 nie będzie to pewnie działać. Czy ktoś jest w stanie mi po ludzku wyjaśnić jak prostemu konsultantowi pracującemu na co dzień z 8 jak ten system modułów trzeba skonfigurować żeby takie sytuacje obsłużyć bo próbowałem eksportować swój pakiet do tego modułu javafx graphics czy do drifta ale za nic nie chce to działać. Niby rozumiem te importy ale mam wrażenie, że to dotyczy mojego source'a a nijak nie wpływa na to czego wymaga np. biblioteka X - strzelam że twórca tej biblioteki powinien wrzucić do module-info wszystko co potrzebuje i dać jakieś zależności np. w pom.

To co bym chciał osiągnąć to taki ekwiwalent jakbym miał cały source code biblioteki u siebie (np. tej drift) i po prostu dał requires to czy tamto z innej biblioteki (np. javafx moduł Y) :D

0

Generalnie musisz "otworzyć" javafx.graphics tak żeby twoja libka diffFX mogła grzebać tam refleksją.
Przy odpalaniu aplikacji dodaj arg command line dla JVM:

--add-opens javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED,com.example.windowedapp

a jakby to samo nie pomogło to jeszcze --add-exports

0

Dzięki za odpowiedź. Po tym dodaniu tego dostaję takie coś:

class com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot access class com.example.windowedapp.HelloApplication (in module com.example.windowedapp) because module com.example.windowedapp does not export com.example.windowedapp to module javafx.graphics

Natomiast po exporcie mojego pakietu czyli dodaniu do module-info.java takiego ustawienia:

module com.example.windowedapp {
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.graphics;
    requires org.eclipse.fx.drift;

    exports com.example.windowedapp; // mój pakiet
}

Dostaję pierwotny błąd

Caused by: java.lang.IllegalAccessError: superclass access check failed: class org.eclipse.fx.drift.impl.NGDriftFXSurface (in module org.eclipse.fx.drift) cannot access class com.sun.javafx.sg.prism.NGNode (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.sg.prism to module org.eclipse.fx.drift
1

Zrób open module, powinno przejść. Ja mam:

open module fxplayer {
  requires java.net.http;
  requires javafx.controls;
  requires javafx.graphics;
  requires javafx.fxml;
  requires javafx.media;
  requires logback.core;
  requires org.slf4j;
  requires com.google.common;
  requires com.google.guice;
  requires com.google.gson;
  requires com.github.benmanes.caffeine;
  requires jaudiotagger;
  requires com.fasterxml.jackson.annotation;
  requires com.fasterxml.jackson.core;
  requires com.fasterxml.jackson.databind;
  requires com.fasterxml.jackson.dataformat.xml;
  requires com.fasterxml.jackson.datatype.jdk8;
  requires com.fasterxml.jackson.datatype.jsr310;
  requires com.zaxxer.hikari;
  requires org.flywaydb.core;
  requires org.xerial.sqlitejdbc;
  requires org.jooq;
}
0

javafx.graphics does not export - musisz jeszcze dodać:

--add-exports javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED,com.example.windowedapp

lub zrobić jak radzi @scibi_92

Generalnie jak nie potrafisz użyć modułów to zrób downgrade to Javy 8 i starego JavaFX i nie będziesz miał takich problemów.

0

Niestety to samo... Teraz mam w jvmie:

--add-opens
javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED,com.example.windowedapp
--add-exports
javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED,com.example.windowedapp

Jak odpalam to sobie w IJ i generalnie importuje te klasy z JavaFX to każe mi dorzucić te exporty co wyżej do compiler options tak żeby mój moduł korzystał z tych klas:

screenshot-20220320175455.png

Dodałem to i w VM options i w sumie mogę używać tych klas u siebie w kodzie ale jak wywołuje klasę z driftFX, która pod spodem używa np. com.sun.javafx.sg.prism.NGNode to się sypie i leci wyjątek. Tak jakby zaimportował jarkę org.eclipse.fx.drift, utworzył sobie automatyczny moduł (bo zdaje się nie ma module-info.java) ale zignorował te exporty dla tego eclipsowego modułu (dla mojego działają ok).

Ostatecznie jak to nie zadziała to chyba poszukam innego rozwiązania bo nawet w sourcach tej biblioteki jest koment:

//Note: this implementation is against internal JavafX API

więc może to i tak troche kiepawo tego używać na dłuższą metę.

0

@lost: a próbowałes z open module?

1 użytkowników online, w tym zalogowanych: 0, gości: 1