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)

压缩包内的目录结构是这样的

jcef支持linux_第1张图片

2.解压后,可以直接运行compile.sh,编译后,运行run.sh,正常情况会出现一个swing窗体。

jcef支持linux_第2张图片

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就可以;

jcef支持linux_第3张图片

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

jcef支持linux_第4张图片

你可能感兴趣的:(java,java)