gluonfx-maven-plugin icon indicating copy to clipboard operation
gluonfx-maven-plugin copied to clipboard

Swing And JavaFX application run fails

Open ygarg465 opened this issue 2 years ago • 1 comments

I am trying to create a native-image of a straightforward application but it requires being a Swing application with JFrame and JFXPanel to run JavaFX UI as I am using Java Chromium Embedded Framework (JCEF) to replace Javafx WebView on Windows as GraalVM does not currently support it. And JavaFX does not render the browser correctly, hence Swing usage. Plugin's build command runs perfectly fine but when I try to run the image using nativerun it fails to run.

C:\Users\Yash\Documents\Gluon-SingleViewProject\target\gluonfx>mvn -f "C:\Users\Yash\Documents\Gluon-SingleViewProject\pom.xml" com.gluonhq:gluonfx-maven-plugin:1.0.15:nativerun
[INFO] Scanning for projects...
[INFO]
[INFO] ------------< com.gluonapplication:gluon-singleviewproject >------------
[INFO] Building Gluon-SingleViewProject 1.0-SNAPSHOT
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- gluonfx-maven-plugin:1.0.15:nativerun (default-cli) @ gluon-singleviewproject ---
[Tue Sep 13 20:37:44 IST 2022][INFO] ==================== RUN TASK ====================
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB] Exception in thread "main" java.lang.UnsatisfiedLinkError: no awt in java.library.path
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibraryRelative(NativeLibrarySupport.java:132)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.lang.ClassLoader.loadLibrary(ClassLoader.java:47)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.lang.Runtime.loadLibrary0(Runtime.java:818)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.lang.System.loadLibrary(System.java:1989)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.awt.Toolkit$2.run(Toolkit.java:1388)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.awt.Toolkit$2.run(Toolkit.java:1386)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.security.AccessController.executePrivileged(AccessController.java:169)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.security.AccessController.doPrivileged(AccessController.java:318)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.awt.Toolkit.loadLibraries(Toolkit.java:1385)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.awt.Toolkit.initStatic(Toolkit.java:1423)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.awt.Toolkit.<clinit>(Toolkit.java:1397)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.awt.Component.<clinit>(Component.java:624)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.lang.Class.ensureInitialized(DynamicHub.java:518)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.lang.Class.ensureInitialized(DynamicHub.java:518)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.lang.Class.ensureInitialized(DynamicHub.java:518)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.lang.Class.ensureInitialized(DynamicHub.java:518)
[Tue Sep 13 20:37:44 IST 2022][INFO] [SUB]      at java.lang.Class.ensureInitialized(DynamicHub.java:518)
             _______  ___      __   __  _______  __    _
            |       ||   |    |  | |  ||       ||  |  | |
            |    ___||   |    |  | |  ||   _   ||   |_| |
            |   | __ |   |    |  |_|  ||  | |  ||       |
            |   ||  ||   |___ |       ||  |_|  ||  _    |
            |   |_| ||       ||       ||       || | |   |
            |_______||_______||_______||_______||_|  |__|

    Access to the latest docs, tips and tricks and more info on
    how to get support? Register your usage of Gluon Substrate now at

    https://gluonhq.com/activate



[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.139 s
[INFO] Finished at: 2022-09-13T20:37:46+05:30
[INFO] ------------------------------------------------------------------------

Application Code

package com.gluonapplication;

import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import org.cef.CefApp;
import org.cef.CefClient;
import org.cef.CefSettings;
import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.handler.CefAppHandlerAdapter;
import org.cef.handler.CefDisplayHandlerAdapter;
import org.cef.handler.CefFocusHandlerAdapter;

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.Serial;

public class MainFrame extends JFrame {
    @Serial
    private static final long serialVersionUID = -5570653778104813836L;
    private final JTextField address_;
    private final CefApp cefApp_;
    private final CefClient client_;
    private final CefBrowser browser_;
    private final Component browerUI_;
    private boolean browserFocus_ = true;

    private MainFrame(String startURL, boolean useOSR, boolean isTransparent) {
        CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
            @Override
            public void stateHasChanged(org.cef.CefApp.CefAppState state) {
                if (state == CefApp.CefAppState.TERMINATED) System.exit(0);
            }
        });
        CefSettings settings = new CefSettings();
        settings.windowless_rendering_enabled = useOSR;
        cefApp_ = CefApp.getInstance(settings);

        client_ = cefApp_.createClient();

        browser_ = client_.createBrowser(startURL, useOSR, isTransparent);
        browerUI_ = browser_.getUIComponent();

        address_ = new JTextField(startURL, 100);
        address_.addActionListener(e -> browser_.loadURL(address_.getText()));

        client_.addDisplayHandler(new CefDisplayHandlerAdapter() {
            @Override
            public void onAddressChange(CefBrowser browser, CefFrame frame, String url) {
                address_.setText(url);
            }
        });

        address_.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                if (!browserFocus_) return;
                browserFocus_ = false;
                KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
                address_.requestFocus();
            }
        });

        client_.addFocusHandler(new CefFocusHandlerAdapter() {
            @Override
            public void onGotFocus(CefBrowser browser) {
                if (browserFocus_) return;
                browserFocus_ = true;
                KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
                browser.setFocus(true);
            }

            @Override
            public void onTakeFocus(CefBrowser browser, boolean next) {
                browserFocus_ = false;
            }
        });

        getContentPane().add(address_, BorderLayout.NORTH);
        getContentPane().add(browerUI_, BorderLayout.CENTER);
        JFXPanel jfxPanel = new JFXPanel();
        javafx.scene.control.Button button = new javafx.scene.control.Button("Print");
        button.setOnAction(e -> browser_.print());
        jfxPanel.setScene(new Scene(button));
        getContentPane().add(jfxPanel, BorderLayout.SOUTH);
        pack();
        setSize(800, 600);
        setVisible(true);

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                CefApp.getInstance().dispose();
                dispose();
            }
        });
    }

    public static void main(String[] args) {
        if (!CefApp.startup(args)) {
            System.out.println("Startup initialization failed!");
            return;
        }

        boolean useOsr = false;
        new MainFrame("https://www.google.com", useOsr, false);
    }
}

Please let me know if any more information is needed

ygarg465 avatar Sep 13 '22 15:09 ygarg465

mvn gluonfx:runagent and click through everything before mvn gluonfx:build copy your .exe to graalvm\bin and execute it from there - if it works there, the awt and dependent dll's are missing and they must exist in the directory where you start the .exe

Khithar avatar Oct 03 '22 14:10 Khithar