拓冰建站拓冰建站
首页 / 资讯中心 / 正文

WebSpoon 9.0.0.0-423本地编译实战:从源码构建可运行war包

先交代一下背景。WebSpoon 9.0.0.0-423 这个版本我在本地编译了不止一次每次都能遇到不一样的问题。WebSpoon 不是新东西它是 Pentaho Data Integration也就是我们常说的 Kettle的社区 Web 版核心是把桌面端的 Spoon 图形界面搬到浏览器里跑。这样一来ETL 开发人员不用在服务器上装图形桌面也不用安装巨大的客户端只要能打开浏览器就能做转换和作业开发。9.0.0.0-423 是 PDI 9.0 系列比较有代表性的一个版本很多人想自己编译一份有的是为了内网隔离部署有的是想改图标和插件有的纯粹是想研究一下这玩意的实现方式。这篇文章不聊怎么用 WebSpoon只聊怎么把源码从 GitHub 拉下来在本地环境里完整编译出可运行的 war 包再把踩过的坑一个个讲清楚。1. 编译前的整体认知与方案设计1.1 WebSpoon 到底是什么为什么值得自己编译为了照顾第一次接触这个项目的人我还是先花两分钟说清楚它和 Kettle 的关系。Kettle 的官方产品叫 Pentaho Data Integration在 9.0 这个年代它发行包里自带一个桌面客户端启动脚本Windows 上是Spoon.batLinux 上是Spoon.sh启动后是一个基于 SWT/JFace 的桌面图形界面。WebSpoon 的玩法不一样它把 Spoon 的图形界面通过 Eclipse RCP 和浏览器渲染机制搬到了 Web 容器里用户打开浏览器就能看到画布、工具箱和运行日志。那为什么不直接用官方发行包非要自己编译我遇到过三种比较典型的场景。第一种是内网环境生产服务器没有外网也没有图形桌面官方安装包虽然能跑但 WebSpoon 的官方 release 文件在部分网络环境下获取不顺畅自己编译一次把 war 包拷进去最省事。第二种是做二次开发比如改 Kettle 的工具栏、加自定义步骤、换主题外观、调整默认日志级别这些都需要动源码编译是躲不开的一步。第三种是学习很多人想搞明白 WebSpoon 和 PDI 的模块依赖关系看源码和跑一次完整构建是完全不同的两个层次。1.2 编译前必须具备的环境清单如果你已经准备开始先把环境对齐省得后面出现一堆莫名其妙的报错。我实测下来这套项目对环境挺挑剔的尤其是 JDK 版本错一个就全盘崩。JDK必须 8。不要用 11、17 或更高版本Pentaho 9.0 系基于 Java 8 构建编译后的 class 字节码版本也是 52.0用了高版本 JDK 可能会在 Maven 编译阶段直接报出 source/target 相关的错误。Maven3.6.x 比较稳3.8 以上我也试过不出大问题但没必要追求新版本。Git2.x 以上拉代码和切 tag 用。磁盘空间至少留出 20GB 以上源码本身几百 MB但 Maven 依赖下载下来会非常占空间一个~/.m2/repository轻松超过 8GB。内存建议 8GB 以上Maven 编译时既要跑 Java 编译又要跑各种插件内存不够会出现OutOfMemoryError。环境检查命令很简单java -version、mvn -v、git --version三个命令过一遍。我还要多说一句Windows 环境下项目目录千万不要放在带有中文或空格的路径里比如D:\开发目录\pentaho kettle这种路径会让某些插件解析失败我一开始就在这上面浪费了半天时间。1.3 镜像源与 Maven 仓库配置这一步虽然不算源码操作但直接影响编译成败。WebSpoon 依赖的 Jar 包数量非常大Pentaho 自己的依赖一部分在 Maven 中央仓库一部分在 Pentaho 的公共仓库。在国内网络环境下直接访问中央仓库下载几十万个文件会非常痛苦所以我强烈建议先把~/.m2/settings.xml配好镜像源。下面是我常用的一个最小配置放在 Maven 安装目录的conf/settings.xml或者当前用户目录下都可以。settings mirrors mirror idaliyun/id nameAliyun Maven Mirror/name urlhttps://maven.aliyun.com/repository/public/url mirrorOfcentral/mirrorOf /mirror /mirrors /settings这样设置之后中央仓库的依赖会优先走阿里云镜像下载速度快不止一个档次。如果你所在团队已经有内部的 Nexus 私服也可以替换成私服地址。我不建议随便用来路不明的第三方仓库依赖完整性没法保证构建中途缺一个包就很难排查。2. 源码获取与工程结构拆解2.1 拉取正确版本的分支与 tag很多人第一步就栽在代码版本上。WebSpoon 的项目仓库实际上托管在HiromuHota/pentaho-kettle这个 GitHub 地址它是 Pentaho 官方 Kettle 仓库的一个社区分支WebSpoon 的所有改动都在这个仓库里。拉代码时不要直接默认 clone 主干分支因为主干分支版本太新和 9.0.0.0-423 的差异很大有些依赖坐标也变了。我建议直接按 tag 拉取git clone -b 9.0.0.0-423 https://github.com/HiromuHota/pentaho-kettle.git cd pentaho-kettle如果你已经把代码拉下来了也可以手动切到对应 taggit fetch --tags git checkout 9.0.0.0-423切完之后执行git branch --show-current确认一下输出应该是9.0.0.0-423或者一个 detached HEAD 状态。这里多说一句为什么版本号写得这么啰嗦Pentaho 的版本号就是三段主版本号加一段构建号9.0.0.0-423表示 PDI 9.0 的第 423 个构建快照对应 WebSpoon 的 release 版本。2.2 工程目录与核心模块解读代码拉下来之后你会看到下面这些核心目录。我建议在跑 Maven 之前先花十分钟熟悉它们后面定位问题会轻松很多。pentaho-kettle/ ├── ui/ # Spoon 图形界面核心逻辑画布、步骤编排、设置界面 ├── engine/ # 转换/作业执行引擎所有数据处理的底层实现 ├── web/ # WebSpoon 特有的 Web 应用模块Servlet、HTML、JS ├── core/ # 公共基础类库常量、工具类、异常定义 ├── plugins/ # 各种扩展插件比如 Hadoop、Big Data 相关 ├── integration/ # 集成测试用例 ├── assemblies/ # 打包脚本和发行包组装逻辑 └── pom.xml # 顶层父 POM定义所有模块的依赖管理重点看三个地方。ui模块是所有图形界面的源头你拖一个“表输入”步骤到画布上对应的 Java 类就在这里。engine模块是执行引擎真正跑数据转换时干活的是它很多二次开发改动会落在这个模块。web模块是 WebSpoon 的入口这部分代码决定了浏览器怎么和 Spoon UI 通信、怎么把绘制指令渲染到页面上。编译的时候 Maven 会按照依赖顺序把所有模块挨个构建一遍这个过程叫 reactor 构建后面我们运行mvn clean install时接触的就是它。2.3 不用深入编译原理但要理解 Maven 在做什么很多人一听编译源码就头大觉得要懂很多底层原理。实际上你不需要深抠 Java 编译原理但至少要理解 Maven 构建的生命周期和模块依赖关系。可以把这套源码想象成一栋楼core是地基engine是承重墙ui是精装修web是安保系统。Maven 不是把整栋楼一次盖完而是按照依赖关系一层一层来。每个模块编译时会把产物安装到本地 Maven 仓库下一个模块再从仓库里取依赖环环相扣。所以一旦某个底层模块编译失败后面所有依赖它的模块都会跟着报错这是排查问题的基本思路。理解了这一点你看到日志里一连串模块失败时就不会慌直接定位最下面最早出现的那个错误就好。3. 本地编译核心流程与关键参数3.1 拿到源码后先做的小调整环境配置好、源码也拉下来了接下来不是急着敲命令而是做两个小调整。第一个是确认 Maven 本地仓库路径没有权限问题。Linux 下默认是~/.m2/repository如果你是 root 用户或者其他受限账号最好提前建好目录并授予写权限否则构建过程中会抛Cannot create directory这类错误。第二个是准备好跳过参数。Pentaho 的工程默认带了很多质量检查插件包括 license 检查、spotless 代码格式检查、Checkstyle、Javadoc 生成等。对第一次编译来说这些检查只会拖慢速度还会因为环境差异引入不必要的失败。所以我通常在命令行里直接跳过。3.2 首次完整构建mvn clean install 必须带的跳过参数首次完整构建我用的是下面这串命令实测下来最省心mvn clean install -DskipTests -Dmaven.javadoc.skiptrue -Dlicense.skiptrue -Dspotless.check.skiptrue -Dcheckstyle.skiptrue每个参数的作用我说一下方便你自己取舍。-DskipTests是跳过单元测试和集成测试测试用例会编译但不会执行这是最常用的提速手段。-Dmaven.javadoc.skiptrue是跳过 Javadoc 文档生成Pentaho 的源码注释里偶尔有几个特殊字符会导致 Javadoc 在严格模式下报错提前跳掉能避免麻烦。-Dlicense.skiptrue是跳过版权许可头检查如果你修改过源码文件原有的版权头可能不匹配检查器会直接中止构建。-Dspotless.check.skiptrue和-Dcheckstyle.skiptrue是跳过代码格式化校验和编码规范检查这些对运行没影响只影响代码风格。敲完命令后你会看到日志里 Maven 先构建core然后engine再然后一路往上层走。首次构建的时间取决于网络和机器性能正常情况下 30 到 60 分钟都有可能期间日志会滚动得很快不用一直盯着看。3.3 只编译 WebSpoon 相关模块的快捷方式有些情况你并不想把整个工程全部构建一遍。比如你只是想打个 war 包做部署验证那完全可以用 Maven 的-pl参数指定模块-am表示同时构建它依赖的上游模块mvn clean install -pl web -am -DskipTests -Dmaven.javadoc.skiptrue -Dlicense.skiptrue -Dspotless.check.skiptrue -Dcheckstyle.skiptrue这个命令会直接进入web目录所在的模块并且把web依赖的ui、engine、core等模块一起构建不会去碰和 Web 无关的插件模块能省不少时间。不过我要提醒一句如果你打算后面做二次开发建议第一次还是全量构建把所有模块的产物都装到本地仓库里后续增量编译时会顺畅很多。3.4 构建完成后产物在哪构建完成后war 包会在web/target目录下。你可以用下面这条命令确认一下find . -name *.war -type f正常情况下你会看到web/target/*.war文件这就是后面要部署到 Tomcat 的最终产物。war 包体积会有一两百兆里面塞满了所有依赖 Jar不用觉得奇怪。除了 war 包之外web/target/下还会有一个同名目录那是 Maven 插件解压后的 web 应用目录开发和调试时可以直接改这个目录里的文件。4. 编译后的部署与本地运行验证4.1 用 Tomcat 部署 war 包war 包拿到手下一步就是找容器跑起来。WebSpoon 9.0 我建议用 Tomcat 8.5 或者 Tomcat 9版本不用太新太新的 Servlet 规范反而可能和项目里的旧依赖冲突。先把 war 包复制到 Tomcat 的webapps目录下为了访问路径方便我一般会重命名成pentaho.warcp web/target/*.war $TOMCAT_HOME/webapps/pentaho.war启动之前一定要设置 Java 内存参数WebSpoon 跑起来之后对内存的需求比一般 Java Web 应用大不少尤其操作大转换时堆内存不够会卡死。编辑 Tomcat 的bin/catalina.sh或者setenv.sh加上export CATALINA_OPTS-Xms1024m -Xmx4096m -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m -Dfile.encodingUTF-8然后正常启动 Tomcat 即可。第一次启动会比较慢因为 war 包要解压大量的类要加载建议至少等一两分钟再访问。4.2 WebSpoon 应用配置与目录约定WebSpoon 部署之后有几种配置需要根据你的使用场景调整。第一建议你显式设置 Kettle 的 Home 目录。可以在环境变量里加一个KETTLE_HOME/opt/kettle-home然后提前建好这个目录里面放.kettle子目录。Kettle 的很多配置文件比如kettle.properties、数据库连接信息、共享 XML都会在这个目录下找。默认情况下它可能指向 Tomcat 启动用户的家目录不规范也容易被系统清理工具误删。第二WebSpoon 的默认访问路径取决于 war 包名。如果 war 包叫pentaho.war就访问http://localhost:8080/pentaho/。浏览器会加载一个类似桌面客户端的 Web 界面第一次加载渲染时稍微有点慢因为要把前端资源都下载到浏览器端。第三如果不想让外网直接访问最稳妥的方式是不要把这个应用暴露到公网而是放在内网里配合防火墙或网关做访问控制。毕竟 ETL 工具涉及到数据源连接越少暴露越好。4.3 验证编译成功的几个关键行为部署完成不代表编译就一定成功还需要做一次真正的功能验证。我的习惯是新建一个最简单的转换从“输入”分类里拖一个“CSV 文件输入”从“输出”分类里拖一个“文本文件输出”把两个步骤连接起来填一个几百 KB 的测试数据然后点击运行。如果整个流程能正常跑完日志里没有红色 Error浏览器画布上的步骤状态变成绿色说明这包编译得没问题。同时打开浏览器开发者工具的 Console 标签看看有没有 JavaScript 报错WebSpoon 的很多前端资源是通过 JS 加载的后端正常不代表前端完全没瑕疵。我第一次编译完部署后页面能打开但拖拽步骤时 Canvas 卡死最后发现是浏览器清理资源后某个 JS 文件缓存版本不匹配清掉缓存重新加载就好了。5. 常见编译问题与排查思路5.1 依赖下载失败或 SSL 握手异常这是出现频率最高的一个问题症状是 Maven 日志里出现大段Could not transfer artifact ... Connection reset或SSLHandshakeException。原因大多数是网络波动或者某个依赖在镜像源上没有同步完整。我的处理方法是先确认镜像源配置是否正确然后强制更新一下快照和缺失依赖mvn clean install -U -DskipTests ...-U会强制 Maven 检查远程仓库的最新版本把上次下载中断留下的.lastUpdated错误标记覆盖掉。如果还是失败就把本地仓库里对应目录删掉再重试。还有一种情况是某些 Pentaho 专属依赖不在 Maven 中央仓库需要额外添加 Pentaho 公共仓库地址这个地址项目根pom.xml里已经有配置检查一下你是否因为使用了mirrorOf配置不当把所有仓库请求都拦截到了中央仓库。我的建议是镜像的mirrorOf尽量配成central而不是*避免影响其他仓库源。5.2 JDK 版本错乱导致的诡异报错我见过不少人在编译时遇到下面这类错误[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:... [ERROR] Source option 8 is no longer supported. Use 7 or later.或者java.lang.UnsupportedClassVersionError: ... Unsupported major.minor version 52.0这两种情况基本都是 JDK 版本不对。第一种是 Maven 默认用的 JDK 太高但项目设置的是 Java 8高版本 JDK 不再支持source 8。第二种是运行时用了低版本 JDK 去加载高版本编译出来的 class。解决办法是把默认 JDK 切成 8。Linux 下可以这样一键切换update-alternatives --config javamacOS 下可以用/usr/libexec/java_home -v 1.8 export JAVA_HOME$(/usr/libexec/java_home -v 1.8)Windows 下就把JAVA_HOME环境变量指向 JDK 8 的安装目录然后重启终端。这里要特别提醒Maven 进程读取的是JAVA_HOME不是PATH里的java命令。有时候你终端里java -version显示 8但 Maven 仍用了另一个 JDK原因就是JAVA_HOME没改对。5.3 构建内存不足与卡死全量编译 WebSpoon 是一个非常吃内存的操作Maven 本身是 Java 进程JVM 默认堆内存往往不够用。报错信息通常是[ERROR] Java heap space [ERROR] GC overhead limit exceeded或者干脆构建进程直接被杀掉。解决办法是给 Maven 加大内存在环境变量里设置export MAVEN_OPTS-Xms1024m -Xmx4096m另外我建议第一次构建不要加-T 1C这种并行参数。并行构建确实能提速但会让多个模块同时占用内存容易在 8GB 的机器上直接把系统打满。我自己的习惯是首次老老实实单线程跑第一次成功后后续增量编译再开并行。5.4 license、spotless、checkstyle 类校验报错你可能会在日志里看到这类信息[ERROR] Missing header in: /path/to/your/File.java [ERROR] Failed to execute goal com.diffplug.spotless:spotless-maven-plugin:... [ERROR] checkstyle failed.这些不是编译逻辑错误是工程自带的纪律检查。Pentaho 项目要求每个源文件必须有版权头注释代码格式必须符合统一规范。如果你改了源码或者从别的分支拷贝过文件很容易触发。处理方式有两种。临时绕过用前面说的跳过参数如果这是你自己要提交的代码建议跑一下格式化插件让它自动修复格式mvn spotless:apply这条命令会自动调整代码换行、缩进、import 顺序再重新编译就不会报格式问题了。我的经验是首次构建一律跳过这些检查等你能顺利出包了再按需打开否则会被一堆与逻辑无关的报错劝退。5.5 编译成功但启动后页面空白这种情况一般是两个原因。第一个是 Tomcat 解压出来的 web 应用目录不完整旧的解压缓存有问题解决方法是删掉webapps/pentaho目录和work/Catalina下的临时文件重新启动。第二个是浏览器端资源加载失败打开开发者工具看看 Network 面板里有没有 404 或 500 的请求特别是 JS、CSS 文件。如果是静态资源 404很可能 war 打包时资源过滤出了问题需要回到web模块重新构建。还有一个容易被忽略的点Tomcat 的日志文件。WebSpoon 的很多错误会同时打印在catalina.out和pentaho.log中遇到页面空白先去看日志比瞎猜效率高得多。6. 一些必须分享的避坑经验6.1 把本地仓库缓存成离线仓库编译一次之后~/.m2/repository会积累大量依赖这个目录其实是一笔财富。如果你需要在内网或者多台机器上重复编译我强烈建议把这个目录整个打包带走。这样一个机器编译完其他机器解压到相同路径就能直接用不用再联网下载一遍能省下几个小时。cd ~ tar czf m2-repository-backup.tar.gz .m2/repository内网机器上解压到对应位置后记得检查settings.xml里的本地仓库路径保持和打包前一致。这个技巧在团队协作时特别有用尤其是多个同事都要编译同一个项目每个人单独搞一遍依赖下载纯属浪费生命。6.2 二开时如何缩短构建周期如果你不是一次性编译完就跑而是想改代码那就要掌握增量编译的技巧。我自己的做法是改哪个模块就编译哪个模块比如只改了ui模块里的一个 Java 文件那就mvn install -pl ui -am -DskipTests -Dlicense.skiptrue -Dspotless.check.skiptrue这样 Maven 会重新构建ui以及它的上游依赖但不会去碰已经构建好的其他模块。改完之后把ui/target/classes下的新 class 文件直接复制到 Tomcat 解压目录的WEB-INF/classes里重启 Tomcat 就能生效比重新打整个 war 包快得多。不过要注意这种热更新的方式只适合验证阶段正式交付时一定要重新打一个干净的 war 包避免遗漏 class 变更。6.3 关于版本选择的个人建议如果你只是为了使用 WebSpoon而不是二次开发我建议直接下载社区提供的 release 包没必要自己编译。自己编译的真正价值在于可控、可改、可离线。如果你要二次开发我建议锁死在这个 9.0.0.0-423 版本上因为它对应的生态资料最多遇到问题时能搜到的解决方案也最多。等你在 9.0 上跑通了整套编译流程再去追更新的版本会轻松很多。另外提醒一点Pentaho 的许可证有一些限制如果是在商业项目里使用或者分发修改版一定要先把许可条款看清楚。我见过有人辛辛苦苦编译完改了版结果对方公司无法合规使用白忙一场。最后再分享一个小技巧。第一次编译时把 Maven 日志输出到文件里不要只靠终端滚动mvn clean install -DskipTests ... build.log 21 tail -f build.log这样你可以在编译的时候安心干别的出错时也能根据build.log里的上下文快速定位问题而不是对着终端里被截断的信息一头雾水。编译这种事只要环境对、参数对剩下的基本就是等。希望这篇实操记录能帮你省下我第一次折腾的那些弯路。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门