« ♪コントラバス・コールユーブンゲン・練習 | トップページ | ANTでJarにまとめる、Jarをまとめる »

単純ANTとJAVAメモ:幾つかの落とし穴回避のための

<?xml version="1.0" encoding="UTF-8"?>
<!-- build.xml -->
<project default="main">
   <target name="main" depends="clean,build,run">
      <echo>=== CLEAN BUILD and RUN done ===</echo>
   </target>
   <target name="build">
      <javac srcdir  ="."
             includes="*.java"
             includeAntRuntime="false"
             encoding="UTF-8"
             debug   ="yes"
             optimize="no" >
         <compilerarg value="-Xlint:deprecation" />
      </javac>
   </target>
   <target name="run">
      <java classname  ="HelloWorld"
            classpath="."
            fork       ="true"
            failonerror="true"  >
            <!-- output="out.txt" error="err.txt" -->
         <arg line="ANT TEST"/>
         <!-- <jvmarg value="-Xrunhprof:cpu=times,file=cpu_times.txt" /> -->
      </java>
   </target>
   <target name="clean">
      <delete dir="." includes="*.class,*.BAK"/>
   </target>
</project>

 シンプルANTとJava

どんなツールにも落とし穴があります。 つまらないことに嵌り無駄な時間を浪費することになりがちです。

それを避けるため本質ではないビルド記述など大概は一度動いたものを使いまわし ていきます。そして徐々に無関係な記述が多くなり、再び 嵌る事になります。

そこで、可能な限りシンプルなANTのbuild.xml記述のメモ。

includeAntRuntime=falseは 邪魔になるANTの無用なワーニングが出るのを抑止します。
classpath="."これがないとHelloWorldが 見つからないというエラーに「なったりします」
line=は重要な 記述で、value=としてしまうと空白も含めて1引数となります。
encoding=も落とし穴となりがちなものです。
jvmargでjavaコマンドオプションを指定します。 -Xrunhproffは実行時の関数の消費時間などのプロファイルを出す指定です。(この例では 指定はコメントアウトしてあり無効状態です)
必須ではありませんが、標準出力、標準エラー出力のリダイレクトは output=,error=で行います。
includesで複数要素をしていする場合のデリミッターはカンマです。
コンパイルオプション-Xlint:deprecationは必須です

単純なJavaプログラムを示します。

// HelloWorld.java
public class HelloWorld{
   public static void main(String[]args){
      try{
         System.out.print("Hello");
         for(String s:args) {
            System.out.printf(" (%s)",s);
            }
         System.out.println(" World!");
         }
      catch(Exception e){
         e.printStackTrace(System.err);
         System.exit(1);
         }
      System.exit(0);
      }
   }
これを先頭で示したbuild.xmlでantを動かすと、次のような結果が得られます。
Buildfile: ####/SimpleANT/build.xml

clean:

build:
    [javac] Compiling 1 source file

run:
     [java] Hello (ANT) (TEST) World!

main:
     [echo] === CLEAN BUILD and RUN done ===

BUILD SUCCESSFUL
Total time: 1 second

引数ANTとTESTが普通に分かれていることが分かります。line= の代わりにvalue=を使ってしまうと一つの引数になってしまいます。

このシンプルな動作ではtry{}catchは不要ですが、必ず入れる習慣を付けておくのが 良いと思います。

System.exit()により終了ステータスを示すことも習慣としておくべきものです。

 antを動かすWindowsバッチスクリプト

Unixでは端末画面からantコマンドを打ちますが、Windowsではコマンドプロンプト が恐ろしく使いづらいので現実的ではありません。
次のようなバッチファイルを作成し、クリックすることで実行させます。

:: A00_clean.bat
call ant clean
pause
:: A01_build.bat
call ant build
pause
:: A05_run.bat
call ant run
pause
:: A10_test.bat
call ant
pause

antコマンドがバッチプログラムなのでcallで呼び出します。 結果の画面を消さないためpauseを入れてあります。

 antを動かすUNIXシェルスクリプト

Unixの場合は直接タイプすることに抵抗はないと思いますが、.shを作成しておいた 方が後で分かりやすいかも知れません。

#!/bin/sh
# AA00_clean.sh
ant clean
# do not remove this line
#!/bin/sh
# AA01_build.sh
ant build
# do not remove this line
#!/bin/sh
# AA05_run.sh
ant run
# do not remove this line
#!/bin/sh
# AA10_test.sh
ant
# do not remove this line

