GraalVM native image of JCEF application not working, even if agent generated config files were added

106 Views Asked by At

I have created a browser based on jcef that displays any url passed to it in command line with some custom context menu, using the library jcefmaven (The jcef native are stored in a fat jar and extracted if not present). I generated the config files using the native image agent. when i tried to build a native image of a jar with those config files, I get two warnings Warning: Method org.cef.browser.CefBrowserWr$3.coalesceEvents(AWTEvent, AWTEvent) not found. and Warning: Method org.example.SingletonDevTools.coalesceEvents(AWTEvent, AWTEvent) not found.even if reflect-config.json does contain the following entries:

{
  "name":"org.cef.browser.CefBrowserWr$3",
  "methods":[{"name":"coalesceEvents","parameterTypes":["java.awt.AWTEvent","java.awt.AWTEvent"] }]
},
{
  "name":"org.example.SingletonDevTools",
  "methods":[{"name":"coalesceEvents","parameterTypes":["java.awt.AWTEvent","java.awt.AWTEvent"] }]
}

and when I launch the native image with same parameters and conditions as the config generation, I get the following error:

Launch called
Nov 22, 2023 10:37:35 AM me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler handleProgress
INFO: LOCATING |> In progress...
Nov 22, 2023 10:37:35 AM me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler handleProgress
INFO: INITIALIZING |> In progress...
Nov 22, 2023 10:37:35 AM me.friwi.jcefmaven.impl.progress.ConsoleProgressHandler handleProgress
INFO: INITIALIZED |> In progress...
initialize on Thread[AWT-EventQueue-0,6,main] with library path /home/****/****/****/jcef-bundle
Exception in thread "AWT-EventQueue-0": java.lang.ClassNotFoundException
java.lang.ClassNotFoundException: org.cef.callback.CefCommandLine_N
    at [email protected]/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:52)
    at [email protected]/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at [email protected]/java.lang.ClassLoader.loadClass(ClassLoader.java:133)
    at org.cef.CefApp.N_Initialize(Native Method)
    at org.cef.CefApp.access$400(CefApp.java:25)
    at org.cef.CefApp$3.run(CefApp.java:427)
    at [email protected]/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:308)
    at [email protected]/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
    at [email protected]/java.awt.EventQueue$4.run(EventQueue.java:722)
    at [email protected]/java.awt.EventQueue$4.run(EventQueue.java:716)
    at [email protected]/java.security.AccessController.executePrivileged(AccessController.java:171)
    at [email protected]/java.security.AccessController.doPrivileged(AccessController.java:399)
    at [email protected]/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at [email protected]/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
    at [email protected]/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at [email protected]/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at [email protected]/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at [email protected]/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at [email protected]/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at [email protected]/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:807)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:210)
Exception in thread "AWT-EventQueue-0": java.lang.ClassNotFoundException
java.lang.ClassNotFoundException: org.cef.callback.CefSchemeRegistrar_N
    at [email protected]/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:52)
    at [email protected]/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at [email protected]/java.lang.ClassLoader.loadClass(ClassLoader.java:133)
    at org.cef.CefApp.N_Initialize(Native Method)
    at org.cef.CefApp.access$400(CefApp.java:25)
    at org.cef.CefApp$3.run(CefApp.java:427)
    at [email protected]/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:308)
    at [email protected]/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
    at [email protected]/java.awt.EventQueue$4.run(EventQueue.java:722)
    at [email protected]/java.awt.EventQueue$4.run(EventQueue.java:716)
    at [email protected]/java.security.AccessController.executePrivileged(AccessController.java:171)
    at [email protected]/java.security.AccessController.doPrivileged(AccessController.java:399)
    at [email protected]/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at [email protected]/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
    at [email protected]/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at [email protected]/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at [email protected]/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at [email protected]/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at [email protected]/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at [email protected]/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:807)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:210)
[1122/103735.075523:WARNING:chrome_browser_cloud_management_controller.cc(88)] Could not create policy manager as CBCM is not enabled.
[1122/103735.158443:WARNING:sandbox_linux.cc(393)] InitializeSandbox() called with multiple threads in process gpu-process.
Exception in thread "System-13": java.lang.ClassNotFoundException
java.lang.ClassNotFoundException: org.cef.browser.CefFrame_N
    at [email protected]/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:52)
    at [email protected]/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at [email protected]/java.lang.ClassLoader.loadClass(ClassLoader.java:133)
