
在上一篇中,介绍了在Windows上搭建Trino开发环境所需要的组件。本篇文章,主要介绍通过修改源码,让Trino在Idea中运行起来。
2. 步骤1)配置文件
Trino的配置文件位于“testing/trino-server-dev/etc”目录下,这里面我们先重点关注config.properties文件里面的plugin.bundles参数,这个参数是用来配置Trino加载哪些插件的。这里我们不需要加载这么多的插件,因业务需求只保留“../../plugin/trino-mysql/pom.xml”即可。
注意: 其它的插件是否能够在windows上运行,需要具体用到哪个具体分析。本文重点是提供一个在windows上能对Trino进行二次开发的环境。
修改后的配置文件,这里只对plugin.bundles进行修改
node.id=ffffffff-ffff-ffff-ffff-ffffffffffff node.environment=test node.internal-address=localhost http-server.http.port=8080 discovery-server.enabled=true discovery.uri=http://localhost:8080 exchange.http-client.max-connections=1000 exchange.http-client.max-connections-per-server=1000 exchange.http-client.connect-timeout=1m exchange.http-client.idle-timeout=1m scheduler.http-client.max-connections=1000 scheduler.http-client.max-connections-per-server=1000 scheduler.http-client.connect-timeout=1m scheduler.http-client.idle-timeout=1m query.client.timeout=5m query.min-expire-age=30m plugin.bundles= ../../plugin/trino-mysql/pom.xml node-scheduler.include-coordinator=true
因为我们只加载“trino-mysql”的插件,所以对应的catalog配置只保留mysql.properties文件即可。
catalog目录位于trino-server-dev模块etc目录下,修改后的目录内容如图
配置文件里面的内容可以指定成mysql的具体实例信息
2)配置启动类-DevelopmentServer
该类位于“testing/trino-server-dev”项目的io.trino.server包里,主要是用于开发环境下的启动。接下来按照官方的要求配置启动类
Main Class: io.trino.server.DevelopmentServer VM Options: -ea -Dconfig=etc/config.properties -Dlog.levels-file=etc/log.properties -Djdk.attach.allowAttachSelf=true Working directory: $MODULE_DIR$ Use classpath of module: trino-server-dev
在Idea中创建DevelopmentServer的运行配置,依次配置上面的内容
注意:JDK版本要11.0.7 +
3)运行启动类-DevelopmentServer
呵呵,是不是觉得要成功了,想多了,提示信息扑面而来
4)修改源码 - 解决不支持windows系统的问题
系统检测的代码集中在trino-main模块的io.trino.server.TrinoSystemRequirements类中。trino-main是Trino中一个核心的模块。
此处我们修改源码是为在windows上启动时,排除掉两个报错信息:
1. “ERROR: Trino requires Linux or Mac OS X”
2. "Cannot read OS file descriptor limit"
插一句题外话,由于Trino用到了插件maven-checkstyle-plugin,这个插件是用于检测代码风格的,为了开发方便,我们先通过配置忽略掉代码风格检测,具体做法如下:
点击项目根目录的pom.xml文件,找到
false true
回到正题,话不多说,上代码
final class TrinoSystemRequirements
{
private static final int MIN_FILE_DEscriptORS = 4096;
private static final int RECOMMENDED_FILE_DEscriptORS = 8192;
//rock-add 此处新增一个开关,用于设置是否开发windows开发模式,设置为true即为开始
private static final boolean DEV_ON_WINDOWS = false;
private TrinoSystemRequirements() {}
.........
private static void verifyOsArchitecture()
{
String osName = StandardSystemProperty.OS_NAME.value();
String osArch = StandardSystemProperty.OS_ARCH.value();
if ("Linux".equals(osName)) {
if (!ImmutableSet.of("amd64", "aarch64", "ppc64le").contains(osArch)) {
failRequirement("Trino requires amd64, aarch64, or ppc64le on Linux (found %s)", osArch);
}
if ("aarch64".equals(osArch)) {
warnRequirement("Support for the ARM architecture is experimental");
}
else if ("ppc64le".equals(osArch)) {
warnRequirement("Support for the POWER architecture is experimental");
}
}
else if ("Mac OS X".equals(osName)) {
if (!"x86_64".equals(osArch)) {
failRequirement("Trino requires x86_64 on Mac OS X (found %s)", osArch);
}
}
else {
// failRequirement("Trino requires Linux or Mac OS X (found %s)", osName);
//rock-add 新增适配代码用于windows开发环境运行
if(!DEV_ON_WINDOWS){
failRequirement("Trino requires Linux or Mac OS X (found %s)", osName);
}
}
}
private static void verifyFileDescriptor()
{
OptionalLong maxFileDescriptorCount = getMaxFileDescriptorCount();
if (maxFileDescriptorCount.isEmpty()) {
// This should never happen since we have verified the OS and JVM above
//failRequirement("Cannot read OS file descriptor limit");
//rock-add 新增适配代码用于windows开发环境运行
if(DEV_ON_WINDOWS){
maxFileDescriptorCount = OptionalLong.of(MIN_FILE_DEscriptORS);
}else{
failRequirement("Cannot read OS file descriptor limit");
}
}
if (maxFileDescriptorCount.getAsLong() < MIN_FILE_DEscriptORS) {
failRequirement("Trino requires at least %s file descriptors (found %s)", MIN_FILE_DEscriptORS, maxFileDescriptorCount.getAsLong());
}
if (maxFileDescriptorCount.getAsLong() < RECOMMENDED_FILE_DEscriptORS) {
warnRequirement("Current OS file descriptor limit is %s. Trino recommends at least %s", maxFileDescriptorCount.getAsLong(), RECOMMENDED_FILE_DEscriptORS);
}
}
......
}
这里的修改有3处(都可以通过搜索rock-add发现):
1.添加了开关变量,DEV_ON_WINDOWS,当值为true时,表示开启windows上的开发者模式。
当然,大家也可以通过获取操作系统的信息来做成自动适配的。
private static boolean DEV_ON_WINDOWS = false;
2.修改了verifyOsArchitecture,已支持在windows开发者模式下,不提示不支持windows。
// failRequirement("Trino requires Linux or Mac OS X (found %s)", osName);
if(!DEV_ON_WINDOWS){
failRequirement("Trino requires Linux or Mac OS X (found %s)", osName);
}
3.修改了verifyFileDescriptor,已支持在windows开发者模式下,不提示文件描述符读取不到的问题。
//failRequirement("Cannot read OS file descriptor limit");
if(DEV_ON_WINDOWS){
maxFileDescriptorCount = OptionalLong.of(MIN_FILE_DEscriptORS);
}else{
failRequirement("Cannot read OS file descriptor limit");
}
5)修改源码 - 解决SPI扩展时分隔符硬编码问题
修改完4)的代码,启动DevelopmentServer,报上图的错误,点击进入PluginDiscovery.java:58, 发现,文件分隔符出现了硬编码
PluginDiscovery用于加载插件用的,用到了SPI机制
动手开始改代码,这里的修改有3处(都可以通过搜索rock-add发现):
1. 添加成员变量,自动获取系统的分隔符
//private static final String SERVICES_FILE = "meta-INF/services/" + Plugin.class.getName(); //rock-add private static final char OS_FILE_SEPARATOR = File.separatorChar; private static final String SERVICES_FILE = "meta-INF" + OS_FILE_SEPARATOR + "services" + OS_FILE_SEPARATOR + Plugin.class.getName(); //end
2. 修改discoverPlugins方法
动态匹配分隔符
//if (!file.getPath().endsWith("/target/classes")) {
//rock-add
if (!file.getPath().endsWith(OS_FILE_SEPARATOR+"target"+OS_FILE_SEPARATOR+"classes")) {
//end
throw new RuntimeException("Unexpected file for main artifact: " + file);
}
3.修改javaName方法
这个方法用于把类文件的路径,转换为java中类的包名+类名
private static String javaName(String binaryName)
{
//return binaryName.replace('/', '.');
//rock-add
if(binaryName.contains("/")){
return binaryName.replace('/', '.');
}
return binaryName.replace(OS_FILE_SEPARATOR, '.');
//end
}
6)大功告成
再次运行DevelopmentServer,期待成功时刻,结果...
“java.lang.NoClassDefFoundError: io/airlift/bootstrap/Bootstrap”
解决办法:
trino-mysql模块下的pom.xml添加
io.airlift bootstrap
然后又报错"Error in custom provider, java.lang.NoClassDefFoundError: io/airlift/stats/TimeStat"
继续在trino-mysql模块下的pom.xml添加
io.airlift stats
再次运行DevelopmentServer,启动成功!
3. 总结本文篇幅有些长,但完整的描述了修改源码和调试过程中遇到的各种问题。至此,windows上搭建Trino开发环境顺利完成。
笔者将上面的代码改动已经分享到码云上,具体地址如下:
trino: 基于trino-355版本,扩展的代码
大家如有需要可以下载tag中v0.1.0的版本,就是支持windows上开发的。
插曲:修改后本想提交给trino社区,但是被社区拒绝了,纪念一下,继续努力