ApacheAntを使ってWEBアプリケーションをビルドする環境を作成

apache

実業務でWEBアプリケーションを開発する際、製造と単体試験は各メンバのパソコンで実施するかと思います。
しかし、本番リリースするアプリケーションをビルドする際は、それなりのビルドマシンを準備してビルドする方がよいです。
正式なアプリケーションを個人のパソコンでビルドするのはリスクが高いですからね。


ビルド用のマシンを準備してビルド環境を構築する際、ApacheAnt(アパッチアント)を使ってビルド環境を構築するのがシンプルで使い勝手もよいとおもいます。


ApacheAntとはいわゆるビルドツールでして、ビルド内容を定義するxmlファイルにAntタスクと呼ばれる定義を記載していくことで、ビルド環境を構築することができます。


今回はApacheAntを使ってWEBアプリケーションのビルド環境を構築する方法を紹介していきます。


環境情報


  • OS:Windows10
  • ビルドツール:ApacheAnt 1.8.2
  • Java:Java1.8.60

ApacheAntの公式サイトは以下になります。



ビルド環境の構成


Windows環境であることを前提に説明していきますが、Linux系の環境であっても同様かと思います。

Linux環境の方はパス等を読み替えて試してみてください。


ビルド環境としては以下になります。


C:---apache-ant-1.8.2       // ApacheAntはCドライブ直下に格納。
  |                         //
  |                         //
  |---buildEnv              // ビルドするプロジェクトが全て
    |                       // 格納されているフォルダ。
    |---buildPJ.bat         // ビルドを実行するBATファイル
    |                       //
    |---targetPJ            // ビルド対象プロジェクト。
        |                   //
        |                   //
        |---build           // ビルド対象プロジェクトのフォルダ。
            |               //
            |               //
            |---build.xml   // ビルド対象プロジェクトの定義ファイル。

buildEnvの下に、ビルド対象プロジェクトを格納しています。
今回は、ビルド対象プロジェクトが一つ(targetPJのみ)の例なのですが、ビルド対象プロジェクトが複数存在する場合は、この「buildEnv」下に格納する方法がよいです。


BATファイル・XMLファイルについて、以降に説明していきます。


BATファイル(バッチファイル)


ビルドする際、格納したバッチファイルである「buildPJ.bat」を実行したビルドするようにします。
「buildPJ.bat」にビルドを開始する定義をおこなっておきます。


@echo off

echo ビルド環境の準備
set ANT_HOME=C:\apache-ant-1.8.2
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_60
set CLASSPATH=.
set PATH=%ANT_HOME%\bin;%PATH%
set STDWEBAP_SETENV="OK"

echo targetPJのビルドをおこないます。
cd C:\buildEnv\targetPJ\build >> C:\buildEnv\buildTargetPJ.txt
call ant clean >> C:\buildEnvbuildTargetPJ.txt
call ant war >> C:\buildEnv\buildTargetPJ.txt
cd C:\buildEnv >> C:\buildEnv\buildTargetPJ.txt

ビルド結果をログで確認できるように、「C:\buildEnv\buildTargetPJ.txt」に実行結果を出力しています。


XMLファイル


XMLファイルの基本構成を説明する前に、ビルド対象プロジェクトを説明していきます。


今回のビルド対象プロジェクトはWEBアプリケーションを想定します。
WEBアプリケーションの場合、Javaのようなソースコード以外に、JavaScriptファイル、CSSファイル、画像ファイル、といったメタファイル(静的ファイル)も扱わなければいけません。
かつ、今回はWAR形式に圧縮する形でビルドをおこないます。
そのため、XMLファイルは複雑になりがちなので、きちんとAntタスクを使いこなす形で定義する必要があります。

ビルド対象プロジェクトのフォルダ構成は以下になります。


targetPJ--build--build.xml           // ビルド定義。
         |                           //
         |                           //
         |--src                      //
             |                       //
             |--main                 //
                 |                   //
                 |--java             // ソースコード
                 |                   //
                 |--webapp           //
                     |               //
                     |--css          // CSS
                     |               // JavaScript
                     |--js           //
                     |               //
                     |--WEB-INF      //
                        |            //
                        |--properties// プロパティ
                        |            //
                        |--lib       // ライブラリ
                        |            //
                        |--view      // JSPなど

XMLの基本構成


XMLの基本構成は以下になります。


