原文地址: https://debezium.io/blog/2022/05/04/switch-to-java-11/
欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯.
Switching to Java 11/17
May 4, 2022 by Vojtěch Juránek
community news
你可能已经注意到了,我们已经开始研究德贝兹2.0了。其中的 计划的变化 对于2.0版本来说 转换到Java11作为基线 .虽然一些Java构建提供者仍然支持Java8,但其他Java8分布已经达到了生命/支持的极限。不管怎样,用户正转向java11,像新文物的调查一样。 爪哇生态系统状况报告 显示。但这不仅仅是支持的问题:Java11带来了各种性能改进,像JDK飞行记录器这样的有用工具,它是在Java11开放的,等等。因此,我们觉得现在是时候开始考虑使用最近的JDK作为Debezu的基线了,而新的主要版本是进行转换的自然里程碑。
从第一版的德贝唑2.0开始, 2.0.0.Alpha1 ,德贝兹比特将被编译成java11字节代码。因此,在下一次主要更新中,将需要Java11来运行Debezns。另外,如果您在您的项目中使用任何一个德贝兹位作为库(使用德贝兹位) 嵌入式发动机 ),你将不得不改用java11。
但是等等,在标题中java11/17是什么意思?这是为了吓你,还是我们要马上转向java17?
戏剧性的停顿
不,我们不想吓到你。实际上,我们正计划转换到Java17,但仅限于测试套件。请注意java11和17都是长期支持版本。我们还不希望将Java17移动到实际的德贝兹工件上,因为这可能是大量德贝兹用户的问题;例如。上述新的文物报告显示,大多数用户仍然在java11上,当然,我们不想排除他们。然而,在测试中使用Java17不会以任何方式影响用户,并且将允许我们在测试中使用一些最近的Java特性,例如。* 文本块 例如,它简化了多行JSON或SQL字符串的使用,* 记录 ,可提高测试中大量使用的流操作的可读性,* 开关表达式 ,还有更多。
很甜蜜,对吧?
实施
为代码和测试设置不同的字节代码级别非常容易,只需要设置以下属性:
<maven.compiler.release>11</maven.compiler.release>
<maven.compiler.testRelease>17</maven.compiler.testRelease>
请注意我们使用的是release 备选办法而不是遗产source 和target 选项,可以防止目标Java版本中不存在的JavaAPI的意外使用。见例如。贡纳的博客帖子 拜特缓冲器和可怕的情报工作者 更多的细节。
转换到java11后 Maven检查风格的插件 以及 不合理的插件 (一个负责处理适当导入订单的插件)开始失败。然而,将他们的版本推到最新版本已经解决了所有的问题。
这是最简单的部分。最困难的是德贝司 阿帕奇卡珊德拉连接器 .
卡珊德拉连接器测试
此后 版本1.9 卡珊德拉连接器为卡珊德拉3号和卡珊德拉4号提供支持。卡珊德拉4号 很有魅力 但是用java11运行卡珊德拉3是不可能的(或者至少需要一些黑客攻击)。这个连接器的现有测试实现没有像我们在所有其他db连接器的测试中那样在容器中运行卡珊德拉,而是在嵌入式模式下运行卡珊德拉。与测试本身相同的JVM和进程。因此,如果您想用Java11(或17)运行这些测试,卡珊德拉3号连接器模块的测试就会失败。
显而易见的解决方案是用java8在容器中运行卡珊德拉。这听起来不错,但这种方法有一个陷阱。卡珊德拉连接器需要访问卡珊德拉日志文件,因为它从卡珊德拉日志文件中获取了c…使用临时目录可以很容易地解决这个问题,例如在target 把它装进卡珊德拉的容器里。在容器中运行的卡珊德拉可以在稍后使用这个安装的卷存储其数据。
真正的问题从测试结束后进行清理时开始。卡珊德拉在一个名为cassandra 这很可能在测试机器上不存在(或者使用不同的UID/GID),当它试图用卡珊德拉文件删除临时目录时,清理失败。这些文件是在安装在容器中的时序目录中创建的,而不是在码头工的叠加中创建的,因此这些文件存在于target 目录。因为这些文件是由cassandra 用户与运行测试的用户很可能是不同的用户,运行测试的用户没有足够的权利删除所创建的文件。cassandra 用户。试图在卡珊德拉出口的卡珊德拉容器中删除它们的一些包装脚本被证明是非常繁琐和不太可靠的。
最有希望的解决方案是启动第二个相同容器cassandra 在第一个卡珊德拉容器停止后,用户可以访问安装的卷并清理文件。
我们考虑了运行集装箱的两种选择:
建筑8码头工人马文插件
试验容器
我们在项目的其他部分使用了FABRR8插件,这意味着在本例中也使用它来实现整个项目的一致性。另一方面,使用测试容器将使测试对开发人员更加方便(毕竟他们实际上使用测试!),因为它允许直接从IDE中运行测试,而无需手动启动容器。
最后,这个决定是由这样一个事实驱动的,即运行一个清除容器是不可能的,以法布里8插件。马文不允许在同一阶段执行不同的配置,因此不可能停止卡珊德拉容器在post-integration-test 在此阶段同时运行清理容器。测试容器允许在需要时以编程方式启动和停止容器,让我们直接在测试代码中定义图像,这样我们就不需要额外的Dockerfile 并且清理容器只是隐藏在测试本身中的一个实现细节。在这些事情的基础上,有能力直接从IDE运行测试,而不必手动启动和停止使用数据库的容器。
当使用测试容器时,唯一棘手的事情是,当我们试图使用Dkerker的cmd 命令,测试容器随机失败,声明容器没有启动,尽管事实上所有的卡珊德拉文件实际上被删除。容器可能跑得太快,在测试容器注意到它之前就完成了。最后,我们通过增加一个简短的sleep 在容器中执行一个额外的命令,在容器中进行清理.
使用测试容器的最终清理代码如下:
@AfterClass
public static void tearDownClass() throws IOException, InterruptedException {
destroyTestKeyspace();
cassandra.stop();
GenericContainer cleanup = new GenericContainer(new ImageFromDockerfile()
.withDockerfileFromBuilder(builder -> builder
.from("eclipse-temurin:8-jre-focal")
.volume("/var/lib/cassandra")
.cmd("sleep", "10") // Give TC some time to find out container is running.
.build()))
.withFileSystemBind(cassandraDir, CASSANDRA_SERVER_DIR, BindMode.READ_WRITE);
cleanup.start();
cleanup.execInContainer(
"rm", "-rf",
CASSANDRA_SERVER_DIR + "/data",
CASSANDRA_SERVER_DIR + "/cdc_raw_directory",
CASSANDRA_SERVER_DIR + "/commitlog",
CASSANDRA_SERVER_DIR + "/hints",
CASSANDRA_SERVER_DIR + "/saved_caches");
cleanup.stop();
}
一旦我们用卡珊德拉测试解决了这个问题,我们基本上就完成了,并准备在测试中使用java11(主Debezum代码)和java17。
未决问题
我们需要更多的战斗测试,以确保所有的工作与Java11/17良好。您对测试和错误报告的帮助在这里非常有价值,非常受欢迎。目前我们知道一个与Java更新相关的未解决的小问题。一些IDE无法区分maven.compiler.release 和maven.compiler.testRelease (或者我们不太清楚如何建立它)。例如这个测试使用了 文本块 会标记为一个错误:
图片来自官网原文
测试使用文本块在智能j思想。
您可以手动地将Java级别设置为17级,但是在这种情况下,您可能会无意中使用非测试代码中的Java&ttt;11特性,而不需要由IDI让您知道(当然,这并不是一个太多的问题,作为下一个Maven构建,例如。会抓住这个问题)。此外,例如在任何更改的代码级别上,"想法"将重置代码级别。pom.xml 文件。你解决了这个问题吗?您是否使用了一个不存在混合不同Java级别问题的IDI?请在讨论中分享你的经验!