ぺんぎんらぼ

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です。たまに絵を描きます。

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です

Eclipseで始めるJava SEでJPA (Jakarta Persistence) アプリケーション

データベースにアクセスするアプリケーションを作るとき、どのような方法でデータベースアクセスを実装してますか?やっぱりMyBatis?まさかのJDBC
Jakarta EEではデータベースアクセスのフレームワークとしてJPA (Jakarta Persistence PI) というものが用意されています。日本では残念ながら知名度が低いフレームワークです。

今回は、この「JPA」を使って、データベースから取得した値を画面に表示するコンソールアプリケーションを作成します。
なんと、Javaクラスを2つ、設定ファイルを2つ作成するだけなので、ぜひ、Java SEによるJPAアプリケーションを体験してみてください。

アプリケーションの作成

Gradleプロジェクトの作成

EclipseのBuildshipプラグインを使って、Gradleプロジェクトを作成します。

プロジェクト名を入力するだけで、数クリックでプロジェクトが作成できます。

検証目的のプロジェクトなので、フラットなシングルプロジェクトとして作成するのもよいでしょう。
Buildshipプラグインで、Gradleのシングルプロジェクトを作成する方法は、以下の記事で解説しています。

penguinlabo.hatenablog.com

build.gradleの編集

build.gradleを編集して、Jakarta EEのプロジェクトとして必要な設定を記載します。

plugins {
    id 'java-library'
}
apply plugin: 'eclipse'

sourceCompatibility = '17'
targetCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.hibernate:hibernate-core:6.4.4.Final'
    implementation 'com.h2database:h2:2.2.224'
}
依存関係の設定
dependencies {
    implementation 'org.hibernate:hibernate-core:6.4.4.Final'
    implementation 'com.h2database:h2:2.2.224'
}

JPAのライブラリを依存関係に追加します。
ここで指定しているライブラリはJPAの実装となるhibernateを指定しています。
また、今回はインメモリデータベースであるH2を使うので、H2のJDBCドライバも依存関係に追加しています。

Gradleプロジェクトのリフレッシュ

build.gradleファイルの変更内容をプロジェクトに反映する必要があります。

プロジェクトを右クリックして、[Gradle] - [Gradleプロジェクトのリフレッシュ]を実行します。

JREシステム・ライブラリー」がbuild.gradleファイルで指定したバージョンのJavaになっていること、「プロジェクトと外部の依存関係」にhibernateのライブラリとH2のJDBCドライバが追加されていることが確認できます。

エンティティの作成

エンティティとは、データベースのテーブルと一対一となるクラスです。

  • テーブル = エンティティクラス
  • テーブルの列 = エンティティクラスのフィールド

という形でクラスを作成します。
今回は以下のテーブルに対応するエンティティクラスを作成します。

テーブル名 : profile

列名 列型 属性
id 数値 主キー
name 文字列 非NULL値
birthday 日付

このテーブルのエンティティクラスは以下のようになります。

import java.io.Serializable;
import java.time.LocalDate;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class Profile implements Serializable {
    @Id
    private int id;
    
    @Column(nullable = false)
    private String name;

    private LocalDate birthday;

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public LocalDate getBirthday() { return birthday; }
    public void setBirthday(LocalDate birthday) { this.birthday = birthday; }
}

クラスは単純なPOJPと同様で、フィールドとフィールドのGetter、Setterの実装です。

エンティティの実装方法はクラス名をテーブル名、フィールド名を列名と同じ名前にします。
そして、クラスに@Entityアノテーションを、主キーに対応するフィールドに@Idアノテーションを指定します。
また、非NULL値の列に対応するフィールドに@Column(nullable = false)アノテーションを指定します。

mainメソッドの作成

データベースにアクセスするmainメソッドを実装したクラスを作成します。

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

public class Main {

    public static void main(String[] args) {
        try (EntityManagerFactory emf = Persistence.createEntityManagerFactory("defaultPU");
                EntityManager em = emf.createEntityManager()) {
            em.getTransaction().begin();
            Profile entity = em.find(Profile.class, 1);
            System.out.println("Hello " + entity.getName());
            em.getTransaction().commit();
        }
    }
}

主キーを使ってテーブルからレコードを取得する部分は、

em.find(Profile.class, 1)

