gluonfx-maven-plugin
gluonfx-maven-plugin copied to clipboard
Swing And JavaFX application run fails
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
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