Exception in thread "System-13": java.lang.ClassNotFoundException
java.lang.ClassNotFoundException: org.cef.network.CefRequest_N
    at [email protected]/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:52)
    at [email protected]/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at [email protected]/java.lang.ClassLoader.loadClass(ClassLoader.java:133)
Exception in thread "System-19": java.lang.ClassNotFoundException
java.lang.ClassNotFoundException: org.cef.misc.BoolRef
    at [email protected]/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:52)
    at [email protected]/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at [email protected]/java.lang.ClassLoader.loadClass(ClassLoader.java:133)
Exception in thread "System-142": java.lang.ClassNotFoundException
java.lang.ClassNotFoundException: org.cef.callback.CefContextMenuParams_N
    at [email protected]/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:52)
    at [email protected]/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at [email protected]/java.lang.ClassLoader.loadClass(ClassLoader.java:133)
Exception in thread "System-142": java.lang.ClassNotFoundException
java.lang.ClassNotFoundException: org.cef.callback.CefMenuModel_N
    at [email protected]/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:52)
    at [email protected]/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at [email protected]/java.lang.ClassLoader.loadClass(ClassLoader.java:133)
Exception in thread "System-142": java.lang.NullPointerException
java.lang.NullPointerException
    at org.example.ContextMenuHandler.onBeforeContextMenu(ContextMenuHandler.java:30)
    at org.cef.CefClient.onBeforeContextMenu(CefClient.java:246)

OS :- Linux Mint

Java version: 17

Source Code :-

SingletonDevTools.java

public class SingletonDevTools extends JFrame {
    private static SingletonDevTools instance;

    private SingletonDevTools(){
        super("Dev Tools");
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    }

    public static SingletonDevTools getInstance(){
        if(instance == null || !instance.isDisplayable()) {
            instance = new SingletonDevTools();
        }
        return instance;
    }

    public void launch(CefBrowser devToolsBrowser) {
        if(!isVisible()){
            getContentPane().add(devToolsBrowser.getUIComponent(), BorderLayout.CENTER);
            setVisible(true);
        } else {
            toFront();
        }
    }
}

ContextMenuHandler.java

public class ContextMenuHandler extends CefContextMenuHandlerAdapter {
    private final int INSPECT = 1;
    private final int OPEN_IN_BROWSER = 2;
    private final int RELOAD = 3;
    String url;
    private CefBrowser devTools;
    private CefBrowser browser;

    public ContextMenuHandler(CefBrowser browser, String url) {
        this.devTools = browser.getDevTools();
        this.browser = browser;
        this.url = url;
    }

    @Override
    public void onBeforeContextMenu(
            CefBrowser browser, CefFrame frame, CefContextMenuParams params, CefMenuModel model
    ) {
        // Clear the default context menu
        model.clear();

        // Add a custom menu item
        model.addItem(RELOAD, "Reload");
        model.setEnabled(RELOAD, true);

        model.addSeparator();

        model.addItem(INSPECT, "Inspect");
        model.setEnabled(INSPECT, true);

        model.addItem(OPEN_IN_BROWSER, "Open in browser");
        model.setEnabled(OPEN_IN_BROWSER, true);
    }

