JavaFX OpenJFX, SpringBoot und Gradle

Diskutiere OpenJFX, SpringBoot und Gradle im AWT, Swing, JavaFX & SWT Bereich.
L

lam_tr

Hallo zusammen,

hat jemand von euch schon eine fertige Konfiguration für OpenJFX11-14 mit SpringBoot in Gradle konfiguriert bekommen?

Ich habe die Gradle Datei von diesem Projekt angepasst und SpringBoot dependencies ergänzt
https://github.com/openjfx/samples/tree/master/HelloFX/Gradle

Danach bekomme ich compile error für JavaFX dependencies.

Vielleicht hat das jemand schon parat und kann es mit mir teilen.

Vielen Dank
lam

P.S. Dzim du hast sowas bestimmt oder :)
 
Zuletzt bearbeitet:
dzim

dzim

Warte mal... Mir ist da kürzlich ein Beispiel untergekommen:
https://blog.jetbrains.com/idea/2019/12/tutorial-reactive-spring-boot/

Konkreter hier:
https://blog.jetbrains.com/idea/201...spring-boot-a-javafx-spring-boot-application/
-> https://github.com/trishagee/jb-stock-client/tree/master/stock-ui
-> https://github.com/trishagee/jb-stock-client/blob/master/stock-ui/pom.xml

Code:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mechanitis</groupId>
    <artifactId>stock-ui</artifactId>
    <version>0.0.2-SNAPSHOT</version>
    <name>stock-ui</name>
    <description>JavaFX front-end for the stock prices application</description>

    <properties>
        <java.version>11</java.version>
        <javafx.version>13.0.1</javafx.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>com.mechanitis</groupId>
            <artifactId>stock-client</artifactId>
            <version>0.0.2-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
Du brauchst weder <artifactId>reactor-test</artifactId> (es sei denn, du möchtest den Reactive ReST Client von Spring Boot verwenden) noch <artifactId>stock-client</artifactId> (der ist spezifisch für das Beispiel hier).

War es das, was du suchtest?

PS: Nutze bitte das nächste Mal das @-Handle, dann bekomme ich auch eine Nachricht. ;) @lam_tr
 
L

lam_tr

Ich wusste doch... vielen Dank, ich werde es heute Abend testen *freu*.
 
L

lam_tr

Ich konnte es kaum erwarten und habe meine Mittagspause dafür vergnügt. Jetzt habe ich es mit Gradle hinbekommen, echt klasse.

@dzim wenn wir schon dabei sind, hast du auch schon Erfahrung mit Graalvm and OpenJFX. Ich habe einiges gelesen, aber dieses Ganze wie man das so konfiguriert, finde ich so schlecht.
 
dzim

dzim

Meine bisherige Erfahrung damit ist: Ich habe es in meinem Übungsprojekt leider nicht zum kompilieren bekommen... :rolleyes:
(Und ich möchte explizit dieses nutzen. Sonst habe ich ja kaum einen Lerneffekt.)

Wenn ich mal wieder etwas mehr Zeit zum "basteln" habe, werde ich es noch einmal probieren.
 
L

lam_tr

Moin @dzim ,

wenn ich die Anwendung mit JLink bauen möchte, bekomme ich diese Fehlermeldung

Code:
C:\Users\...\build\jlinkbase\tmpjars\de.dc.merged.module\module-info.java:1370: error: package com.fasterxml.jackson does not exist
    uses com.fasterxml.jackson.core;
                              ^
C:\Users\...\build\jlinkbase\tmpjars\de.dc.merged.module\module-info.java:1371: error: package com.fasterxml does not exist
    uses com.fasterxml.classmate;
                      ^
C:\Users\...\build\jlinkbase\tmpjars\de.dc.merged.module\module-info.java:1372: error: package com.fasterxml.jackson does not exist
    uses com.fasterxml.jackson.databind;
                              ^
C:\Users\...\build\jlinkbase\tmpjars\de.dc.merged.module\module-info.java:1373: error: package com.fasterxml.jackson.module does not exist
    uses com.fasterxml.jackson.module.paramnames;
                                     ^
C:\Users\...\build\jlinkbase\tmpjars\de.dc.merged.module\module-info.java:1374: error: package com.fasterxml.jackson does not exist
    uses com.fasterxml.jackson.annotation;
                              ^
