Apache Ant не будет заниматься математикой - PullRequest
3 голосов
/ 09 ноября 2011

Я использую распределенный исходный код для работы над проектом на Java, и для правильной работы исходный код должен быть создан с использованием специального сценария Ant. Проблема в том, что когда я запускаю скрипт, я получаю

BUILD FAILED
C:\[path]\autobuild.xml:47: Only 1 operation can be specified

Строки 47-59 читать:

<math result="months" datatype="int">
    <op op="-">
        <op op="+">
            <num value="${month}"/>

            <op op="*">
                <num value="${year}"/>
                <num value="12"/>
            </op >
        </op>
        <num value="24097"/>
    </op>
</math>

Я попытался погуглить фразу ошибки, и единственным результатом является Ant-источник MathTask.java , где он показывает, что это то, что должно произойти, если операция пуста. Я попытался изменить код в соответствии с:

<op type="-">

или

<op op="subtract">

но это выдает ту же ошибку. Я изменил это вместо:

<subtract>

и теперь ошибки нет, но результат всегда равен нулю. Я также попытался сократить математическую строфу до одной операции:

<math result="months" datatype="int">
    <op op="subtract">
        <num value="27940"/>
        <num value="24123"/>
    </op>
</math>

но проблема остается.

Я в полном недоумении. Кто-нибудь знает, что здесь происходит? Я использую новейшую версию Ant ... $ {month} и ​​$ {year} установлены правильно (я также проверял жестко запрограммированные числа, и это все еще не работает).

Спасибо!

Ответы [ 3 ]

6 голосов
/ 05 марта 2013

У меня была такая же проблема с этим фрагментом кода. Самое смешное, что большую часть времени это работает. Ошибка возникала примерно каждый пятый раз, когда я запускал свой скрипт сборки.

<math datatype="int" result="rndNum">
    <op op="+">
        <num value="42000" />
        <op op="*">
           <num value="1000"/>
           <op op="random"/>
        </op>               
    </op>
</math>

Я удалил атрибут datatype из математического задания и поместил его в первую операцию.

<math result="rndNum">
    <op datatype="int" op="+">
        <num value="42000" />
        <op op="*">
           <num value="1000"/>
           <op op="random"/>
        </op>               
    </op>
</math>

Пока это работает. Посмотрим, как долго :) Я удалю свой ответ, если он не сработает.

4 голосов
/ 06 марта 2013

Вам не нужны никакие дополнительные задачи муравья или дополнительные языки сценариев, просто используйте встроенный движок сценариев javascript, который поставляется вместе с java (начиная с jdk 1.6, собственная реализация Sun основана на rhino 1.6R2) и вставьте макрос для повторного использования, то есть:

<project>
  <property name="foo" value="22"/>
  <echo>$${foo} => ${foo}</echo>

  <!-- create macrodef -->
  <macrodef name="math">
   <attribute name="operation"/>
   <attribute name="operator1"/>
   <attribute name="operator2"/>
   <attribute name="result"/>
   <sequential>
    <script language="javascript">
     tmp = 0;
     switch ("@{operation}")
     {
      case "+" :
       tmp = parseInt("@{operator1}") + parseInt("@{operator2}");
       break;
      case "-" :
       tmp = parseInt("@{operator1}") - parseInt("@{operator2}");
       break;
      case "*" :
       tmp = parseInt("@{operator1}") * parseInt("@{operator2}");
       break;
      case "/" :
       tmp = parseInt("@{operator1}") / parseInt("@{operator2}");
       break;
     }
     project.setProperty("@{result}", tmp);
    </script>
   </sequential>
 </macrodef>

  <!-- create new properties -->
  <math operation="/" operator1="${foo}" operator2="11" result="foooo"/>
  <math operation="+" operator1="${foo}" operator2="21" result="fooo"/>
  <!-- overwrite existing property foo -->
  <math operation="+" operator1="${foo}" operator2="1" result="foo"/>
  <echo>
  create    => $${fooo} => ${fooo}
  create    => $${foooo} => ${foooo}
  overwrite => $${foo}  => ${foo}
  </echo> 
</project>

Если вам нужно перезаписать существующее свойство пользователя (= те свойства, которые определены в командной строке с помощью ant -f foobar.xml -Dmyuserproperty = foo ...), вы должны использовать метод

project.setUserProperty()
1 голос
/ 09 ноября 2011

Я думаю, это показывает, почему Ant не следует использовать в качестве языка программирования.: -)

Вместо этого следует использовать встроенный язык сценариев, например Jython или Groovy .

<groovy>
month = Integer.valueOf(properties["month"])
year = Integer.valueOf(properties["year"])

properties["months"] = 24097 - ((year * 12) + month)
</groovy>
...