    @Override
    public boolean onContextMenuCommand(CefBrowser browser, CefFrame frame,
                                        CefContextMenuParams params, int commandId, int eventFlags
    ) {
        // Register a listener for custom menu item clicks
        switch (commandId) {
            case RELOAD -> {
                browser.reload();
                return true;
            }
            case INSPECT -> {
                SingletonDevTools.getInstance().launch(devTools);
                return true;
            }
            case OPEN_IN_BROWSER -> {
                try {
                    Desktop.getDesktop().browse(new URI(url));
                } catch (Exception e) {
                    System.out.println(e);
                    return false;
                }
                return true;
            }
        }
        return false;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

JcefLauncher.java

public class JcefLauncher {
    String url;
    CefApp app;

    public JcefLauncher(String url) {
        this.url = url;
    }

    public void launch() {
        System.out.println("Launch called");
        //Create a new CefAppBuilder instance
        CefAppBuilder builder = new CefAppBuilder();

        //Configure the builder instance
        builder.getCefSettings().windowless_rendering_enabled = false;

        //Build a CefApp instance using the configuration above
        try {
            app = builder.build();
        } catch (IOException | InterruptedException | CefInitializationException | UnsupportedPlatformException e) {
            System.out.println(e);
            System.exit(1);
        }

        // Create a CefClient instance
        CefClient client = app.createClient();

        // Create a CefBrowser instance
        CefBrowser browser = client.createBrowser(this.url, false, false);

        final ContextMenuHandler contextMenuHandler = new ContextMenuHandler(browser, this.url);
        client.addContextMenuHandler(contextMenuHandler);

        client.addDisplayHandler(new CefDisplayHandlerAdapter() {
            @Override
            public void onAddressChange(CefBrowser browser, CefFrame frame, String url) {
                contextMenuHandler.setUrl(url);
            }

            @Override
            public boolean onConsoleMessage(CefBrowser browser, CefSettings.LogSeverity level, String message, String source, int line){
                return true;
            }
        });

        // Create a JFrame to host the browser
        JFrame frame = new JFrame("Time Table Scheduler");
        frame.setSize(1260, 700);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.getContentPane().add(browser.getUIComponent(), BorderLayout.CENTER);
        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                app.dispose();
                System.out.println("System exiting");
                System.exit(0);
            }
        });
        while (true) {
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (!frame.isVisible()){
                app.dispose();
                System.out.println("System exiting");
                System.exit(0);
            }
        }
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        if(args == null || args.length==0) {
            System.err.println("No initial link provided, exiting");
            System.exit(1);
        }
        JcefLauncher jcefLauncher = new JcefLauncher(args[0]);
        jcefLauncher.launch();
    }
}

Config files :-

reflect-config.json :-

[
{
  "name":"java.awt.SequencedEvent"
},
{
  "name":"java.awt.event.KeyEvent",
  "fields":[{"name":"VK_CONTEXT_MENU"}, {"name":"VK_F10"}]
},
{
  "name":"java.sql.Date"
},
{
  "name":"java.util.concurrent.atomic.AtomicBoolean",
  "fields":[{"name":"value"}]
},
{
  "name":"javax.swing.plaf.basic.BasicPanelUI",
  "methods":[{"name":"createUI","parameterTypes":["javax.swing.JComponent"] }]
},
{
  "name":"javax.swing.plaf.metal.MetalRootPaneUI",
  "methods":[{"name":"createUI","parameterTypes":["javax.swing.JComponent"] }]
},
{
  "name":"org.cef.browser.CefBrowserWr$3",
  "methods":[{"name":"coalesceEvents","parameterTypes":["java.awt.AWTEvent","java.awt.AWTEvent"] }]
},
{
  "name":"org.example.SingletonDevTools",
  "methods":[{"name":"coalesceEvents","parameterTypes":["java.awt.AWTEvent","java.awt.AWTEvent"] }]
},
{
  "name":"sun.java2d.marlin.DMarlinRenderingEngine",
  "methods":[{"name":"<init>","parameterTypes":[] }]
}
]

resource-config.json :-

{
  "resources":{
  "includes":[{
    "pattern":"\\Qbuild_meta.json\\E"
  }, {
    "pattern":"\\Qjcef-natives-linux-amd64-jcef-37f25dc+cef-116.0.19+gc6a20bc+chromium-116.0.5845.141.tar.gz\\E"
  }]},
  "bundles":[{
    "name":"com.sun.swing.internal.plaf.basic.resources.basic",
    "classNames":["com.sun.swing.internal.plaf.basic.resources.basic"]
  }, {
    "name":"com.sun.swing.internal.plaf.metal.resources.metal",
    "classNames":["com.sun.swing.internal.plaf.metal.resources.metal"]
  }, {
    "name":"sun.awt.resources.awt",
    "classNames":["sun.awt.resources.awt"]
  }]
}
0

There are 0 best solutions below