C:\Users\...\build\jlinkbase\tmpjars\de.dc.merged.module\module-info.java:1375: error: package javafx does not exist
    uses javafx.base;
               ^
C:\Users\...\build\jlinkbase\tmpjars\de.dc.merged.module\module-info.java:1423: error: the service implementation type must be a subtype of the service interface type, or have a public static no-args method named "provider" returning the service implementation
    provides javax.xml.bind.JAXBContext with com.sun.xml.bind.v2.ContextFactory;
                                                                ^
C:\Users\...\build\jlinkbase\tmpjars\de.dc.merged.module\module-info.java:1437: error: package javax.enterprise.inject.spi does not exist
    provides javax.enterprise.inject.spi.Extension with org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension;
                                        ^
C:\Users\...\build\jlinkbase\tmpjars\de.dc.merged.module\module-info.java:1512: error: package org.apache.logging.log4j.spi is not visible
    provides org.apache.logging.log4j.spi.Provider with org.apache.logging.slf4j.SLF4JProvider;
Ich habe dann den Gradle Task suggestMergedModuleInfo ausgeührt um alle required dependencies zu bekommen. Im Anschluss habe ich die build.gradle file erweitert mit

Code:
jlink {
    mergedModule {
        requires 'com.fasterxml.jackson.core';
        requires 'com.fasterxml.classmate';
        requires 'com.fasterxml.jackson.databind';
        requires 'com.fasterxml.jackson.module.paramnames';
        requires 'com.fasterxml.jackson.annotation';
        requires 'javafx.base';
    }
    launcher {
        name = 'exe_name'
    }
}
scheint leider immer noch nicht zu gehen, hier wird ein ähnliches Problem geschildert https://github.com/beryx/badass-jlink-plugin/issues/59 . Leider komme ich da nicht weiter.

Kennst du einen Weg um das zu Lösen?

Viele Grüße
lam
 
dzim

dzim

Wie sieht denn deine generierte module-info.java aus? Hast du zusätzlich auch eine manuell erstellte? Wenn ja, wo liegt sie (src/main/[java|kotlin|...])
Meine manuell erstellte sieht so aus:
Java:
module packagetest {

    requires javafx.base;
    requires javafx.controls;
    requires javafx.graphics;

    requires kotlin.stdlib.jdk8;

    opens ch.cnlab.jfx.test to javafx.fxml;

    exports ch.cnlab.jfx.test;
}
 
dzim

dzim

Btw: Ich habe heute mit etwas Support durch Gluon den Build der Test-App mittels GraalVM hinbekommen! :D

0.3s gegen 2.1s Zeit zum Aufstarten können sich schon sehen lassen! Ist halt nen 50 MB Executable (unter Linux). Braucht aber auch nur genausoviel Speicher!
 
L

lam_tr

Wie sieht denn deine generierte module-info.java aus? Hast du zusätzlich auch eine manuell erstellte? Wenn ja, wo liegt sie (src/main/[java|kotlin|...])
Meine manuell erstellte sieht so aus:
Java:
module packagetest {

    requires javafx.base;
    requires javafx.controls;
    requires javafx.graphics;

    requires kotlin.stdlib.jdk8;

    opens ch.cnlab.jfx.test to javafx.fxml;

    exports ch.cnlab.jfx.test;
}
Ich habs zwar Kenntnisse in OSGI Modulaisierung aber mit Java Modularisierung, kenne ich mich noch überhaupt nicht. Ich habe über Gradle Skript eine automatisch erstelle Liste bekommen, die sieht auch sehr lang aus. Ich habe einmal nur Jackson Abhängigkeiten genommen und einmal komplett, bei beidem knalle ich voll auf die oben erwähnte Fehlermeldung.

