@ledsun blog

無味の味は佳境に入らざればすなわち知れず

AntからJavaScriptを実行したときに起きたエラーを拾う方法

f:id:ledsun:20060924102518j:plain

Apache AntではScriptタスクを使うとJavaScirptを実行できる。 しかしJavaScriptで例外が上がると、表示される内容の9割以上がRhinoScriptEngineの例外になる。 興味があるJavaScriptの例外は一行だけ。

例外が起きるbuild.xml

<?xml version="1.0" encoding="UTF-8"?>
<project default="a">
  <target name="a">
    <script language="javascript"><![CDATA[
      throw 'わあ!';
    ]]></script>
  </target>
</project>

実行すると

C:\Users\ledsun\workingDirectory>ant
Buildfile: C:\Users\ledsun\workingDirectory\build.xml

a:

BUILD FAILED
C:\Users\ledsun\workingDirectory\build.xml:4: javax.script.ScriptException: sun.org.mozilla.javascript.internal.JavaScriptException: わあ! (<Unknown source>#2) in <Unknown source> at line number 2
        at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:156)
        at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:170)
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.util.ReflectUtil.invoke(ReflectUtil.java:108)
        at org.apache.tools.ant.util.ReflectWrapper.invoke(ReflectWrapper.java:81)
        at org.apache.tools.ant.util.optional.JavaxScriptRunner.evaluateScript(JavaxScriptRunner.java:103)
        at org.apache.tools.ant.util.optional.JavaxScriptRunner.executeScript(JavaxScriptRunner.java:67)
        at org.apache.tools.ant.taskdefs.optional.Script.execute(Script.java:52)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:392)
        at org.apache.tools.ant.Target.performTasks(Target.java:413)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
        at org.apache.tools.ant.Main.runBuild(Main.java:811)
        at org.apache.tools.ant.Main.startAnt(Main.java:217)
        at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
        at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

Total time: 0 seconds

C:\Users\ledsun\workingDirectory>

まったくもって見づらい。JavaScriptで例外をキャッチするとAntの実行結果がBuild Successになってしまう。 Antの設定でエラーを伝えようにもScriptタスクにはそれらしい属性が無い。 Execタスクにはfailonerrorがあるのに!

解決策

project.setProperty で Antプロジェクトに変数を設定し、Failタスクでエラーを検出します*1

<?xml version="1.0" encoding="UTF-8"?>
<project default="a">
  <target name="a">
    <script language="javascript"><![CDATA[
      try{
        throw '';
      }catch(e){
        project.setProperty('fail', '');
      }
    ]]></script>
    <fail if="fail" message="JavaScriptでエラーが起きた" />
  </target>
</project>

参考にしたStack Overflow : ant javascript failonerror

Ant 第2版 Pro Apache Ant (Professional Apress) Scripting in Java: Languages, Frameworks, and Patterns: Using Apache Bsf, Groovy, and PHP JavaScript 第6版 JavaScriptリファレンス 第6版

*1:プロパティに例外メッセージを設定しておけば実行結果に表示することも可能です。具体例はStack Overflowの例を見て下さい。