です。引数の「1」が検索する主キーの値で、復帰値はレコードの内容が格納されたProfileクラスになります。

設定ファイルの作成

Jakarta Persistence 3.1 まではpersistence.xmlという設定ファイルが必須になります。
このファイルはMETA-INFフォルダに作成する必要があります。src/main/resourcesMETA-INFフォルダを作成して、そのフォルダにpersistence.xmlファイルを作成します。

次のバージョンとなるJakarta Persistence 3.2では、PersistenceConfigurationというクラスを使って、設定ファイルレスでJPAが使えるようになる予定です。
指定しているスキーマファイル「persistence_3_0.xsd」やversion属性が3.0と古いバージョンになっていますが、3.1用のスキーマファイルが提供されておらず、3.1でもpersistence.xmlの内容に変更がないため、3.0を指定しています。
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
             version="3.0">
    <persistence-unit name="defaultPU" transaction-type="RESOURCE_LOCAL"> 
        <properties>
            <property name="jakarta.persistence.jdbc.driver"   value="org.h2.Driver" />
            <property name="jakarta.persistence.jdbc.url"      value="jdbc:h2:mem:test" />
            <property name="jakarta.persistence.jdbc.user"     value="sa" />
            <property name="jakarta.persistence.jdbc.password" value="" />
            <property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>
            <property name="jakarta.persistence.sql-load-script-source" value="data.sql"/>
        </properties>
    </persistence-unit>
</persistence>

今回のお試し実装ではデータベースの接続情報と2つのプロパティを設定しています。

<property name="jakarta.persistence.jdbc.driver"   value="org.h2.Driver" />
<property name="jakarta.persistence.jdbc.url"      value="jdbc:h2:mem:test" />
<property name="jakarta.persistence.jdbc.user"     value="sa" />
<property name="jakarta.persistence.jdbc.password" value="" />

インメモリデータベースであるH2の接続情報を定義しています。他のデータベースに接続する場合は、この部分を変更します。

<property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>

起動時にデータベースに対するアクションです。エンティティクラスに対応するテーブルを削除(drop)して、エンティティクラスの定義内容に従ってテーブルを作成(create)する設定です。

<property name="jakarta.persistence.sql-load-script-source" value="data.sql"/>

データ読み込み用のスクリプトファイルからDML文を読み込んで実行します。基本的に、このスクリプトファイルにテーブルに挿入するSQL文を記載して、テーブルを初期化します。

データ読み込み用のスクリプトの作成

先ほど作成したpersistence.xmljakarta.persistence.sql-load-script-sourceで定義したdata.sqlファイルを作成します。
ファイル名のみでパスが指定されていないので、src/main/resources直下に配置する必要があります。

INSERT INTO profile (id, name, birthday) VALUES (1, 'Matsuki', '2021-12-31')

profileテーブルに主キー列idに値が「1」のレコードをINSERTするSQLです。

作成完了!!

以上で、必要なファイルの作成は終わりです。
以下のようなファイル配置になります。

アプリケーションの動作確認

作成したアプリケーションを実行します。

正しく動作していれば、コンソールに以下のように表示されます。

2月 18, 2024 8:14:37 午前 org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [name: defaultPU]
2月 18, 2024 8:14:37 午前 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 6.4.4.Final
2月 18, 2024 8:14:37 午前 org.hibernate.cache.internal.RegionFactoryInitiator initiateService
INFO: HHH000026: Second-level cache disabled
2月 18, 2024 8:14:37 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using built-in connection pool (not intended for production use)
2月 18, 2024 8:14:37 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: Loaded JDBC driver class: org.h2.Driver
2月 18, 2024 8:14:37 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001012: Connecting with JDBC URL [jdbc:h2:mem:test]
2月 18, 2024 8:14:37 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {password=****, user=sa}
2月 18, 2024 8:14:37 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
2月 18, 2024 8:14:37 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH10001115: Connection pool size: 20 (min=1)
2月 18, 2024 8:14:39 午前 org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2月 18, 2024 8:14:39 午前 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@2007435e] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
2月 18, 2024 8:14:39 午前 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@16a2ed51] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hello Matsuki
2月 18, 2024 8:14:39 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:h2:mem:test]

Eclipseで始めるJakarta EE 10プログラミング超入門 ③ - JPAアプリケーションの作成

