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"]
}]
}