• jcef支持linux


    由于工作中有需求,需要在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.执行的时候会崩溃,报错一般是:

    1. Offscreen rendering disabled
    2. Using:
    3. JCEF Version = 78.3.9.242
    4. CEF Version = 78.3.9
    5. Chromium Version = 78.0.3904.108
    6. AppHandler.stateHasChanged: INITIALIZING
    7. initialize on Thread[AWT-EventQueue-0,6,main] with library path /root/java-cef-build-bin/bin/lib/linux64
    8. Added scheme search://
    9. Added scheme client://
    10. LaunchProcess: failed to execvp:
    11. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    12. LaunchProcess: failed to execvp:
    13. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    14. [0803/100412.828133:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 1 time(s)
    15. LaunchProcess: failed to execvp:
    16. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    17. [0803/100412.830704:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 2 time(s)
    18. LaunchProcess: failed to execvp:
    19. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    20. AppHandler.stateHasChanged: INITIALIZED
    21. [0803/100412.833812:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 3 time(s)
    22. LaunchProcess: failed to execvp:
    23. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    24. [0803/100412.837619:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 4 time(s)
    25. LaunchProcess: failed to execvp:
    26. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    27. [0803/100412.840672:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 5 time(s)
    28. LaunchProcess: failed to execvp:
    29. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    30. [0803/100412.843655:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 6 time(s)
    31. LaunchProcess: failed to execvp:
    32. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    33. [0803/100412.846199:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 7 time(s)
    34. LaunchProcess: failed to execvp:
    35. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    36. [0803/100412.851683:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 8 time(s)
    37. LaunchProcess: failed to execvp:
    38. /root/java-cef-build-bin/bin/lib/linux64/jcef_helper
    39. [0803/100412.855244:WARNING:gpu_process_host.cc(1220)] The GPU process has crashed 9 time(s)
    40. [0803/100412.855281:FATAL:gpu_data_manager_impl_private.cc(986)] The display compositor is frequently crashing. Goodbye.
    41. ./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();

    附测试例子代码:

    1. import java.awt.BorderLayout;
    2. import java.awt.Component;
    3. import java.awt.Dimension;
    4. import javax.swing.JFrame;
    5. import javax.swing.JPanel;
    6. import org.cef.CefApp;
    7. import org.cef.CefClient;
    8. import org.cef.CefSettings;
    9. import org.cef.OS;
    10. import org.cef.browser.CefBrowser;
    11. import org.cef.browser.CefMessageRouter;
    12. import org.cef.browser.CefMessageRouter.CefMessageRouterConfig;
    13. /**
    14. * Chrome 浏览器内嵌Panel
    15. * 内嵌浏览器属于重量级Canvas,Chromium属于耗资源的控件,不能随意初始化
    16. *
    17. * @author Gui Lei
    18. *
    19. */
    20. public class ChromePanel extends JPanel
    21. {
    22. private static final long serialVersionUID = 1L;
    23. private static CefApp cefApp_;
    24. private CefClient client_;
    25. private CefBrowser browser_;
    26. private Component browerUI_;
    27. private Dimension size = new Dimension(800, 600);
    28. static
    29. {
    30. CefSettings settings = new CefSettings();
    31. if(OS.isLinux())
    32. {
    33. //linux的特殊处理
    34. CefApp.startup();
    35. }
    36. cefApp_ = CefApp.getInstance(settings);
    37. }
    38. /**
    39. * 进入页面之前,添加js交互(这里做登录用)
    40. * @param client
    41. */
    42. public void jsActive(CefClient client)
    43. {
    44. CefMessageRouterConfig cmrc = new CefMessageRouterConfig("java", "javaCancel");
    45. CefMessageRouter cmr = CefMessageRouter.create(cmrc);
    46. client.addMessageRouter(cmr);
    47. }
    48. /**
    49. *
    50. * @param startURL
    51. */
    52. public ChromePanel(String startURL)
    53. {
    54. this.setLayout(new BorderLayout());
    55. if (client_ == null)
    56. {
    57. client_ = cefApp_.createClient();
    58. }
    59. //添加js交互
    60. jsActive(client_);
    61. browser_ = client_.createBrowser(startURL, OS.isLinux(), false);
    62. browerUI_ = browser_.getUIComponent();
    63. this.add(browerUI_, BorderLayout.CENTER);
    64. this.setSize(size);
    65. this.setPreferredSize(size);
    66. }
    67. /**
    68. * 设置浏览器新的URL地址
    69. *
    70. * @param url
    71. */
    72. public void setUrl(String url)
    73. {
    74. if(browser_ != null)
    75. {
    76. browser_.loadURL(url);
    77. }
    78. }
    79. // 关闭程序之前必须调用这个
    80. public void disposeApp()
    81. {
    82. cefApp_.dispose();
    83. }
    84. public CefApp getCefApp_()
    85. {
    86. return cefApp_;
    87. }
    88. public CefClient getClient_()
    89. {
    90. return client_;
    91. }
    92. public CefBrowser getBrowser_()
    93. {
    94. return browser_;
    95. }
    96. public Component getBrowerUI_()
    97. {
    98. return browerUI_;
    99. }
    100. public static void main(String[] args)
    101. {
    102. JFrame frame = new JFrame();
    103. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    104. String url = "http://www.baidu.com";
    105. ChromePanel chromePanel = new ChromePanel(url);
    106. frame.setSize(chromePanel.getPreferredSize());
    107. frame.setContentPane(chromePanel);
    108. frame.setVisible(true);
    109. }
    110. }

    部署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效果正常:

  • 相关阅读:
    Visual Studio Code调试和发布ASP.NET Core Web应用
    什么是雷曼时刻(Lehman Moment)
    Panda3D设置窗体长宽及其他参数
    开源协议、开源贡献协议与OpenHarmony
    C++之特殊函数成员
    vscode编写前端提升效率的三个必不可缺的插件以及使用方法
    代码随想录算法训练营第23期day20| 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先
    maven中的install 和 clean命令,以及compile、、package、test等操作介绍
    产品人生(9):从“波士顿矩阵”看“个人职业规划”
    【YOLO】拾遗(五)
  • 原文地址:https://blog.csdn.net/geminit2011/article/details/126138109