データベースにアクセスするアプリケーションを作るとき、どのような方法でデータベースアクセスを実装してますか?やっぱりMyBatis?まさかのJDBC
Jakarta EEではデータベースアクセスのフレームワークとしてJPA (Jakarta Persistence PI) というものが用意されています。日本では残念ながら知名度が低いフレームワークです。

今回は、この「JPA」を使って、データベースから取得した値を画面に表示するWebアプリケーションを作成します。
なんと、Javaクラスを3つ、設定ファイルを2つ作成するだけなので、ぜひ、Jakarta EEによるJPAアプリケーションを体験してみてください。

アプリケーションの作成

プロジェクトの用意

Jakarta EEのプロジェクトが必要です。以前の記事を参考にプロジェクトを用意してください。

penguinlabo.hatenablog.com

Webアプリケーションサーバの用意

eclipse上でWebアプリケーションサーバを立ち上げるための設定をします。
ほとんどのWebアプリケーションサーバはzipファイルを展開して、eclipse上にサーバ・ランタイムを登録するだけです。

エンティティの作成

エンティティとは、データベースのテーブルと一対一となるクラスです。

  • テーブル = エンティティクラス
  • テーブルの列 = エンティティクラスのフィールド

という形でクラスを作成します。
今回は以下のテーブルに対応するエンティティクラスを作成します。

テーブル名 : profile

列名 列型 属性
id 数値 主キー
name 文字列 非NULL値
birthday 日付

このテーブルのエンティティクラスは以下のようになります。

import java.io.Serializable;
import java.time.LocalDate;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotNull;

@Entity
public class Profile implements Serializable {
    @Id
    private int id;
    
    @NotNull
    private String name;

    private LocalDate birthday;

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public LocalDate getBirthday() { return birthday; }
    public void setBirthday(LocalDate birthday) { this.birthday = birthday; }
}

クラスは単純なPOJPと同様で、フィールドとフィールドのGetter、Setterの実装です。

エンティティの実装方法はクラス名をテーブル名、フィールド名を列名と同じ名前にします。
そして、クラスに@Entityアノテーションを、主キーに対応するフィールドに@Idアノテーションを指定します。
また、非NULL値の列に対応するフィールドに@NotNullアノテーションを指定します。

データベースアクセスの作成

データベースにアクセスするクラスを作成します。Jakarta EEではEJBというクラスで作成しますが、今回はEJBとは何か?という部分は理解しなくでもよいです。

import jakarta.ejb.Stateless;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;

@Stateless
public class ProfileBean {
    @PersistenceContext
    private EntityManager em;

    public Profile findById(int id) {
        return em.find(Profile.class, id);
    }
}

今回はfindByIdメソッドとして、主キーで検索するメソッドを実装しています。
EntityManager型のフィールドを定義して、そのフィールドに@PersistenceContextアノテーションを指定します。こうすることで、JPAがデータベースアクセスを肩代わりしてくれるEntityManagerが作成されます。
そして、メソッド内でEntityManagerのfindメソッドを呼び出すことで、主キーによるテーブルアクセスが実行されます。

サーブレットの作成

以上でデータベースにアクセスするクラスの作成は完了です。
最後に、これまでのクラスを使ってデータベースから値を取得して、Webブラウザに表示するためのサーブレットクラスを作成します。

import java.io.IOException;

import com.sandbox.jakarta.web.ejb.ProfileBean;

import jakarta.ejb.EJB;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {

    @EJB
    private ProfileBean profileBean;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.getOutputStream().print("Hello " + profileBean.findById(1).getName());
    }
}

主キーを使ってテーブルからレコードを取得する部分は、

profileBean.findById(1)

です。引数の「1」が検索する主キーの値で、復帰値はレコードの内容が格納されたProfileクラスになります。

設定ファイルの作成

Jakaera EE 10 まではpersistence.xmlという設定ファイルが必須になります。
このファイルはMETA-INFフォルダに作成する必要があります。src/main/resourcesMETA-INFフォルダを作成して、そのフォルダにpersistence.xmlファイルを作成します。

