Jakarta EE 10 - Jakarta Expression Language 5.0 変更内容まとめ


はじめに

Jakarta EE 10 で EL が 4.0 から 5.0 へバージョンアップします。

4.0 から 5.0 の変更点をまとめます。

メジャーバージョンアップとなりますが、そんなに大きな変更は含まれていません。


関数インターフェースを受け取るメソッドの呼び出しが可能となった

EL 3.0 からラムダ式は LambdaExpression として利用可能でしたが、以下のような関数インターフェースを受け取るメソッドの呼び出しには対応できませんでした。

public static String test(Predicate<String> filter) {
    // ...
}
test(x -> x.equals('data'))

5.0 からは、ELSupport.java に追加された以下のメソッドにより、デフォルトの型変換が行われるようになりました。

private static <T> T coerceToFunctionalInterface(
    final ELContext ctx, final LambdaExpression lambdaExpression, final Class<T> type) {
  // ...
}

仕様書上は 1.23.8. Coerce A to functional interface method invocation が該当します。


インターフェースのデフォルトメソッドにプロパティアクセス可能となった

インターフェースのデフォルトメソッドはJava 8 で導入されました。

旧来は、デフォルトメソッドで提供されたメソッドにプロパティアクセスした場合に PropertyNotFoundException となっていました(これはJavaBeans仕様に基づいた挙動)。

EL 5.0 からは、インターフェースのデフォルトメソッドで定義されたプロパティにアクセス可能となりました。


jakarta.el.MethodExpression から MethodReference を取得可能となった

MethodExpression には getMethodInfo() でメソッドの情報にアクセスできましたが、アノテーションへのアクセス手段が有りませんでした。

これは、JSF4.0 で提供されるアノテーションによるリダイレクト(@Redirect) においてアノテーションへのアクセス手段を要望することから導入されました。

MethodReference に以下のメソッドが追加されます。

public MethodReference getMethodReference(ELContext context) {
    // ...
}

MethodReference は以下の情報を提供するクラスになります。

public class MethodReference {
    private final Object base;
    private final MethodInfo methodInfo;
    private final Annotation[] annotations;
    private final Object[] evaluatedParameters;
    // ...
}


Java モジュールシステムのためのモジュールディスクリプタ追加

他の仕様と同様に モジュールディスクリプタ の追加が行われています。

以下の module-info.java が追加されました。

module jakarta.el {
    exports jakarta.el;
    requires transitive java.desktop;
    uses jakarta.el.ExpressionFactory;
}

java.desktop の依存は、以下に記載する ELResolver#getFeatureDescriptors() の非推奨化 に関連するものです。


その他の変更点

  • ELResolver#getFeatureDescriptors() の非推奨化

    • java.beans.FeatureDescriptor の実装はIntrospector#getBeanInfo()を使用しており、java.bean パッケージに依存
    • java.bean パッケージは java.desktop モジュールに依存するため、モジュール化された環境で javax.el を使用する場合、java.desktop モジュールが必要となる
    • 今バージョンで非推奨化、次期(Jakarta EE 11 を予定)バージョンで削除される予定
    • 実装者のために null を返すデフォルトメソッドとして追加
  • @Deprecated だった MethodExpression.isParmetersProvided() が削除となった(APIのスペルミス)

  • Object を戻り値としていたメソッドがジェネリクス対応された

    • ELContext#convertToType(Object obj, Class<T> targetType) など
  • ELResolver.getType() は読み取り専用プロパティの場合に null を返すことが明文化された

    • これに伴い StaticFieldELResolver の挙動が仕様と異なるため統一された
  • EL環境にデフォルトインポートされる java.lang.* に加え、EL仕様に依存する仕様でデフォルトインポートされるパッケージを定義可能なことが明示された

  • 配列型のデフォルトの型変換が明示された

    • 1.23.7. Coerce A to an array of Type T として追加
    • Tomcat の実装に合わせる形の変更
  • 可変長引数のメソッド呼び出しで NullPointerException となる問題が解消された