どのシェルで動くかを#!/bin/shで指定します。 コマンドの後ろに必ず改行が必要ですので コメント行# do not remove this lineを入れてあります。

 ソースリリース用ANT記述。改行処理、実行モード処理

ソースをリリースするための記述を載せます。

<?xml version="1.0" encoding="UTF-8"?>
<!-- release.xml -->
<project default="release">
   <property name="FOLDER" value="SimpleANT" />
   <target name="release">
      <fixcrlf srcdir="." eol="lf">
          <include name="**/*.sh" />
          <include name="**/*.csh" />
      </fixcrlf>
      <delete file="./${FOLDER}.zip"/>
      <zip destfile="./${FOLDER}.zip">
          <zipfileset dir="." prefix="${FOLDER}"
                      includes="**/*.java,*.bat,*.xml,README*.txt" />
          <zipfileset dir="." prefix="${FOLDER}"
                      includes="**/*.csh,*.sh" filemode="775"/>
      </zip>
   </target>
</project>

UnixのおバカなB-shellでも動作させるため改行をCR-LFでなく、LFにします。 fixcrlfタスクを用いています。eol="lf"は改行をlfにするという 意味です。既にlfとなっているものに対して作用させても問題は発生しません。
cshはまっとうですので CR-LFでも動きますが、念のため変更しています。愚かなB-shellではCR-LFだと 「コマンドが見つかりません」 という訳の分らないエラーメッセージを出します。

**/*.javaはANTの特殊な書き方で、ディレクトリの階層に依らず合致します。

<zip>中の<zipfileset>のfilemode=記述でファイルモードを変更できます。
zipタスクはオーバーライトしません。必ず<delete>と組み合わせる 必要があります。
なお、<copy>もオーバーライトしません。copyタスクはoverwrite="true"指定でオーバーライトが できるようになっていますので必ず指定しなくてはなりません。

   <copy> file="A.txt" tofile="X.txt" overwrite="true" </copy>

zipの中をフォルダ構成にするにはprefix=でフォルダ名を指定します。
同じ名前を繰り返し書くのは間違いのもとですのでここではプロパティ定義 <property name="FOLDER" value="simpleANT" /> で${FOLDER}に名前"simpleANT"を設定しています。SimpleANT.zipの中にSimpleANT/HelloWorld.java の形でファイルがセットされます。


ANT記述ファイル名が標準のbuild.xmlでない場合は-fオプションで指定します。

:: A90_release.bat
call ant -f release.xml
pause

 ダウンロード

実際にこの記述で作成されたSimpleANT.zipを置きます。
「右クリック-対象をファイルに保存」でダウンロードできます

展開すると次のファイルが得られます。

   SimpleANT/
      A00_clean.bat
      A01_build.bat
      A05_run.bat
      A10_test.bat
      A90_release.bat
      AA00_clean.sh
      AA01_build.sh
      AA05_run.sh
      AA10_test.sh
      build.xml
      HelloWorld.java
      README_UTF8.txt
      READEM_EUC.txt
      README_SJIS.txt
      release.xml

WindowsとLinuxで動作確認を行ってあります。

 たかがHelloWorldを出すだけに、なんと大げさなとお思いでしょうが

Javaは言語は単純で、コンパイラのチェックなどもちゃんと入るので PHPやJavascriptなどのようなおふざけ言語と違いとても易しいものです。

が、

コードは易しくても、出来あがったものを動かすのは、ものすごく 難しいのです。
単純にjavacでコンパイルしてjavaで動くなんていうのは余程運の良い人だけです。

0から作るのではなく、開発キット(本記事が提供するようなもの)をベースに すべきです。

 コピペ用サンプルとコメント

コピペ用サンプルにはあまりコメントを入れない方がよいと最近は思っています。
要らぬコメントを消す作業が入るからです。

|

« ♪コントラバス・コールユーブンゲン・練習 | トップページ | ANTでJarにまとめる、Jarをまとめる »

トラックバック


この記事へのトラックバック一覧です: 単純ANTとJAVAメモ:幾つかの落とし穴回避のための:

« ♪コントラバス・コールユーブンゲン・練習 | トップページ | ANTでJarにまとめる、Jarをまとめる »