次のバージョンとなるJakarta Persistence 3.2では、PersistenceConfigurationというクラスを使って、設定ファイルレスでJPAが使えるようになる予定です。
指定しているスキーマファイル「persistence_3_0.xsd」やversion属性が3.0と古いバージョンになっていますが、3.1用のスキーマファイルが提供されておらず、3.1でもpersistence.xmlの内容に変更がないため、3.0を指定しています。
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
             version="3.0">
    <persistence-unit name="defaultPU" transaction-type="JTA"> 
        <properties>
            <property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>
            <property name="jakarta.persistence.sql-load-script-source" value="data.sql"/>
        </properties>
    </persistence-unit>
</persistence>

本来であれば、persistence.xmlに接続先データベースのデータソース名や接続情報を記載しますが、今回はお試しなので、JPAがデフォルトで持っているインメモリデータベースのH2を使用します。
接続情報を記載しなかった場合、このH2データベースが使用されます。

アプリケーションサーバWildFly、PayaraはデフォルトでH2データベースが使用されますが、WebSphere LibertyはデフォルトのJNDI名に対応するデータソースが定義されていないというエラーが発生します。 デフォルトでH2データベースが使用されないアプリケーションサーバはデータソースの定義とJNDI名の指定が必要になります。

今回のお試し実装では2つのプロパティを設定しています。

<property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>

起動時にデータベースに対するアクションです。エンティティクラスに対応するテーブルを削除(drop)して、エンティティクラスの定義内容に従ってテーブルを作成(create)する設定です。

<property name="jakarta.persistence.sql-load-script-source" value="data.sql"/>

データ読み込み用のスクリプトファイルからDML文を読み込んで実行します。基本的に、このスクリプトファイルにテーブルに挿入するSQL文を記載して、テーブルを初期化します。

データ読み込み用のスクリプトの作成

先ほど作成したpersistence.xmljakarta.persistence.sql-load-script-sourceで定義したdata.sqlファイルを作成します。
ファイル名のみでパスが指定されていないので、src/main/resources直下に配置する必要があります。

INSERT INTO profile (id, name, birthday) VALUES (1, 'Matsuki', '2021-12-31')

profileテーブルに主キー列idに値が「1」のレコードをINSERTするSQLです。

作成完了!!

以上で、必要なファイルの作成は終わりです。
以下のようなファイル配置になります。

アプリケーションの動作確認

作成したアプリケーションをWebアプリケーションサーバに追加して、Webアプリケーションサーバを起動します。

Webアプリケーションサーバによってポートが違ったり、プロジェクトによってコンテキストルートが変わったりしますが、ほとんどのケースでは以下のURLをWebブラウザで開けば、作成したServletアプリケーションが動作して結果が表示されます。

http://localhost:8080/プロジェクト名/hello

正しく動作していれば、以下のような画面が表示されます。

Eclipseで始めるJakarta EE 10プログラミング超入門 ② - Servletアプリケーションの作成

Jakarta EEのアプリを作ったことがなくても、JavaでWebアプリを作ったことがあるなら「サーブレット」という言葉が聞いたことがあると思います。
サーブレット」はJavaでWebアプリケーションを構築するうえで、基本的で低レベルな方式となります。

今回は、この「サーブレット」でWebアプリケーションを作成します。画面に文字列を表示するだけのアプリケーションです。
なんと、Javaクラスを1つ作成するだけなので、ぜひ、Jakarta EEによるServletアプリケーションを体験してみてください。

アプリケーションの作成

プロジェクトの用意

Jakarta EEのプロジェクトが必要です。以前の記事を参考にプロジェクトを用意してください。

penguinlabo.hatenablog.com

Webアプリケーションサーバの用意

eclipse上でWebアプリケーションサーバを立ち上げるための設定をします。
ほとんどのWebアプリケーションサーバはzipファイルを展開して、eclipse上にサーバ・ランタイムを登録するだけです。

サーブレットの作成

HelloServletクラスを作成します。適当なパッケージ配下に以下のJavaクラスを作成します。

import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException  {
        response.getOutputStream().print("Hello World");
    }
}

Servlet2.5まではweb.xmlサーブレットマッピングにURLとサーブレットの対応を定義する必要がありました。
Servlet3.0からはWebServletアノテーションサーブレット実装クラスにURLを定義できるようになりました。ここらへんはSpring Frameworkに近い感じですね。

アプリケーションの動作確認

作成したアプリケーションをWebアプリケーションサーバに追加して、Webアプリケーションサーバを起動します。

