【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

Jakarta EE 开发者必备的 2 个工具

作者:Dennis Gesker

  • 2022-04-30
  • 本文字数:7844 字

    阅读完需:约 26 分钟

Jakarta EE开发者必备的2个工具

我喜欢新玩具。我真的很喜欢那些经过验证的技术栈里的新玩具。我非常喜欢那些能让我玩到经过产品验证的新技术的新玩具。而工具玩具是其中最好的。


在本文中,我将讨论两个新玩具。如果一起使用,它们很可能成为你软件开发之战中的必备之箭。这两个工具分别是来自 WildFly 项目的 wildfly-jar-maven-plugin 和全新的 wildfly-datasources-preview-galleon-pack


WildFly 是 RedHat 公司 JBoss 应用服务器的一个上游项目,对于许多项目来说,都是一个很好的解决方案。该应用服务器兼容 Jakarta EE 8,最新的“预览”版本则兼容 Jakarta EE 9.1。


2022 年WildFly的发布计划包括为即将发布的 Jakarta 10 做准备,通过未来的一个“预览”版本,让开发者就可以把下一个版本的标准拿来玩。真令人激动。


现在,我们将重点讨论 WildFly 26.0.1 预览版(已在一月的最后一周发布)和 Jakarta EE 9.1。

第一个新玩具

wildfly-jar-maven-plugin 允许开发者按需配置(确定应用程序需要应用服务器的哪些部分、依赖或能力,并进行任何必要的配置)WildFly 服务器,并使用 Maven 生成包含应用程序和 WildFly 容器的 Uber JAR。没错,整个应用服务器和应用程序都被打包在一个整洁的 JAR 文件中。执行命令:


java -jar nameOfYourApplication-bootable.jar
复制代码


服务器和应用程序就准备好了。把那个可启动的 JAR 文件放到局域网的服务器上,部署到边缘设备上,部署到容器化环境中,当然要放到目标目录中。它仍然提供了标准的 WAR 文件,你可以把它部署在裸机或虚拟机上运行的 Jakarta EE 容器中。这里有很多选项和一大堆配置工作,但这个插件可以帮我们在短时间内完成。这个插件好像是在 2020 年被推送到 Maven 仓库的,最新版本 7.0.0.Final 是几个月前推送的。从 Maven 仓库的发布频率来看,该插件显然得到了积极的维护。


如上所述,应用服务器和应用程序紧密地捆绑在一起,你很容易就可以得到一个简单的 Docker 文件,做好在 Kubernetes 上部署的准备。将插件添加到 Maven 的 pom.xml 中,如下所示:


<plugin>    <groupId>org.wildfly.plugins</groupId>    <artifactId>**wildfly-jar-maven-plugin**</artifactId>    <version>${version.wildfly.jar.maven.plugin}</version>    <configuration>        <log-time>true</log-time>        <cloud>            <type>kubernetes</type>        </cloud>        <context-root>false</context-root>        <feature-packs>            <feature-pack>                <location>wildfly@maven(org.jboss.universe:community-universe)#${version.wildfly}                </location>            </feature-pack>            <feature-pack>                <groupId>org.wildfly</groupId>                <artifactId>wildfly-datasources-galleon-pack</artifactId>                <version>${version.wildfly.datasources.galleon-pack}</version>            </feature-pack>        </feature-packs>        <hollow-jar>false</hollow-jar>        <plugin-options>            <jboss-fork-embedded>true</jboss-fork-embedded>        </plugin-options>        <!-- Listen on all ports -->        <arguments>            <argument>-b=0.0.0.0</argument>        </arguments>        <!-- Make sure we can debug -->        <jvmArguments>            <arg>-agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n</arg>        </jvmArguments>        <cli-sessions>            <cli-session>                <!-- Feed WildFly Some Properties -->                <properties-file>package_properties.properties</properties-file>                <!-- Run some jboss-cli.sh commands against WildFly -->                <script-files>                    <script>package_script.cli</script>                </script-files>            </cli-session>        </cli-sessions>        <excluded-layers>            <!-- Just here to demonstrate one can take layers OUT of the Container -->            <layer>core-management</layer>            <layer>deployment-scanner</layer>            <layer>jmx-remoting</layer>            <layer>request-controller</layer>            <layer>security-manager</layer>        </excluded-layers>        <layers>            <!-- Some of these layers are redundant as Galleon dependencies take's care of most things -->            <layer>cloud-server</layer>            <layer>ejb-dist-cache</layer>            <layer>web-clustering</layer>            <layer>ee</layer>            <layer>ejb-lite</layer>            <layer>jaxrs</layer>            <layer>jpa</layer>            <layer>jsf</layer>            <layer>jsonb</layer>            <layer>jsonp</layer>            <!-- These go along with **wildfly-datasources-preview-galleon-pack** -->            <layer>datasources-web-server</layer>            <layer>postgresql-datasource</layer> <!-- Yes, there are other drivers available -->        </layers>    </configuration>    <executions>        <execution>            <goals>                <goal>package</goal>            </goals>        </execution>    </executions></plugin>
复制代码


