2012-02-03 2 views
0

Чтение свойств в файле свойств с ant не соблюдает порядок.Чтение свойств в файле свойств с ant не соблюдает порядок

Порядок не соблюдается:

Пример:

<property file="build.properties" prefix="prefix."/> 
<propertyselector property="cases" match="prefix.project\.(.*)" select="\1"/> 
<for list="${cases}" param="pr"> 
<sequential> 
<echo message="Project: @{pr} Version: ${[email protected]{pr}}"/> 
</sequential> 
</for> 

с:

build.properties

project.1 = 1.2.3 
project.8 = 5.9.4 
project.4 = 3.5.0 

Получить:

Project: 8 Version 5.9.4 
Project: 1 Version 1.2.3 
Project: 4 Version 3.5.0 

(И результат кажется случайным образом изменен) Мне нужно построить их в порядке, как они появляются в файле build.properties?

ответ

2

Файл свойства читается в правильном порядке. Вы можете проверить это, просто вставив дубликаты свойств и узнайте, какой из них определяется. Вот build.properties:

dup.prop = foo 
dup.prop = bar 

А вот мой Ant скрипт:

<project> 
    <property file="build.properties"/> 
    <echo>Dup.prop is set to "${dup.prop}".</echo> 
</project> 

Запуск этого, я получаю:

Dup.prop is set to "foo". 

Это потому, что значение Foo определяется первым в build.properies , и как только свойство определено, оно не может быть (легко) изменено.

Что вы пытаетесь сделать, так это получить доступ к свойствам в том порядке, в котором они определены. Это не гарантируется, поскольку свойства хранятся в хеше.

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

Во-первых, Ant - это язык матрицы построения, что означает, что он имеет иерархию зависимостей. Самые большие разработчики проблем пытаются заставить языки матрицы построения выполнять в определенном порядке. Вы должны указать иерархию зависимостей в ваших файлах build.xml (и чем меньше там, тем легче для Ant получить все правильно).

Если подпроект «B» зависит от файла jar в подпроекте «A», он должен быть в сценарии Ant-проекта «B» зависимой от сборки j-блока подпроекта «A».

<project name="proj-b"/> 
    ... 
    <target name="build-jar" 
     depends="test.if.jar.exists" 
     unless="jar.exist"> 
     <ant directory="${proj.a.dir}" 
      target="build.depend.jar"/> 
    </target> 

    <target name="test.if.jar.exists"> 
     <condition property="jar.exists"> 
      <available file="${proj.a.dir}/dist/${dend.jar.file}"/> 
     </condition> 
    </target> 

    <target name="compile" 
     depends="build-jar"> 
     .... 
    </target> 
    ... 
</project> 

В приведенном выше build.xml для проекта «B», я завишу от некоторой банки файла, которого Проект «А» строит перед тем, как можно компилировать проект «B». Поэтому моя задача compile зависит от build-jar, которая построит файл jar Target «A». Чтобы эта задача не могла скомпилировать банку проекта «А» снова и снова, я использую <condition> в качестве теста, чтобы узнать, существует ли эта банка. Если он уже делает, я не перестраиваю банку.

В этом случае:

  • Target "компилировать" называется. Эта цель понимает, что это зависит от целевой «строительной банки».
  • Перед выполнением задачи «компиляция». Сначала вызывается цель «build-jar».
  • Целевой «сборщик» зависит от цели «test.if.jar.exists».
  • Перед «строить-банку» выполняется, он называет «Target test.if.jar.exists»
  • В Target «test.if.jar.exists», если баночка уже существует, свойство jar.exists будет задавать.
  • Теперь объект «build-jar» активен и смотрит, установлено ли свойство jar.exists. Если это так, цель не будет выполнена.
  • И, наконец, управление возвращается к целевому «компиляции», которое затем выполняется.

Здесь я не выполняю приказ напрямую. Вместо этого у меня просто есть иерархия зависимостей, которую я указываю, и я позволил Муравью точно выяснить, что делать.

Если проблема с сомнительной емкостью является большой проблемой, вы также можете посмотреть на Ivy. Ivy позволяет создать Jar Repository. Ваши проекты, которые строят банки, остальная часть ваших проектов зависит от того, могут ли вы получить необходимые банки из этого хранилища. Это очень похоже на Maven. Фактически, Ant с Ivy может использовать репозитории Maven. Мы используем Artifactory, локальный менеджер хранилища Maven, для наших проектов Ant.

Вы также можете попробовать <subant> задачу, которая действительно позволяет указать buildpath, который позволил бы вам сказать сборки суб-проекта «А» до суб-проекта «B». Вы можете определить путь построения в другом файле Ant XML, который может зависеть от клиента, а затем использовать <import> для импорта пути сборки для этого проекта.

1

Действительно. Свойства Java представлены java.util.Hashtable, и, как вы точно знаете, хеш-таблицы не сохраняют порядок. Вы просто не можете делать то, что хотите, с файлом свойств.

Если эти «проекты», которые, как вы заявляете, хотите построить в порядке, в свою очередь представляют собой проекты Ant, вы можете захотеть переместить свои задачи в свой основной файл сборки и просто обеспечить правильный порядок здания, используя обычный Ant зависимостей.

+0

Эта основная задача муравья - мой проект упаковки, который вызывает создание других подпроектов ant, но я не могу переместить их задачи на своем уровне, потому что в зависимости от клиента некоторые проекты должны быть построены, другие нет. – itomorow

+0

Я не вижу, как это мешает вам перемещать задачи. Если у вас есть один файл сборки со всеми задачами в нем, вы можете просто вызвать его для создания требуемых задач, в зависимости от клиента. – Dolda2000

+0

Например, у меня есть только один основной проект, который нужно построить перед любым другим, поэтому в моем основном муравейте дважды повторяться в моем списке: Сначала нужно только определить, объявлен ли этот основной проект в файл свойств (если да, чтобы вызвать его задачу сборки) и другой for-loop для создания другого.Это не умное решение, но оно работает до тех пор, пока не будет объявлен другой проект и что этот проект должен быть построен на второй позиции раньше других ... Если бы я мог делать то, что я хочу, чтобы эта часть второго проекта была интегрирована как API в первом, но я не могу принять это решение. – itomorow

0

Ниже код поможет отсортировать список порожденной propertyselector тегом

<sortlist property="my.sorted.list" value="${my.list}" 
      delimiter="," /> 
<echo message="${my.sorted.list}" /> 
Смежные вопросы