Webアプリケーションサーバによってポートが違ったり、プロジェクトによってコンテキストルートが変わったりしますが、ほとんどのケースでは以下のURLをWebブラウザで開けば、作成したServletアプリケーションが動作して結果が表示されます。

http://localhost:8080/プロジェクト名/hello

正しく動作していれば、以下のような画面が表示されます。

Eclipseで始めるJakarta EE 10プログラミング超入門 ① - Gradleプロジェクトの作成

Jakarta EE (旧Java EE)でアプリを作ってみたいけど、Jakarta EEは難しそうだしなー。とりあえず簡単に始められるSpring Bootでいいか。

という方、多くないですか?そもそも、Spring Bootがあるから、Jakarta EEは興味ない!って人も多いと思います。
Jakarta EEは壮大なフレームワークで、日本語の情報が少ないため、とっつきにくい、というのも否定できません。

でも、お仕事プログラマーをしてると、大規模なエンタープライズアプリの開発で、Jakarta EEを使いことは少なくありません。
そんな時のために、Jakarta EEで最低限のプログラムが書けるようになっておきましょう!!

Jakarta EEのプロジェクトの作成

今回はプログラミングをする前に、Jakarta EEのプロジェクトを作成します。
Eclipseでは、新規プロジェクトの作成で「動的Webプロジェクト」を選ぶことで、Jakarta EEのプロジェクトを作成できます。
しかし、「動的Webプロジェクト」で作成したプロジェクトはMavenやGradleなどのビルドツールを使わないプロジェクトになっています。
プロジェクトの管理をしやすくするために、今回はGradleプロジェクトとしてJakarta EEのプロジェクトを作成します。

Gradleプロジェクトの作成

EclipseのBuildshipプラグインを使って、Gradleプロジェクトを作成します。

プロジェクト名を入力するだけで、数クリックでプロジェクトが作成できます。

検証目的のプロジェクトなので、フラットなシングルプロジェクトとして作成するのもよいでしょう。
Buildshipプラグインで、Gradleのシングルプロジェクトを作成する方法は、以下の記事で解説しています。

penguinlabo.hatenablog.com

build.gradleの編集

build.gradleを編集して、Jakarta EEのプロジェクトとして必要な設定を記載します。

plugins {
    id 'java-library'
}
apply plugin: 'war'
apply plugin: 'eclipse'
apply plugin: 'eclipse-wtp'

sourceCompatibility = '17'
targetCompatibility = '17'

repositories {
    mavenCentral()
}

eclipse {
    wtp {
        facet {
            facet name: 'jst.java', version: '17'
            facet name: 'jst.web', version: '6.0'
        }
    }
}

dependencies {
    compileOnly 'jakarta.platform:jakarta.jakartaee-api:10.0.0'
    testCompileOnly 'jakarta.platform:jakarta.jakartaee-api:10.0.0'
}

以下に、各項目の内容を解説しますが、興味がない方は、このサンプルをそのまま使って、以下の説明は読み飛ばしてください。

プラグインの設定
plugins {
    id 'java-library'
}
apply plugin: 'war'
apply plugin: 'eclipse'
apply plugin: 'eclipse-wtp'

Gradle内で必要となるプラグインを指定します。

Javaのバージョン
sourceCompatibility = "17"
targetCompatibility = "17"

sourceCompatibilityで、Javaソースのバージョンを指定します。
targetCompatibilityで、コンパイルで生成されるクラスファイル(バイトコード)の互換性を指定します。

Mavenリポジトリの指定
repositories {
    mavenCentral()
}

依存関係の解決にMaven Centralを使用する指定です。

eclipseのWebアプリケーションの設定
eclipse {
    wtp {
        facet {
            facet name: 'jst.java', version: '17'
            facet name: 'jst.web', version: '6.0'
        }
    }
}

eclipseのWebアプリケーションの設定を定義します。

facet name: 'jst.java'でJavaファセットのバージョンを、facet name: 'jst.web'で動的Webモジュールファセットのバージョンを指定します。
eclipseでプロジェクトのプロパティーのプロジェクト・ファセットに表示される使用するファセットとバージョンに反映されます。
動的Webモジュールのファセットを有効にしないと、eclipse上でサーバにデプロイ(追加)することができなくなるため、設定を定義しています。
動的Webモジュールとは、Jakarta EEのJakarta Servletに当たります。