这里有构建可启动 JAR 文件的完整文档。为了让你能够快速上手,我在 GitHub 上发布了一些示例代码。克隆这个资源库,然后执行命令:


mvn cleanmvn wildfly-jar:dev-watch
复制代码

第二个新玩具

现在,我们已经介绍完了第一个新玩具,让我们拿 WildFly 的“预览”版来试一试。首先,我们将更新“功能包”的位置,从:


<location>wildfly@maven(org.jboss.universe:community-universe)#${version.wildfly}</location>
复制代码


改为:


<location>wildfly-preview@maven(org.jboss.universe:community-universe)#${version.wildfly}</location>
复制代码


我们还必须改变全新的 wildfly-datasources-preview-galleon-pack artifactId,以便应用程序能够连接到数据库。毕竟,没有数据的应用程序什么都不是?从:


<artifactId>wildfly-datasources-galleon-pack</artifactId>
复制代码


改为:


<artifactId>wildfly-datasources-preview-galleon-pack</artifactId>
复制代码


WildFly extras(WildFly Java 社区附加资源库)的维护者值得称赞,因为他们提供的这个东西确实是一个很好的补充。对于使用 WildFly“预览”版尝试数据库驱动应用程序开发来说,它是必不可少的。它是在 2022 年 2 月的第一个周被推送到 Maven 的。执行命令:


mvn wildfly-jar:dev-watch
复制代码


现在可以开始运行了。wildfly-jar-maven-plugin 会在你保存文件的同时对代码进行监控和部署。有了 wildfly-datasources-preview-galleon-pack,连接数据库就变得非常简单了。这非常好。大多数 IDE 都允许通过 Maven GUI 控件执行“mvn maven wildfly-jar:dev-watch”。下面是 IntelliJ IDEA 中 Maven 控件的截图,其中包括我们在 pom.xml 中配置的 wildfly-jar-maven-plugin



就像在命令行中执行“mvn maven wildfly-jar:dev-watch”一样,IDE 将显示构建、启动和配置示例应用程序的过程信息:


在示例应用程序的持久化单元配置中,有一个 jakarta.persistence.sql-load-script-source 属性,它引用了位于应用程序 META-INF 目录中的 my_jpa_data_table.sql 文件。该 SQL 文件被用来向示例应用程序所使用的数据库表插入一些占位记录。启动示例应用程序后,对 PostgreSQL 中的 my_jpa_data_table 表执行一条 SELECT 命令。如下所示,这是将示例应用程序指向数据库服务器并使用本文中的工具启动后,你将看到的情况:


而且,如果想证明该示例应用程序可以完全实现数据往返,则可以启动一个浏览器来显示应用程序中的数据:


如果你想看看这些工具如何加快应用程序开发,让“mvn maven wildfly-jar:dev-watch”命令保持运行,编辑示例应用中的 index.xhtml 文件并保存。你会看到应用程序迅速重新部署,你的改动立即就反映在了 Web 浏览器上。不仅是在应用程序的用户界面层面,在数据库以上的每一个层面上都是如此。


超酷的玩具。


如果你通过 wildfly-jar-maven-plugin 试用 wildfly-preview 和 wildfly-datasources-preview-galleon-pack,那么这里有几个小提示:


  • “layers”配置处理你可能需要的来自 WildFly 的任何依赖。如果要进行容器化,则可以直接添加“cloud-server”层和“postgresql-datasource”或其他与数据库相匹配的数据源层。

  • 如果不需要某些 “layers”,则可以把它们排除在外,从而为 Uber JAR 瘦身。我在插件配置中排除了一些,只是为了展示 wildfly-jar-maven-plugin 的这种能力。检查一下可用的层,根据自己的需求确定哪些是可选的或非必要的。

  • 你需要将应用程序中的 javax 命名空间更新为 jakarta。WildFly 的常规版本既允许使用比较旧的 javax 命名空间,也允许使用比较新的 jakarta 命名空间,但预览版把重点放在了 Jakarta EE 上,所以你在 Java 源代码中需要一直使用 import jakarta.。如果这适用于你的项目,那么 web.xml*文件也应如此。

  • 请记住,这是一个预览版,所以在生产中最好还是使用常规版本。重要提示!

  • 你会注意到,我们没有在任何地方定义应用程序可以在哪里找到数据库服务器以及其中的数据库。wildfly-datasources-preview-galleon-pack 将从环境变量中读取这些信息。现在,你也可以在 WildFly 内部设置,但在实践中,我推荐使用环境变量。这有利于应用服务器/应用程序 Uber JAR 的容器化。以下是在 Linux 上配置数据库环境变量的例子:


export POSTGRESQL_HOST=server.withyourdatabase.comexport POSTGRESQL_PORT=5432export POSTGRESQL_DATABASE=quickDbexport POSTGRESQL_USER=yourUsernameexport POSTGRESQL_PASSWORD=yourSecretPassword
复制代码


另外,在 IDE 中配置数据库环境变量的例子:


在遇到这个插件,并在 WildFly 社区的帮助下使用预览版连接到数据库后,我很快就离不开这个工具组合了。我责备自己:“我怎么会错过这个?”而且,这些 Galleon“功能包”和 wildfly-jar-maven-plugin 为开发者提供了非常好的体验,让人乐在其中。这一点在 mvn wildfly-jar:dev-watch 上表现得尤为明显!


此外,在处于活跃开发状态时,“mvn wildfly-jar:dev-watch”还是很有用的,它让开发者可以获得一个可感知数据库的 JAR,具有 WildFly 固有的所有功能,可以随时部署。有了这个插件,这个过程就很简单了,只要发出命令:


mvn clean package wildfly-jar:package
复制代码


真是超酷的工具!

需要考虑的配置项

使用 wildfly-jar-maven-plugin,可以解决基本的应用程序配置问题。你将看到,在示例代码中,有几个(几乎是)空文件,可以用来添加应用程序环境变量,并发出一些额外的配置命令,以完成 WildFly 的设置。


从 package_script.cli 文件可以看到,我添加了下面这行配置:


/system-property=somePropertyName:add(value=somePropertyValue)
复制代码


它将属性“somePropertyName”设置为“somePropertyValue”。其效果和在命令行上发出下面这行命令一样:


${JBOSS_HOME}/bin/jboss-cli.sh /system-property=somePropertyName:add(value=somePropertyValue)
复制代码


在示例代码中,插件引用的 package_script.cli package_properties.properties 文件,似乎足以满足大多数应用服务器配置需求。尽管如此,对于它们提供的这种灵活性,有一些配置任务的最佳做法我还不确定。不是说没有办法解决这些配置问题,但仍然需要制定个计划。


例如,需要保持凭证安全的情况。如果应用程序要进入Kubernetes环境,那么你可能会使用像Bitnami Sealed SecretsHashiCorp Vault这样的东西来应对这个挑战。在你的工作站上,或者是在你能控制操作环境的服务器上,应用程序可以引用这个环境。


但是,如果最适合应用程序的做法是在 WildFly 容器内存储这些凭证呢?WildFly 包含一个优秀的安全子系统Elytron,所以使用该工具将是一个很自然的选择。你应该考虑在 WildFly 内部借助 Elytron 存储凭证的功能。


在工作站或服务器上,你可以使用*${JBOSS_HOME}/bin/jboss-cli.sh*命令添加一个“secret-key-redential-store”。这一系列的命令可能是下面这样:


history --disable/subsystem=elytron/secret-key-credential-store=secret-key-credential-store:add(relative-to=jboss.server.config.dir, path=secretKeyCredentialStore.cs)/subsystem=elytron/secret-key-credential-store=secret-key-credential-store:export-secret-key(alias=key)/subsystem=elytron/expression=encryption:add(resolvers=[{name=secret-key-resolver, credential-store=secret-key-credential-store, secret-key=key}])
复制代码


到目前为止,一切顺利。但是,这个“确保 WildFly 内部凭证安全”配置任务的第一只拦路虎现在出现了。你需要发出以下两个命令,为第一个命令的明文密码(输入)创建一个表达式,并将该命令的输出添加到“凭证库”中,这两个命令是从属关系:


/subsystem=elytron/expression=encryption:create-expression(resolver=secret-key-resolver, clear-text=passwordThatNoOneWillEverGuess)
/subsystem=elytron/credential-store=credential-store:add(relative-to=jboss.server.config.dir, path=credentialStoreCandela.cs, credential-reference={clear-text= OUTPUT_OF_PREVIOUS_COMMAND_AS_INPUT_HERE }, create=true)
复制代码