Das ist die vollständige generierte module-info.java
Code:
mergedModule {
    requires 'com.fasterxml.jackson.core';
    requires 'com.fasterxml.classmate';
    requires 'com.fasterxml.jackson.databind';
    requires 'com.fasterxml.jackson.module.paramnames';
    requires 'java.xml';
    requires 'com.sun.xml.txw2';
    requires 'java.desktop';
    requires 'javafx.base';
    requires 'jdk.unsupported';
    requires 'java.management';
    requires 'java.naming';
    requires 'java.security.sasl';
    requires 'com.sun.xml.fastinfoset';
    requires 'java.instrument';
    requires 'com.fasterxml.jackson.annotation';
    requires 'java.logging';
    requires 'jdk.httpserver';
    requires 'java.sql';
    requires 'java.prefs';
    requires 'jdk.jdi';
    requires 'java.rmi';
    requires 'java.security.jgss';
    requires 'jdk.attach';
    requires 'java.scripting';
    requires 'java.datatransfer';
    requires 'java.compiler';
    requires 'java.management.rmi';
    requires 'java.sql.rowset';
    requires 'java.transaction.xa';
    uses 'javax.mail.Provider';
    uses 'org.jboss.logging.LoggerProvider';
    uses 'net.fortuna.ical4j.transform.rfc5545.Rfc5545PropertyRule';
    uses 'org.apache.juli.logging.Log';
    uses 'javax.persistence.spi.PersistenceProvider';
    uses 'org.apache.tomcat.websocket.Authenticator';
    uses 'javax.validation.spi.ValidationProvider';
    uses 'javax.websocket.server.ServerEndpointConfig.Configurator';
    uses 'javax.websocket.ContainerProvider';
    uses 'net.fortuna.ical4j.transform.rfc5545.Rfc5545ComponentRule';
    provides 'net.fortuna.ical4j.model.ParameterFactory' with 'net.fortuna.ical4j.model.parameter.Abbrev.Factory',
                'net.fortuna.ical4j.model.parameter.AltRep.Factory',
                'net.fortuna.ical4j.model.parameter.Cn.Factory',
                'net.fortuna.ical4j.model.parameter.CuType.Factory',
                'net.fortuna.ical4j.model.parameter.DelegatedFrom.Factory',
                'net.fortuna.ical4j.model.parameter.Dir.Factory',
                'net.fortuna.ical4j.model.parameter.Display.Factory',
                'net.fortuna.ical4j.model.parameter.Email.Factory',
                'net.fortuna.ical4j.model.parameter.Encoding.Factory',
                'net.fortuna.ical4j.model.parameter.FbType.Factory',
                'net.fortuna.ical4j.model.parameter.Feature.Factory',
                'net.fortuna.ical4j.model.parameter.FmtType.Factory',
                'net.fortuna.ical4j.model.parameter.Label.Factory',
                'net.fortuna.ical4j.model.parameter.Language.Factory',
                'net.fortuna.ical4j.model.parameter.Member.Factory',
                'net.fortuna.ical4j.model.parameter.PartStat.Factory',
                'net.fortuna.ical4j.model.parameter.Range.Factory',
                'net.fortuna.ical4j.model.parameter.RelType.Factory',
                'net.fortuna.ical4j.model.parameter.Related.Factory',
                'net.fortuna.ical4j.model.parameter.Role.Factory',
                'net.fortuna.ical4j.model.parameter.Rsvp.Factory',
                'net.fortuna.ical4j.model.parameter.ScheduleAgent.Factory',
                'net.fortuna.ical4j.model.parameter.ScheduleStatus.Factory',
                'net.fortuna.ical4j.model.parameter.SentBy.Factory',
                'net.fortuna.ical4j.model.parameter.Type.Factory',
                'net.fortuna.ical4j.model.parameter.TzId.Factory',
                'net.fortuna.ical4j.model.parameter.Value.Factory',
                'net.fortuna.ical4j.model.parameter.Vvenue.Factory';
    provides 'net.fortuna.ical4j.transform.rfc5545.Rfc5545ComponentRule' with 'net.fortuna.ical4j.transform.rfc5545.VAlarmRule',
                'net.fortuna.ical4j.transform.rfc5545.VEventRule';
    provides 'org.apache.commons.logging.LogFactory' with 'org.apache.commons.logging.LogFactoryService';
    provides 'net.fortuna.ical4j.transform.rfc5545.Rfc5545PropertyRule' with 'net.fortuna.ical4j.transform.rfc5545.AttendeePropertyRule',
                'net.fortuna.ical4j.transform.rfc5545.CreatedPropertyRule',
                'net.fortuna.ical4j.transform.rfc5545.DTStampRule',
                'net.fortuna.ical4j.transform.rfc5545.DateListPropertyRule',
                'net.fortuna.ical4j.transform.rfc5545.DatePropertyRule',
                'net.fortuna.ical4j.transform.rfc5545.TzIdRule';
    provides 'javax.xml.bind.JAXBContext' with 'com.sun.xml.bind.v2.ContextFactory';
    provides 'javax.persistence.spi.PersistenceProvider' with 'org.hibernate.jpa.HibernatePersistenceProvider';
    provides 'java.sql.Driver' with 'org.h2.Driver';
    provides 'javax.mail.Provider' with 'com.sun.mail.imap.IMAPProvider',
                'com.sun.mail.imap.IMAPSSLProvider',
                'com.sun.mail.pop3.POP3Provider',
                'com.sun.mail.pop3.POP3SSLProvider',
                'com.sun.mail.smtp.SMTPProvider',
                'com.sun.mail.smtp.SMTPSSLProvider';
    provides 'javax.servlet.ServletContainerInitializer' with 'org.apache.tomcat.websocket.server.WsSci';
    provides 'javax.websocket.server.ServerEndpointConfig.Configurator' with 'org.apache.tomcat.websocket.server.DefaultServerEndpointConfigurator';
    provides 'net.fortuna.ical4j.validate.CalendarValidatorFactory' with 'net.fortuna.ical4j.validate.DefaultCalendarValidatorFactory';
    provides 'javax.validation.spi.ValidationProvider' with 'org.hibernate.validator.HibernateValidator';
    provides 'javax.websocket.ContainerProvider' with 'org.apache.tomcat.websocket.WsContainerProvider';
    provides 'javax.enterprise.inject.spi.Extension' with 'org.springframework.data.jpa.repository.cdi.JpaRepositoryExtension';
    provides 'net.fortuna.ical4j.model.ComponentFactory' with 'net.fortuna.ical4j.model.component.Available.Factory',
                'net.fortuna.ical4j.model.component.Daylight.Factory',
                'net.fortuna.ical4j.model.component.Standard.Factory',
                'net.fortuna.ical4j.model.component.VAlarm.Factory',
                'net.fortuna.ical4j.model.component.VAvailability.Factory',
                'net.fortuna.ical4j.model.component.VEvent.Factory',
                'net.fortuna.ical4j.model.component.VFreeBusy.Factory',
                'net.fortuna.ical4j.model.component.VJournal.Factory',
                'net.fortuna.ical4j.model.component.VTimeZone.Factory',
                'net.fortuna.ical4j.model.component.VToDo.Factory',
                'net.fortuna.ical4j.model.component.VVenue.Factory';
    provides 'net.fortuna.ical4j.model.PropertyFactory' with 'net.fortuna.ical4j.model.property.Acknowledged.Factory',
                'net.fortuna.ical4j.model.property.Action.Factory',
                'net.fortuna.ical4j.model.property.Attach.Factory',
                'net.fortuna.ical4j.model.property.Attendee.Factory',
                'net.fortuna.ical4j.model.property.BusyType.Factory',
                'net.fortuna.ical4j.model.property.CalScale.Factory',
                'net.fortuna.ical4j.model.property.Categories.Factory',
                'net.fortuna.ical4j.model.property.Clazz.Factory',
                'net.fortuna.ical4j.model.property.Color.Factory',
                'net.fortuna.ical4j.model.property.Comment.Factory',
                'net.fortuna.ical4j.model.property.Completed.Factory',
                'net.fortuna.ical4j.model.property.Conference.Factory',
                'net.fortuna.ical4j.model.property.Contact.Factory',
                'net.fortuna.ical4j.model.property.Country.Factory',
                'net.fortuna.ical4j.model.property.Created.Factory',
                'net.fortuna.ical4j.model.property.Description.Factory',
                'net.fortuna.ical4j.model.property.DtEnd.Factory',
                'net.fortuna.ical4j.model.property.DtStamp.Factory',
                'net.fortuna.ical4j.model.property.DtStart.Factory',
                'net.fortuna.ical4j.model.property.Due.Factory',
                'net.fortuna.ical4j.model.property.Duration.Factory',
                'net.fortuna.ical4j.model.property.ExDate.Factory',
                'net.fortuna.ical4j.model.property.ExRule.Factory',
                'net.fortuna.ical4j.model.property.ExtendedAddress.Factory',
                'net.fortuna.ical4j.model.property.FreeBusy.Factory',
                'net.fortuna.ical4j.model.property.Geo.Factory',
                'net.fortuna.ical4j.model.property.Image.Factory',
                'net.fortuna.ical4j.model.property.LastModified.Factory',
                'net.fortuna.ical4j.model.property.Locality.Factory',
                'net.fortuna.ical4j.model.property.Location.Factory',
                'net.fortuna.ical4j.model.property.LocationType.Factory',
                'net.fortuna.ical4j.model.property.Method.Factory',
                'net.fortuna.ical4j.model.property.Name.Factory',
                'net.fortuna.ical4j.model.property.Organizer.Factory',
                'net.fortuna.ical4j.model.property.PercentComplete.Factory',
                'net.fortuna.ical4j.model.property.Postalcode.Factory',
                'net.fortuna.ical4j.model.property.Priority.Factory',
                'net.fortuna.ical4j.model.property.ProdId.Factory',
                'net.fortuna.ical4j.model.property.RDate.Factory',
                'net.fortuna.ical4j.model.property.RRule.Factory',
                'net.fortuna.ical4j.model.property.RecurrenceId.Factory',
                'net.fortuna.ical4j.model.property.RefreshInterval.Factory',
                'net.fortuna.ical4j.model.property.Region.Factory',
                'net.fortuna.ical4j.model.property.RelatedTo.Factory',
                'net.fortuna.ical4j.model.property.Repeat.Factory',
                'net.fortuna.ical4j.model.property.RequestStatus.Factory',
                'net.fortuna.ical4j.model.property.Resources.Factory',
                'net.fortuna.ical4j.model.property.Sequence.Factory',
                'net.fortuna.ical4j.model.property.Source.Factory',
                'net.fortuna.ical4j.model.property.Status.Factory',
                'net.fortuna.ical4j.model.property.StreetAddress.Factory',
                'net.fortuna.ical4j.model.property.Summary.Factory',
                'net.fortuna.ical4j.model.property.Tel.Factory',
                'net.fortuna.ical4j.model.property.Transp.Factory',
                'net.fortuna.ical4j.model.property.Trigger.Factory',
                'net.fortuna.ical4j.model.property.TzId.Factory',
                'net.fortuna.ical4j.model.property.TzName.Factory',
                'net.fortuna.ical4j.model.property.TzOffsetFrom.Factory',
                'net.fortuna.ical4j.model.property.TzOffsetTo.Factory',
                'net.fortuna.ical4j.model.property.TzUrl.Factory',
                'net.fortuna.ical4j.model.property.Uid.Factory',
                'net.fortuna.ical4j.model.property.Url.Factory',
                'net.fortuna.ical4j.model.property.Version.Factory';
    provides 'org.apache.logging.log4j.spi.Provider' with 'org.apache.logging.slf4j.SLF4JProvider';
}
 