<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<project basedir="." default="war" name="targetPJ">

    <property environment="env" />

    <!-- ----------------------------------------------- --->
    <!-- 1.アプリ名、コンテンツ格納元・先、といった     -->
    <!--     プロパティを定義                             -->
    <!-- ----------------------------------------------- --->
    <property name="app.name" value="targetWeb" />
    <property name="dest.dir" value="dest" />
    <property name="src.dir" value="../src" />
    <property name="src.script.dir" 
        value="../src/main/webapp/js" />
    <property name="dest.script.dir" 
        value="${dest.dir}/release/resource/js" />
         ・
         ・
         ・

    <!-- ------------------------------------------------ -->
    <!-- 2.クラスパス定義を追加                         -->
    <!-- ----------------------------------------------- --->
    <path id="classpath">
        <fileset dir="${lib.dir}">
            <include name="*.jar" />
        </fileset>
    </path>

    <!-- ------------------------------------------------ -->
    <!-- 3.初期化とクリーン                             -->
    <!-- ------------------------------------------------ -->
    <target name="init" depends="clean">
        <mkdir dir="${dest.dir}" />
    </target>
    <target name="clean">
        <delete dir="${dest.dir}" />
    </target>

    <!-- ------------------------------------------------ -->
    <!-- 4.warファイル作成                              -->
    <!-- ------------------------------------------------ -->
    <target name="war" depends="init,compile">
        <echo message="warファイルを作成します。" />
        <jar destfile="${dest.dir}/${app.name}.war" 
           basedir="${dest.webcontents.dir}">
            <manifest>
                <attribute name="version" value="1.0.0" />
            </manifest>
        </jar>
    </target>

    <!-- ------------------------------------------------ -->
    <!-- 5.コンパイル                                   -->
    <!-- ------------------------------------------------ -->
    <target name="compile">
        <echo message="ビルドを行います。" />
        <mkdir dir="${dest.class.dir}" />
        <javac debug="true" destdir="${dest.class.dir}" 
            includeantruntime="false" source="${source}" 
            target="${target}" encoding="UTF-8">
            <src path="${src.dir}" />
            <classpath refid="classpath" />
        </javac>
    </target>

    <!-- ------------------------------------------------ -->
    <!-- 6.静的ファイルのコピー                         -->
    <!-- ------------------------------------------------ -->
    <target name="contents">

        <copy preservelastmodified="true" 
            todir="${dest.css.dir}" flatten="no">
            <fileset dir="${css.dir}" includes="**/*.css" />
            <fileset dir="${css.dir}" includes="**/*.htc" />
            <fileset dir="${css.dir}" includes="**/*.png" />
            <fileset dir="${css.dir}" includes="**/*.gif" />
            <fileset dir="${css.dir}" includes="**/*.svg" />
        </copy>
    </target>
</project>

Antタスク(アントタスク)


「XMLの基本構成」で使用しているAntタスクについて、特に重要なタスクについて説明してきます。


  • <property>タスク

主に、「1.アプリ名、コンテンツ格納元・先、といったプロパティを定義」で使用しているAntタスクです。


<property>タスクは、XMLファイル内で使用する変数に値を格納するタスク定義です。
以下の例では、「src.script.dir」という定数名に”../src/main/webapp/js”という値を格納しています。


<property name="src.script.dir" value="../src/main/webapp/js" />

大きなプロジェクトになるほど、XMLファイルは複雑になります。
<property>タスクを使って、定数定義をおこなっておいた方が見やすい定義になります。


  • <path>タスク

「2.クラスパス定義を追加」で使用しているAntタスクです。


<path>タスクは、idで指定したパスに新たなパスを追加することができるAntタスクになります。
「2.クラスパス定義を追加」では、<fileset>タスク・<include>タスクを使用して、jarファイルのパスをクラスパスに設定して、ビルドがおこなえるようにしています。


  • <target>タスク

「3.初期化とクリーン」でも使用していますが、他の箇所でも多く使用しているAntタスクです。


<target>タスクは、初期化やコンパイルといった大きなタスクを括りを定義できるタスクです。
「■BATファイル」の中で以下の2行を定義しています。


call ant clean >> C:\buildEnvbuildTargetPJ.txt
call ant war >> C:\buildEnv\buildTargetPJ.txt

「clean」「war」という2つのタスクを、<target>タスクに定義することでBATファイルからの定義を可能としています。


<target>タスクで囲ったタグの間に、定義した名称で実行するタスクを定義します。


<target name="clean">
    <delete dir="${dest.dir}" />
</target>

上記例では、「clean」という名称で実行するタスクを定義しています。


かつ、「3.初期化とクリーン」では、<mkdir>タスク・<delete>タスクを使用して、ビルド環境を初期化しています。
<mkdir>タスクはフォルダ作成のタスクになります。
<delete>タスクは削除のタスクになります。


  • <javac>タスク

「5.コンパイル」で使用しているAntタスクです。


構文は難しくないですが、ポイントとしては「includeantruntime」です。
「includeantruntime」とは、”ビルドにAntのライブラリを使用するか?”という属性になります。
この属性をfalseしておかないと、ビルドにAntのライブラリを参照してしまい、ビルドに失敗してしまう場合があります。


  • <copy>タスク

「6.静的ファイルのコピー」で使用しているAntタスクです。


JavaScriptファイル、CSSファイル、画像ファイル、といった静的ファイルのコピーをおこなっています。
「preservelastmodified」をtrueにすいることで、ファイルのタイムスタンプも保持したままコピーすることができます。


<fileset>タグを使い、コピーする対象ファイルを、拡張子指定のワイルドカードで指定をおこなっています。


まとめ


ApacheAntを使えば、ビルドルールをあらかじめ定義することができ、安定したビルド環境を構築することができます。


きちんと開発をおこなっていても、ビルドで失敗して不具合が発生したら悔しいですからね。


紹介してきれていないAntタスクを沢山ありますので、皆さんで調べていろいろ試してみてください。



FortniteAPIを使って対戦履歴を取得する

fortnite-Victory Royale

Fortniteおもしろいですよね。
筆者もハマっています。
下手ですが。


自分の対戦履歴(プレイ時間やキル数、など)などを知りたいなと思い、調べてみると「Fortnite Tracker」というサイトで調べることができます。


こういうサイト作ってみたいなと思い、もうちょっと調べてみるとAPIが準備されているみたいですね。
でも、このAPIのいい感じの日本語ドキュメントが見つからず。。。


という訳で、自分なりにAPIの処理結果を解析してみたので、その結果を紹介していきます


環境情報


使用するAPIは、Rakuten Rapid APIで公開されているAPIを使用します。
Epic(Fortniteの運営会社)が公開しているAPIをラップしている形ですかね。
使いやすいです。


今回は、上記のAPIをPHPから呼び出して、処理結果をWEBページに表示する形にします。


  • 言語:PHP5.5.35
  • API:Rakuten Rapid API/Fortnite-API

Rakuten Rapid API は従量課金制ですが、お試しで使う分には課金されるまではトラフィックは使わないと思います。


ステータス取得のAPI実行


APIの実行サンプルを紹介します。


今回はcurlを使ってAPIを実行しています。
キー情報(x-rapidapi-key)は、Rakuten Rapid APIで取得したキー情報を使用します。


Fortnite APIは、「Status」「Others」「PVE」の3つがありますが、戦歴を取得できるのは「Status」のようです。
「Status」APIをcurlで実行して、取得した結果をJSONデコードします。


$curl = curl_init();
curl_setopt_array($curl, array(
    CURLOPT_URL => "https://fortnite-api.p.rapidapi.com/stats/" . $_POST['__nickname'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => array(
        "x-rapidapi-host: fortnite-api.p.rapidapi.com",
        "x-rapidapi-key: '※APIのキー"
    ),
));
$response = curl_exec($curl);

// 実行失敗時はエラー表示
$err = curl_error($curl);
curl_close($curl);
if ($err) {
    echo "cURL Error #:" . $err;
} 

// JSONの処理結果をデコード
$resDecode = json_decode($response, true);

ソロ結果


ソロ結果を表示するWEB画面を作りました。

ニックネームを入力して「表示する」ボタンを押下すると、ニックネームユーザの戦歴が画面上に表示されます。


以下に、API実行結果の解析方法を紹介していきます。


ソロ結果の画面表示


「Fortnite Tracker」のソロ結果表示画面は以下になります。
吹き出しでコメントを入れている数値が、APIで取得できているはず、という事です。


FortniteAPIの実行結果

ソロ結果のAPI取得


FortniteAPIの実行結果に対する日本語マニュアルがみつからず、筆者が独自で解析した結果をまとめます。


まず、ソロ結果は”defaultsolo”キーに格納されているようです。

ソロ結果の格納場所
ソロ結果の各値

  • マッチ数

‘matchNum’キーの値。


  • 勝利数(ビクロイ)

‘winrate’キーの値。


  • キル数

‘kills’キーの値。


  • 勝率(ビクロイ率)

‘winrate’キーの値。


  • 1日あたりのキル数

‘kills’キーの値 / ’matchNum’キーの値。


  • TOP10の入賞数

‘placetop10’キーの値。


  • TOP25の入賞数

‘placetop25’キーの値。


  • 総プレイ時間

‘minutesplayed’キーの値。
値は分なので、日と時間にするには計算が必要。


  • 1マッチの平均時間

‘minutesplayed’キーの値 / ’matchNum’キーの値


  • 1マッチの平均キル数

‘kills’キーの値 /’matchNum’キーの値


  • 1分あたりのの平均キル数

‘kills’キーの値 /’mminutesplayed’キーの値


  • 1マッチの平均スコア数

‘score’キーの値 /’matchNum’キーの値


  • 1分あたりのの平均スコア数

‘score’キーの値 /’minutesplayed’キーの値


  • 総スコア数

‘score’キーの値。