依存関係の設定
dependencies {
    compileOnly 'jakarta.platform:jakarta.jakartaee-api:10.0.0'
    testCompileOnly 'jakarta.platform:jakarta.jakartaee-api:10.0.0'
}

Jakarta EE 10のライブラリを依存関係に追加します。
ここで指定しているライブラリは空実装となっており、機能しません。
実行時にJakarta EEのライブラリはWebアプリケーションサーバに含まれるものが使用されるので、コンパイルするための空実装のライブラリとなります。

Webアプリリソースのディレクトリ作成

Webアプリのリソースを格納するディレクトリを作成します。
一般的には、今回のbuild.gradleファイルで指定したとおり、src/main/webappです。 src/mainディレクトリに「webapp」ディレクトリを作成します。

Gradleプロジェクトのリフレッシュ

build.gradleファイルの変更内容をプロジェクトに反映する必要があります。

プロジェクトを右クリックして、[Gradle] - [Gradleプロジェクトのリフレッシュ]を実行します。

JREシステム・ライブラリー」がbuild.gradleファイルで指定したバージョンのJavaになっていること、「プロジェクトと外部の依存関係」にJakarta EEのライブラリが追加されていることが確認できます。

EclipseでGradleのシングルプロジェクトを作る

EclipseではBuildshipプラグインによりGUIで簡単にGradleのプロジェクトを作成することができます。

ある時、Gradleのプロジェクトを作成したところ、プロジェクトが入れ子になった「マルチプロジェクト」としてプロジェクトが作成され、「なんで?」となりました。

Gradleの6.7からマルチプロジェクトになった

Gradleのバージョン6.7からプロジェクトの構成が変更され、マルチプロジェクトになりました。
次のように、作成したプロジェクトに「lib」という名前のサブプロジェクトが追加されます。

旧来のシングルプロジェクトを作る

マルチプロジェクトはある程度大きなアプリケーションを作るときは、分割したプロジェクトをまとめることができて便利です。
しかし、小さなアプリケーションや検証目的でちょっとしたプロジェクトを作りたいときは、旧来のシングルプロジェクトのほうがディレクトリ構成が深くならず、見通しが良いと思います。

EclipseのBuildshipプラグインでGradleのシングルプロジェクトを作成する方法を解説します。

プロジェクトの作成

Eclipseから、新規のGradleプロジェクトを作成します。
その際、オプションの指定で、「ワークスペース設定を上書き」チェックボックスをチェックし、「Gradleバージョンの指定」で6.7未満のバージョンを選択します。
また、古いGradleは古いJavaでないと動作しないため、「拡張オプション」の「Javaホーム」でGradleに対応するバージョンのJavaのフォルダを指定します。

GradleとJavaのバージョンの互換性は、以下のページにまとめられています。

docs.gradle.org

作成したプロジェクトは次のように、フラットな旧来の「シングルプロジェクト」構成になっていることがわかります。

Gradleのバージョンアップ

シングルプロジェクトは作成できましたが、作成したプロジェクトのGradle Wrapperのバージョンが古いものになっている点が気になります。

そこで、プロジェクトのGradle Wrapperのバージョンを変更することにします。

プロジェクトのgradle/wrapperフォルダのgradle-wrapper.propertiesを変更します。

distributionUrlで指定されているgradleのバージョンを変更します。

distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip

gradle-wrapper.propertiesを直接変更しても構いませんが、Gradle 2.4からは、コマンドからバージョンを変更することもできます。
このコマンドは、gradle-wrapper.propertiesを書き換えているだけです。

gradlew wrapper --gradle-version=8.5

最後に、書き換えたgradle-wrapper.propertiesのバージョンに合わせて、Gradle Wrapper本体のjarファイルと起動コマンドgradlewを更新します。
以下のコマンドで更新されます。

gradlew wrapper

最新版FESS - 本運用環境で起動する

最新版FESSの設定方法

FESSの各種設定方法は公式サイトで公開されていますが、検索サイトで検索すると、古いバージョンのドキュメントが検索結果の上位に表示されることが多いです。
ここではバージョン14にて、よく使う設定を抜粋して、まとめておきます。

そのFESS、開発モードで動いてないですか?

FESSの左上を確認してください。左上のユーザーの横に「⚠」アイコンが表示されてませんか?
アイコンが表示されているのであれば、マウスカーソルを当ててみてください。次のようなメッセージが表示されるはずです。

開発モードで起動しています。本運用環境ではOpenSearchを別途インストールしてください。

FESSをダウンロードして実行すると、検索エンジンに組み込みのElasticSearchが使用されます。
この「組み込みのElasticSearch」は、とりあえず、というものなので、本格的に運用するのであれば、別途、OpenSearchを導入したほうがいいです。

OpenSearchのインストール

FESSのバージョンに対応したOpenSearchをインストールする必要があります。
FESSのダウンロードページでは、FESSのバージョンごとに適応するOpenSearchのダウンロードリンクがあるので、こちらからOpenSearchのzipファイルをダウンロードします。

ダウンロードしたOpenSearchを任意の場所に展開すれば、インストールは終了です。

OpenSearchプラグインインストール

OpenSearchにいくつかのプラグインをインストールする必要があります。
必要なプラグインプラグインのバージョンはOpenSearchのバージョンによって変わるので、インストールしたバージョンのFESSに対応するインストールガイドを参照してください。

設定ファイルの更新

OpenSearchの設定

まずは、OpenSearchの設定です。
OpenSearchをインストールしたフォルダのconfigフォルダにある「opensearch.yml」を書き換えます。
書き換える箇所は2か所で、configsync.config_pathにパスの設定、plugins.security.disabledをtrueに変更します。

configsync.config_path: [OpenSearchをインストールした絶対パス]/data/config/
plugins.security.disabled: true

Windowsであれば、パスの記載は次のようにします。パス区切りに「/」を使う点に注意しましょう。

configsync.config_path: C:/OpenSearch/data/config/
plugins.security.disabled: true

FESSの設定

次に、FESSの設定です。 FESSをインストールしたフォルダのbinフォルダにある「fess.in.bat」ファイルを書き換えます。
書き換える箇所は2か所で、fess.search_engine.http_addressとfess.dictionary.pathの設定がコメントアウト(REM)されているので、コメントアウト(REM)を削除します。
そして、fess.dictionary.pathに先ほどOpenSearchのconfigsync.config_pathに設定したパスと同じものを、こちらにも設定します。

REM External opensearch cluster
set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Dfess.search_engine.http_address=http://localhost:9200
set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Dfess.dictionary.path=[OpenSearchをインストールした絶対パス]/data/config/

FESSの起動

OpenSearchの起動

FESSを起動する前に、OpenSearchを起動します。
OpenSearchをインストールしたフォルダのbinフォルダにある「opensearch.bat」を実行します。
OpenSearchの起動には時間がかかるので、しばらく待ちます。

FESSの起動

OpenSearchが起動したら、次にFESSを起動します。 FESSをインストールしたフォルダのbinフォルダにある「fess.bat」を実行します。
先ほどの設定作業で「fess.in.bat」ファイルを書き換えましたが、こちらを実行する必要がないことに注意しましょう。

起動後の確認

起動したらFESSをWebブラウザで開きます。
FESSの左上を確認してください。左上のユーザーの横に「⚠」アイコンが表示されてなければ、正常にOpenSearch検索エンジンとして使用されています。

最新版FESS - デスクトップ検索の設定

最新版FESSの設定方法

FESSの各種設定方法は公式サイトで公開されていますが、検索サイトで検索すると、古いバージョンのドキュメントが検索結果の上位に表示されることが多いです。
ここではバージョン14にて、よく使う設定を抜粋して、まとめておきます。

デスクトップ検索とは

ローカルPCで FESS を起動して、ファイルシステムをクロールした場合、デフォルトでは検索結果から該当ファイルにアクセスできません。
デスクトップ検索を有効にすると、検索結果のリンクから該当ファイルにアクセスすることができます。

サーバー・クライアントの環境ではデスクトップ検索は利用することはできません。

デスクトップ検索の設定

bin/fess.in.bat (Linuxの場合は bin/fess.in.sh) の java.awt.headless を true から false に変更します。

set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Djava.awt.headless=false

app/WEB-INF/classes/fess_env_crawler.properties に以下の内容を追加します。

search.desktop=true