dzim

dzim

Das sieht irgendwie nicht richtig aus:
  • ich hab keine einfachen Anführungsstriche um die Module (oder angebotenen Service-Klassen)
  • ich hab nicht eine derart abstrus hohe Menge an provides drin
  • die Syntax ist doch module moduleName { /* content */ }
Sehr verwirrend.
 
L

lam_tr

Das sieht irgendwie nicht richtig aus:
  • ich hab keine einfachen Anführungsstriche um die Module (oder angebotenen Service-Klassen)
  • ich hab nicht eine derart abstrus hohe Menge an provides drin
  • die Syntax ist doch module moduleName { /* content */ }
Sehr verwirrend.
Axo ja ich habe vergessen zu erwähnen, ich habe kein modul-info.java. Die wird im Rahmen von jlink über den Gradle Task erstellt.

das oben in der Box ist eine Ergänzung für build.gradle im jlink{} Knoten.
 
dzim

dzim

Ok. Dann aber stellt sich die Frage: Wozu brauchst du so viel!?
Gerade die ganzen provides.

Ob generiert oder nicht: in deinen build oder out oder target Verzeichnis müssen ja die Class-Files herumliegen - da müsste dann auch eine java-module.class sein -> decompiler drüber laufen lassen (z.B. einfach Doppelklick mit IntelliJ) und den Inhalt anschauen.
Bist du ansonsten auch sicher, dass alle nötigen Dependencies auch wirklich da sind?
 
L

lam_tr

Moin dzim,

ich teste es heute abend, dann gebe ich dir eine Rückmeldung.

Grüße
lam
 
Thema: 

OpenJFX, SpringBoot und Gradle

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben