由于工作中有需求,需要在Linux平台支持JCEF内置浏览器到Java窗口,且需要支持WebGL三维浏览。
基于此需求,就排除了DJNativeSwing和JavaFx自带的WebView,选用了JCEF技术路线。
将踩坑步骤记录如下:
1.找到Linux JCEF可用的包,由于我的项目要求是Java8环境,所以选择的是:
Release v1.0.9-78.3.9+gc7345f2+chromium-78.0.3904.108 · jcefbuild/jcefbuild · GitHub
这个源包支持java8环境;
(https://download.csdn.net/download/geminit2011/86281288)
压缩包内的目录结构是这样的
2.解压后,可以直接运行compile.sh,编译后,运行run.sh,正常情况会出现一个swing窗体。
3.可能出现的踩坑:
a.GLIBCXX版本过低
这个解决简单,升级gcc,就可以,我这里用的是gcc6.1.0
解压gcc-6.1.0.tar.xz,假定目录在/root/soft/目录(目录可以自定义)
升级指令
mv /usr/bin/gcc /usr/bin/gcc485
mv /usr/bin/g++ /usr/bin/g++485
mv /usr/bin/c++ /usr/bin/c++485
ln -s /root/soft/gcc-6.1.0/bin/gcc /usr/bin/gcc
ln -s /root/soft/gcc-6.1.0/bin/g++ /usr/bin/g++
ln -s /root/soft/gcc-6.1.0/bin/c++ /usr/bin/c++
mv /lib64/libstdc++.so.6 /lib64/libstdc++.so.6.bak
ln -s /root/soft/gcc-6.1.0/lib64/libstdc++.so.6.0.22 /lib64/libstdc++.so.6
升级完毕后执行指令:strings /lib64/libstdc++.so |grep GLIBCXX
输出的GLIBCXX有3.4.22就可以;
b.执行的时候会崩溃,报错一般是:
- Offscreen rendering disabled
- Using:
- JCEF Version = 78.3.9.242
- CEF Version = 78.3.9
- Chromium Version = 78.0.3904.108
- AppHandler.stateHasChanged: INITIALIZING
- initialize on Thread[AWT-EventQueue-0,6,main] with library path /root/java-cef-build-bin/bin/lib/linux64
- Added scheme search://
- Added scheme client://
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- [0803/100412.828133:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 1 time(s)
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- [0803/100412.830704:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 2 time(s)
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- AppHandler.stateHasChanged: INITIALIZED
- [0803/100412.833812:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 3 time(s)
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- [0803/100412.837619:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 4 time(s)
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- [0803/100412.840672:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 5 time(s)
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- [0803/100412.843655:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 6 time(s)
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- [0803/100412.846199:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 7 time(s)
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- [0803/100412.851683:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 8 time(s)
- LaunchProcess: failed to execvp:
- /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
- [0803/100412.855244:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 9 time(s)
- [0803/100412.855281:FATAL:gpu_data_manager_impl_private.cc(986)] The display compositor is frequently crashing. Goodbye.
- ./run.sh: 行 13: 11622 Trace/breakpoint trap (吐核)LD_PRELOAD=$LIB_PATH/libcef.so java -cp "./bin:./bin/*" -Djava.library.path=$LIB_PATH tests.detailed.MainFrame "$@"
-
这种一般是linux权限问题,我的解决办法是,执行chmod +x -R java-cef-build-bin/
赋予文件夹执行权限【这个地方踩坑解决了1天,各种搜索材料…】
4.代码集成
简单的写了一个Java Project工程,拷贝java-cef-build-bin/bin目录下的jar到工程的环境依赖;
linux需要特殊处理,在初始化之前调用CefApp.startup();
附测试例子代码:
-
-
- import java.awt.BorderLayout;
- import java.awt.Component;
- import java.awt.Dimension;
-
- import javax.swing.JFrame;
- import javax.swing.JPanel;
-
- import org.cef.CefApp;
- import org.cef.CefClient;
- import org.cef.CefSettings;
- import org.cef.OS;
- import org.cef.browser.CefBrowser;
- import org.cef.browser.CefMessageRouter;
- import org.cef.browser.CefMessageRouter.CefMessageRouterConfig;
-
- /**
- * Chrome 浏览器内嵌Panel
- * 内嵌浏览器属于重量级Canvas,Chromium属于耗资源的控件,不能随意初始化
- *
- * @author Gui Lei
- *
- */
- public class ChromePanel extends JPanel
- {
- private static final long serialVersionUID = 1L;
-
- private static CefApp cefApp_;
- private CefClient client_;
- private CefBrowser browser_;
- private Component browerUI_;
- private Dimension size = new Dimension(800, 600);
-
- static
- {
- CefSettings settings = new CefSettings();
- if(OS.isLinux())
- {
- //linux的特殊处理
- CefApp.startup();
- }
- cefApp_ = CefApp.getInstance(settings);
- }
-
- /**
- * 进入页面之前,添加js交互(这里做登录用)
- * @param client
- */
- public void jsActive(CefClient client)
- {
- CefMessageRouterConfig cmrc = new CefMessageRouterConfig("java", "javaCancel");
- CefMessageRouter cmr = CefMessageRouter.create(cmrc);
- client.addMessageRouter(cmr);
- }
-
- /**
- *
- * @param startURL
- */
- public ChromePanel(String startURL)
- {
- this.setLayout(new BorderLayout());
-
- if (client_ == null)
- {
- client_ = cefApp_.createClient();
- }
-
- //添加js交互
- jsActive(client_);
-
- browser_ = client_.createBrowser(startURL, OS.isLinux(), false);
- browerUI_ = browser_.getUIComponent();
- this.add(browerUI_, BorderLayout.CENTER);
-
- this.setSize(size);
- this.setPreferredSize(size);
- }
-
- /**
- * 设置浏览器新的URL地址
- *
- * @param url
- */
- public void setUrl(String url)
- {
- if(browser_ != null)
- {
- browser_.loadURL(url);
- }
- }
-
- // 关闭程序之前必须调用这个
- public void disposeApp()
- {
- cefApp_.dispose();
- }
-
- public CefApp getCefApp_()
- {
- return cefApp_;
- }
-
- public CefClient getClient_()
- {
- return client_;
- }
-
- public CefBrowser getBrowser_()
- {
- return browser_;
- }
-
- public Component getBrowerUI_()
- {
- return browerUI_;
- }
-
- public static void main(String[] args)
- {
- JFrame frame = new JFrame();
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
- String url = "http://www.baidu.com";
- ChromePanel chromePanel = new ChromePanel(url);
- frame.setSize(chromePanel.getPreferredSize());
- frame.setContentPane(chromePanel);
- frame.setVisible(true);
- }
- }
部署jcef相关资源到jre
a.解压linux64.zip资源;
b.复制java-cef-build-bin/bin/lib/linux64的所有文件到jre/lib和jre/lib/amd64目录
c.然后执行指令chmod +x -R jre/
运行的时候有个小注意事项,设置java.library.path为jdk目录的jre/lib,防止cef找不到依赖
-Djava.library.path=JDK所在目录/jre/lib
示例:-Djava.library.path=/root/soft/jdk1.8.0_241/jre/lib
运行效果如下,用了three.js的demo,运行WebGL效果正常: