Java EE Webアプリケーションをモジュール化して組み合わせる

これはJava EE Advent Calendarの9日目の記事です。

完全に市民権を得た感じのあるSpring Bootですが、機能は複数のjarに分けて固められており、jarを追加するだけで機能を追加することが出来ます。
それと同じ事をJava EEでもやってみようというお話です。

たとえば、以下のようなクラスを用意します。

@WebFilter(urlPatterns = "/*", filterName = "auth")
public class AuthenticationFilter implements Filter {
    @Override
    public void init(FilterConfig fc) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain fc) throws IOException, ServletException {
        if (!authorize(authKey, req)) {
            sendError(res);
            return;
        }
        fc.doFilter(req, res);
    }

    private void sendError(ServletResponse res) throws IOException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }

    private boolean authorize(String authKey, ServletRequest req) throws ServletException {
        //実際の認証処理
    }

    @Override
    public void destroy() {
    }
}

これをauthrization.jarにまとめて、認証処理を通したい場合はクラスパスに通して、認証処理を通したくない場合はクラスパスからはずせば認証処理だけモジュール化することが出来ます。

これはテストのときに非常に便利です。
また、各モジュールの祖結合化が進み、可搬性もあがります。


これを応用すると、テストのときと本番のときとで使用するライブラリを入れ替えられることにも気が付くと思います。
aaa-production.jarとaaa-test.jarを用意して、それぞれで同じ名称のXXX.javaを作成します。
通常、CDIを利用しているとQualifierを定義してテストのときだけプライオリティを変更して云々とかやって、テストするだけでひどい苦労をするのですが、そういったことよりはもうクラス自体入れ替えてしまえばいいんじゃないかとか。

JAX-WSでエンドポイントから生成したJAX-WSクライアントライブラリについてもテスト環境と本番環境でどうせ違うのはURLだけだったりするので、テストのときだけフックしてURL書き換えてーとかするよりはこちらのほうが簡単になります。


という感じで。

最後にmavenでライブラリを切り替える方法だけ説明をしておくと、mavenではprofileの仕組みがあり、profileのところに依存関係を書くことで特定のprofileのみ依存するjarを増やすみたいなことが出来ます。

〜略〜
    <profiles>
        <profile>
            <id>release</id>
            <dependencies>
                <dependency>
                    <groupId>xxxxx</groupId>
                    <artifactId>auth</artifactId>
                    <version>1.0</version>
                </dependency>
            </dependencies>
        </profile>
        <profile>
            <id>development</id>
            <dependencies>
                <dependency>
                    <groupId>xxxxx</groupId>
                    <artifactId>auth-test</artifactId>
                    <version>1.0</version>
                </dependency>
            </dependencies>
        </profile>
    </profiles>
〜略〜


終わり。