在终端窗口中,将一个命令的输出链接到另一个命令非常简单。或者在最坏的情况下,这是一个偶尔执行的系统管理任务,你只需将第一个命令中的表达式剪切并粘贴到第二个命令中。这项任务接下来的工作也相当简单,你只需要发出:


/subsystem=elytron/credential-store=credential-store:generate-secret-key(alias=key)/subsystem=elytron/expression=encryption:list-add(name=resolvers, value={name=resolver, credential-store=credential-store, secret-key=key})reload/subsystem=elytron/expression=encryption:write-attribute(name=default-resolver, value=resolver)reload/subsystem=elytron/expression=encryption:create-expression(clear-text=passwordThatNoOneWillEverGuess)history --enable/subsystem=elytron/credential-store=credential-store:add-alias(alias=MyFirstCredential, secret-value=doNotShareThis)/subsystem=elytron/credential-store=credential-store:add-alias(alias=MySecondCredential, secret-value=AlsoDoNotShareThis)/subsystem=elytron/secret-key-credential-store=secret-key-credential-store:read-aliases/subsystem=elytron/credential-store=credential-store:read-aliases
复制代码


上面的“reload”命令是完成任务所必需的,在工作站或服务器上都不是问题。通过“mvn wildfly-jar:watch-dev”和“mvn clean package wildfly-jar:package”命令即时完成这项任务则有所不同。由这些工具执行的即时配置并不会指示应用服务器重新读取及重新加载其主配置文件,而在这个特定的配置任务中,这是一个必要的步骤。是否有什么方法可以处理这样一个稍显复杂的配置?当然有。也许只需在选定的 Maven 阶段复制一个配置文件和适当的支持文件。也许可以在 package_script.cli package_properties.properties 中加入特定内容,看看能走多远。


怎样做最好?鉴于使用 wildfly-jar-maven-plugin 的时间相对还比较短,我还不能确定。我的初步想法是,wildfly-preview-datasources-galleon-pack 非常灵活,也许可以创建一个 “wildfly-credential-store-galleon-pack”或类似的新工具工件,用于应对这一特定情况。也许可以把 galleon-pack 加入到插件配置中,由它读取一大堆环境变量(也许有预定义的命名规则?),或者是从安全地存储在开发工作站上应用程序存储库之外的属性文件中读取。这将使你能够将这些凭证安全地加载到 Elytron 中,就像 wildfly-preview-datasources-galleon-pack 实时处理数据库连接一样。


同样,我只是选择了在 WildFly 内部确保凭证安全这样一个场景,如果你要使用这个插件,就需要额外做些计划。我相信,如果你把应用程序打包在一个可启动的 JAR 中,那么你可以根据自己的部署需求想象出其他配置任务。

需求永无止境

这真是太酷了。你还想要什么呢?我很高兴你这么问,因为如果我不想要更多,那我还算什么终端用户?


我想使用Eclipse Vert.x驱动连接数据库,并希望这些驱动能够进入 wildfly-datasources-preview-galleon-pack 中。这个愿望得以实现的前提是,新版本的 Hibernate(WildFly 的JPA和 ORM 实现)以及 Hibernate Reactive 发布。Hibernate 网站显示,那将是 5.6 版本。Hibernate 5.3 打包了 wildfly-preview。如果Hibernate ORM 6Jakarta EE 10之前达到稳定状态,这也许就不是问题了。从Quarkus这样的项目中可以看到 Hibernate Reactive 带来的好处,我很想看到 WildFly 中也提供这些功能,只要这些新增功能不违反 Jakarta EE 标准。这应该不是问题,因为该标准通常不排斥应用服务器和/或工具供应商提供“更多”的特性。


还有一个WildFly MicroProfile Reactive Feature Pack,但不像 Panache,我在那个项目库中没有看到任何对 Hibernate Reactive 的具体引用。

结语

这些不仅仅是新玩具,而且是有用的工具。如果你正在为开发数据库驱动的应用程序了解 wildfly-preview,那么不妨试一试 wildfly-jar-maven-plugin wildfly-datasources-preview-galleon-pack


我在 GitHub 上发布了一个小的示例项目,如果你想快速试用一下这个新工具组合,那么可以从这里入手。其中包括前面提到的那个简单的 Docker 文件,还有一个 Kubernetes YAML 文件示例。该示例代码中有一个参考 SQL 文件,可以配置 JPA 持久化单元和 JPA 对象。如果你向表中填充了数据,还有一个 JSF 页面可以把它们显示出来。wildfly-datasources-preview-galleon-pack 使可启动 JAR 包能够感知数据库,你只需付出很少的努力(只需设置环境变量以指向你的数据库),就可以让示例应用程序获取并显示数据。

