これは、なにをしたくて書いたもの?
Jakarta EEのプロジェクトのとっかかりを作れる、Eclipse Starter for Jakarta EEというものがあることは知っていたのですが、使わないまま
存在を完全に忘れていたので、1度試しておくことにしました。
Eclipse Starter for Jakarta EE
Eclipse Starter for Jakarta EEは、こちらのサイトになります。
Eclipse Starter for Jakarta EE
こんな感じで、
- Jakarta EEのバージョン
- Jakarta EEのプロファイル
- Java SEのバージョン
- ランタイム(アプリケーションサーバー)
- Dockerのサポート
をそれぞれ選択していきます。
あとは「Generate」ボタンを押すと、jakartaee-hello-world.zip
というzipファイルがダウンロードできます。
試してみる
今回の環境は、こちらです。
$ java --version openjdk 17.0.8.1 2023-08-24 OpenJDK Runtime Environment (build 17.0.8.1+1-Ubuntu-0ubuntu122.04) OpenJDK 64-Bit Server VM (build 17.0.8.1+1-Ubuntu-0ubuntu122.04, mixed mode, sharing) $ mvn --version Apache Maven 3.9.4 (dfbb324ad4a7c8fb0bf182e6d91b0ae20e3d2dd9) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 17.0.8.1, vendor: Private Build, runtime: /usr/lib/jvm/java-17-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "5.15.0-83-generic", arch: "amd64", family: "unix"
Eclipse Starter for Jakarta EEで指定する内容は、先程のキャプチャーの通りなのですが
で作成したzipファイルをダウンロードして、展開。
$ unzip jakartaee-hello-world.zip $ cd jakartaee-hello-world
中身はこんな感じですね。
$ tree . ├── Dockerfile ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src └── main ├── java │ └── org │ └── eclipse │ └── jakarta │ └── hello │ ├── Hello.java │ └── HelloWorldResource.java └── webapp ├── WEB-INF │ └── web.xml ├── images │ └── jakartaee_logo.jpg └── index.html 10 directories, 10 files
中身を少し見てみましょう。
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.eclipse</groupId> <artifactId>jakartaee-hello-world</artifactId> <version>0.1-SNAPSHOT</version> <packaging>war</packaging> <name>jakartaee-hello-world</name> <description> This is a very simple Jakarta EE application generated by the official Eclipse Starter. </description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.report.sourceEncoding>UTF-8</project.report.sourceEncoding> <maven.compiler.release>17</maven.compiler.release> <jakartaee-api.version>10.0.0</jakartaee-api.version> <wildfly.version>27.0.1.Final</wildfly.version> <compiler-plugin.version>3.11.0</compiler-plugin.version> <war-plugin.version>3.3.2</war-plugin.version> <wildfly-plugin.version>4.1.0.Final</wildfly-plugin.version> </properties> <dependencies> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-api</artifactId> <version>${jakartaee-api.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>jakartaee-hello-world</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${compiler-plugin.version}</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>${war-plugin.version}</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <!-- Execute 'mvn clean package wildfly:dev' to run the application. --> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>${wildfly-plugin.version}</version> <configuration> <version>${wildfly.version}</version> <server-config>standalone-full.xml</server-config> </configuration> </plugin> </plugins> </build> </project>
src/main/java/org/eclipse/jakarta/hello/HelloWorldResource.java
package org.eclipse.jakarta.hello; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; @Path("hello") public class HelloWorldResource { @GET @Produces({ MediaType.APPLICATION_JSON }) public Hello hello(@QueryParam("name") String name) { if ((name == null) || name.trim().isEmpty()) { name = "world"; } return new Hello(name); } }
src/main/java/org/eclipse/jakarta/hello/Hello.java
package org.eclipse.jakarta.hello; public class Hello { private String name; public Hello(String name) { this.name = name; } public String getHello(){ return name; } }
src/main/webapp/WEB-INF/web.xml
<web-app version="6.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"> <servlet> <servlet-name>jakarta.ws.rs.core.Application</servlet-name> </servlet> <servlet-mapping> <servlet-name>jakarta.ws.rs.core.Application</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
Dockerfile
FROM quay.io/wildfly/wildfly COPY target/jakartaee-hello-world.war /opt/jboss/wildfly/standalone/deployments/ CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0", "-c","standalone-full.xml"]
主要なファイルはこんなところでしょうか。WildFlyのバージョンが27.0.1.Finalと微妙に古いですね。
実行方法はREADME.md
に書かれているので、まずは起動してみます。
$ mvn clean package wildfly:dev
確認。
$ curl localhost:8080/jakartaee-hello-world/rest//hello {"hello":"world"} $ curl localhost:8080/jakartaee-hello-world/rest//hello?name=jakarta {"hello":"jakarta"}
OKですね。
wildfly:dev
で起動しているので、ソースコードを書き換えると
@GET @Produces({ MediaType.APPLICATION_JSON }) public Hello hello(@QueryParam("name") String name) { if ((name == null) || name.trim().isEmpty()) { name = "world"; } name = name + "!!"; return new Hello(name); }
変更が検知されて、すぐにビルド&再デプロイされます。
[INFO] Changes detected - recompiling the module! :source [INFO] Compiling 2 source files with javac [debug release 17] to target/classes [INFO] Exploding webapp [INFO] Assembling webapp [jakartaee-hello-world] in [/path/to/jakartaee-hello-world/target/jakartaee-hello-world] [INFO] Processing war project [INFO] Copying webapp resources [/path/to/jakartaee-hello-world/src/main/webapp] 22:54:17,068 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool -- 23) WFLYUT0022: Unregistered web context: '/jakartaee-hello-world' from server 'default-server' 22:54:17,101 INFO [org.jboss.as.server.deployment] (MSC service thread 1-5) WFLYSRV0028: Stopped deployment jakartaee-hello-world (runtime-name: jakartaee-hello-world.war) in 38ms 22:54:17,105 INFO [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0027: Starting deployment of "jakartaee-hello-world" (runtime-name: "jakartaee-hello-world.war") 22:54:17,307 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool -- 90) WFLYUT0021: Registered web context: '/jakartaee-hello-world' for server 'default-server' 22:54:17,324 INFO [org.jboss.as.server] (management-handler-thread - 1) WFLYSRV0013: Redeployed "jakartaee-hello-world.war" 〜省略〜
確認。
$ curl localhost:8080/jakartaee-hello-world/rest//hello {"hello":"world!!"} $ curl localhost:8080/jakartaee-hello-world/rest//hello?name=jakarta {"hello":"jakarta!!"}
まあ、これはWildFlyの話ですが。
Eclipse Starter for Jakarta EEのGitHubリポジトリー
Eclipse Starter for Jakarta EEはGitHubにソースコードが公開されています。こちらですね。
GitHub - eclipse-ee4j/starter: Eclipse Starter for Jakarta EE
検索しても見つかりますし、Webサイトのissue trackerの向き先がGitHubになっていることでも気づくことができます。
README.md
を見るとわかるのですが、Web UIだけではなくてMavenアーキタイプとしても実行できます。
Eclipse Starter for Jakarta EE / Generate Jakarta EE Project Using Archetypes
MavenアーキタイプとWeb UIが含まれているリポジトリーになるので、実際にWebサイトがどのバージョンで動作しているのか
わからなくなるのですが…現時点だとMavenアーキタイプは2.2.0、2.2.0を使うWeb UIは2.0.2のようです。
https://github.com/eclipse-ee4j/starter/tree/archetype-2.2.0
https://github.com/eclipse-ee4j/starter/tree/ui-2.0.2
今回は、Mavenアーキタイプの2.2.0のタグで見ていくことにしましょう。
ディレクトリはこちら。
https://github.com/eclipse-ee4j/starter/tree/archetype-2.2.0/archetype
コマンドの例として以下が書かれていますが、どういったものが指定できるのか(指定するのか)気になりますね。
$ mvn archetype:generate -DarchetypeGroupId="org.eclipse.starter" -DarchetypeArtifactId="jakarta-starter"
設定できるプロパティは、以下に定義されています。
<requiredProperties> <requiredProperty key="groupId"> <defaultValue>org.eclipse</defaultValue> </requiredProperty> <requiredProperty key="artifactId"> <defaultValue>jakartaee-hello-world</defaultValue> </requiredProperty> <requiredProperty key="version"> <defaultValue>0.1-SNAPSHOT</defaultValue> </requiredProperty> <requiredProperty key="package"> <defaultValue>org.eclipse</defaultValue> </requiredProperty> <requiredProperty key="jakartaVersion"> <defaultValue>10</defaultValue> <validationRegex>^(8|9|9.1|10)$</validationRegex> </requiredProperty> <requiredProperty key="profile"> <defaultValue>full</defaultValue> <validationRegex>^(core|web|full)$</validationRegex> </requiredProperty> <requiredProperty key="javaVersion"> <defaultValue>17</defaultValue> <validationRegex>^(8|11|17)$</validationRegex> </requiredProperty> <requiredProperty key="docker"> <defaultValue>no</defaultValue> <validationRegex>^(no|yes)$</validationRegex> </requiredProperty> <requiredProperty key="runtime"> <defaultValue>none</defaultValue> <validationRegex>^(none|glassfish|open-liberty|payara|tomee|wildfly)$</validationRegex> </requiredProperty> </requiredProperties>
雰囲気、なんとなくわかりますね。
アプリケーションサーバーなどのバージョンがどこで決まるかというと、pom.xml
内にテンプレートが埋め込まれています。
#if (${profile} == 'core') #set ($eeArtifactId = "jakarta.jakartaee-core-api") #set ($wildflyConfiguration = "standalone") #elseif (${profile} == 'web') #set ($eeArtifactId = "jakarta.jakartaee-web-api") #set ($wildflyConfiguration = "standalone") #else #set ($eeArtifactId = "jakarta.jakartaee-api") #set ($wildflyConfiguration = "standalone-full") #end #if (${jakartaVersion} == '10') #set ($eeApiVersion = "10.0.0") #elseif (${jakartaVersion} == '9.1') #set ($eeApiVersion = "9.1.0") #elseif (${jakartaVersion} == '9') #set ($eeApiVersion = "9.0.0") #else #set ($eeApiVersion = "8.0.0") #end #if (${jakartaVersion} == '8') #set ($tomeeVersion = "8.0.14") #set ($payaraVersion = "5.2022.5") #set ($glassfishContainerId = "glassfish5x") #if (${profile} == 'web') #set ($glassfishUrl = "https://repo.maven.apache.org/maven2/org/glassfish/main/distributions/web/5.1.0/web-5.1.0.zip") #else #set ($glassfishUrl = "https://repo.maven.apache.org/maven2/org/glassfish/main/distributions/glassfish/5.1.0/glassfish-5.1.0.zip") #end #else #set ($payaraVersion = "6.2023.5") #set ($tomeeVersion = "9.0.0") #set ($glassfishContainerId = "glassfish7x") #if (${profile} == 'web') #set ($glassfishUrl = "https://repo.maven.apache.org/maven2/org/glassfish/main/distributions/web/7.0.5/web-7.0.5.zip") #else #set ($glassfishUrl = "https://repo.maven.apache.org/maven2/org/glassfish/main/distributions/glassfish/7.0.5/glassfish-7.0.5.zip") #end #end #if (${jakartaVersion} == '10') #set ($wildflyVersion = "27.0.1.Final") #else #set ($wildflyVersion = "26.1.3.Final") #end
試しに指定すると、こんな感じでしょうか。
$ mvn archetype:generate \ -DarchetypeGroupId="org.eclipse.starter" \ -DarchetypeArtifactId="jakarta-starter" \ -DgroupId=org.example \ -DartifactId=my-jakartaee-hello-world \ -Dversion=0.0.1-SNAPSHOT \ -Dpackage=org.example \ -DjakartaVersion=10 \ -Dprofile=web \ -DjavaVersion=17 \ -Ddocker=yes \ -Druntime=wildfly \ -DinteractiveMode=false
指定した項目が反映されていることが確認できます。
[INFO] Parameter: groupId, Value: org.example [INFO] Parameter: artifactId, Value: my-jakartaee-hello-world [INFO] Parameter: version, Value: 0.0.1-SNAPSHOT [INFO] Parameter: package, Value: org.example [INFO] Parameter: packageInPathFormat, Value: org/example [INFO] Parameter: package, Value: org.example [INFO] Parameter: javaVersion, Value: 17 [INFO] Parameter: groupId, Value: org.example [INFO] Parameter: profile, Value: web [INFO] Parameter: runtime, Value: wildfly [INFO] Parameter: artifactId, Value: my-jakartaee-hello-world [INFO] Parameter: version, Value: 0.0.1-SNAPSHOT [INFO] Parameter: jakartaVersion, Value: 10 [INFO] Parameter: docker, Value: yes
できあがったプロジェクト内に移動。
$ cd my-jakartaee-hello-world
確認。
$ tree . ├── Dockerfile ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src └── main ├── java │ └── org │ └── example │ └── jakarta │ └── hello │ ├── Hello.java │ └── HelloWorldResource.java └── webapp ├── WEB-INF │ └── web.xml ├── images │ └── jakartaee_logo.jpg └── index.html 10 directories, 10 files
pom.xml
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>my-jakartaee-hello-world</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>jakartaee-hello-world</name> <description> This is a very simple Jakarta EE application generated by the official Eclipse Starter. </description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.report.sourceEncoding>UTF-8</project.report.sourceEncoding> <maven.compiler.release>17</maven.compiler.release> <jakartaee-api.version>10.0.0</jakartaee-api.version> <wildfly.version>27.0.1.Final</wildfly.version> <compiler-plugin.version>3.11.0</compiler-plugin.version> <war-plugin.version>3.3.2</war-plugin.version> <wildfly-plugin.version>4.1.0.Final</wildfly-plugin.version> </properties> <dependencies> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-web-api</artifactId> <version>${jakartaee-api.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>jakartaee-hello-world</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${compiler-plugin.version}</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>${war-plugin.version}</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <!-- Execute 'mvn clean package wildfly:dev' to run the application. --> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>${wildfly-plugin.version}</version> <configuration> <version>${wildfly.version}</version> <server-config>standalone.xml</server-config> </configuration> </plugin> </plugins> </build> </project>
生成されるプロジェクトの元ネタは、こちらを参照しましょう。
こんなところでしょうか。
ちなみに、Web UIの方はJakarta EE 8で作られているみたいですね。
https://github.com/eclipse-ee4j/starter/blob/archetype-2.2.0/ui/pom.xml