相关资源

Jakarta EE确实是 Java 生态系统的重心。如果你没有通过一个或多个实现整个标准的应用服务器(如 WildFly)直接使用它,那么你也很可能在间接地使用它的一个库,由生态系统中其他 Java 项目提供的实现。本文讨论的工具将使使用 Jakarta EE 和 WildFly 成为一种特别愉快的经历。在 Java 和 Jakarta EE 领域有许多了不起的事情发生,这个领域的活动似乎只会加速。要想不错过一些能真正提高生产力,改善这一基本标准的使用体验的东西,可能是一个不小的挑战。除了Eclipse基金会(Jakarta EE 的管理机构)之外,Jakarta EE Ambassadors也是一个很棒的社区和开发者资源。这是一个很好的方式,让你可以了解 Jakarta EE 本身及周边的情况。如果你还不是社区成员,那么还请考虑加入 Jakarta EE Ambassadors,以此为途径参与到这一部分 Java 生态系统。


再次感谢wildfly-extras团队。WildFly项目提供了许多好工具,可不止这里讨论的这两个。这些工具中的每一个都增加了使用Jakarta EE和 WildFly 开发应用程序的乐趣!


作者简介:


Dennis Gesker是一位经验丰富的 Java 开发人员,也是Jakarta EE Ambassadors的成员。他目前正致力于Candela Global项目。这是一个社交媒体金融科技项目,将于今年晚些时候推出。


原文链接:


Two Must-Have Tools for Jakarta EE Developers

2022-04-30 08:002186

评论

发布
暂无评论
发现更多内容

Mysql大法-Mysql索引失效VS Mysql存储引擎

知识浅谈

8月月更

[JS真好玩] InfoQ创作者必备: 监控每天是谁取关了你?

HullQin

CSS JavaScript html 前端 8月月更

索信达控股上半年成绩出炉:核心业务收入大幅增长75.3%

索信达控股

一文读懂隐私公链Findora生态布局

股市老人

开源一夏 | React对于生命周期的深入研究

恒山其若陋兮

开源 8月月更

Hash算法详细介绍与实现(一)

迷彩

hash算法 8月月更

盘点:阿里云效平台的5大替代解决方案

PingCode

后端面试必备知识点

浅羽技术

Java 面试 后端 8月月更

如何快速地学习东西(上篇)

宇宙之一粟

学习 成长 8月月更

StarRocks 与奥威软件完成产品兼容认证,共同打造数据驱动的智慧企业

StarRocks

数据库

隐私公链Findora生态布局,隐私赛道发展急先锋

EOSdreamer111

开源一夏 |为什么线程池不允许使用Executors去创建?

六月的雨在InfoQ

开源 OOM Executors ThreadPoolExecutor 8月月更

当满世界喧嚣“All in Web3”,但你可以慢慢来

One Block Community

区块链 程序员 开发者 就业 黑客马拉松

J-Tech Talk | 编写Dockerfile的最佳实践

Jina AI

Docker J-Tech Talk

每日一R「16」实践课之 kv-server(二)

Samson

学习笔记 8月月更 ​Rust

vim设置go语法高亮

程序员欣宸

vim 8月月更

乐观锁和悲观锁各自应用场景

浅羽技术

Java 乐观锁 悲观锁 8月月更

MySQL常见面试题

浅羽技术

MySQL 数据库 面试 后端 8月月更

[JS入门到进阶] 哎,被vite小坑了一波,大家记得配置build.cssTarget为'chrome61'

HullQin

CSS JavaScript html 前端 8月月更

1个理念4个步骤,快速上手客户体验管理

创意时空

拆解实体门店转型升级中的体验思维

创意时空

云原生(二十七) | Kubernetes篇之自建高可用k8s集群前置概念与操作

Lansonli

云原生 k8s 8月月更

我是咖啡师,在软件公司上班|ONES 人物

万事ONES

什么是数据结构

乌龟哥哥

8月月更

购物体验值急转直下?消费体验的症结和解药在这里!

创意时空

SMTP协议详解

工程师日月

8月月更

leetcode 205. Isomorphic Strings 同构字符串(简单)

okokabcd

LeetCode 算法与数据结构

头脑风暴:二叉搜索树中的众数

HelloWorld杰少

算法 LeetCode 8月月更

一文读懂隐私公链Findora生态布局

BlockChain先知

一文读懂隐私公链Findora生态布局

鳄鱼视界

页面切换转场动画,英雄救场更有趣!

岛上码农

flutter ios 前端 移动端开发 8月月更

Jakarta EE开发者必备的2个工具_编程语言_InfoQ精选文章