Ant не может найти класс, необходимый внешне определенному taskdef - PullRequest
14 голосов
/ 27 января 2009

Я пытаюсь использовать задачу ant-java2wsdl ant для создания wsdl из одного из моих классов java, но я не могу получить правильный путь к классам.

Я использую пакет libaxis-java Ubuntu, который устанавливает axis-ant.jar в $ ANT_HOME / lib и axis.jar в / usr / share / java. Интересные части моего build.xml выглядят так:

<property name="library.dir" value="lib"/>
<property name="system.library.dir" value="/usr/share/java"/>
<path id="libraries">
    <fileset dir="${library.dir}">
        <include name="*.jar"/>
    </fileset>
    <fileset dir="${system.library.dir}">
        <include name="*.jar"/>
    </fileset>
</path>

<target name="genwsdl" depends="compile">
    <taskdef resource="axis-tasks.properties" classpathref="libraries"/>
    <axis-java2wsdl>
            details omitted
    </axis-java2wsdl>
</target>

Запуск ant genwsdl Результат:

/build.xml:50: taskdef A class needed by class
org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask
cannot be found: org/apache/axis/utils/DefaultAuthenticator

Ant может найти определение задачи axis-java2wsdl, потому что axis-ant.jar находится в $ ANT_HOME / lib, но не может найти классы в axis.jar, даже если этот jar находится на пути, определенном "библиотека"

Я знаю, что это проблема пути к классам, потому что я смог обойти DefaultAuthenticator для другого класса, не найденного с помощью символической ссылки axis.jar в $ ANT_HOME / lib. Как я могу заставить taskdef распознавать jar-файлы в / usr / share / lib или в локальном каталоге lib моего проекта, не вставляя все ссылки в $ ANT_HOME / lib?

EDIT:

Я наконец смог успешно сгенерировать wsdl с этой строкой:

ant -lib /usr/share/java/axis.jar -lib /usr/share/java/jaxrpc.jar -lib /usr/share/java/wsdl4j.jar -lib /usr/share/java/commons-logging.jar -lib /usr/share/java/commons-discovery.jar -lib build genwsdl

Я все равно буду очень признателен, если кто-нибудь скажет мне, что я делаю неправильно, не имея возможности определить эти библиотеки в build.xml

Ответы [ 6 ]

15 голосов
/ 27 января 2009

В общем, это работает. Но вы должны очень тщательно проверить, какие классы где.

Если ваш класс задач может быть загружен в загрузчик классов выше в иерархии загрузчиков классов (например, CLASSPATH или ANT_HOME / lib), тогда ваш classpathref просто будет проигнорирован .

Прочитайте запись FAQ для более подробной информации.

В реализации загрузчика классов Ant используется Модель делегирования Java

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

Примечание: запуск ant -diagnostics тоже может помочь .

5 голосов
/ 27 января 2009

Ant механизм для добавления библиотек:

  • через аргумент командной строки -lib
  • добавление в $ {user.home} /. Ant / lib
  • добавление в $ {ant.home} / lib

Только. В руководстве ничего не говорится об использовании свойства system.library.dir . Вероятно, это в значительной степени игнорируется для этой цели.

Кроме того, запустите ant в подробном режиме (и -verbose), чтобы увидеть, что происходит под капотом.

1 голос
/ 07 декабря 2010

Используя ответы здесь и всю частичную информацию, я нашел решение. Я добавил jar файл ant, необходимый в папку lib в проекте (в частности, драйверы mysql jdbc). Затем я запускаю задачу установки в ant, которая копирует в домашнюю папку пользователя .ant / lib, а затем не запускает ant с сообщением для перезапуска. Это только один раз для пользователя, а затем работает каждый раз. Это может быть сложно, если вы обновите банку до новой версии ...

Вот муравей build.xml:

<project name="data_source" default="build">

  <!-- BUILD PROPERTIES -->
  <property file="build.properties"/>

  <!-- SQL Server Properties -->
  <property name="sql.driver" value="org.gjt.mm.mysql.Driver"/>
  <property name="sql.url" value="jdbc:mysql://127.0.0.1/datastore"/>
  <property name="sql.user" value="user"/>
  <property name="sql.pass" value="password"/>

  <!-- FILE LOCATIONS  -->
  <property name="sql.dir" location="sql"/>

  <!-- INITIALIZE PROJECT -->
  <target name="init" description="Initialize the project">
      <available property="no.ant.lib.dir" file="${user.home}/.ant/lib/" type="dir" />
  </target>

  <!-- SETUP MYSQL -->
  <target name="setup_mysql" description="Copy the lib so ant can see it" unless="no.ant.lib.dir">
      <mkdir dir="${user.home}/.ant"/>
      <mkdir dir="${user.home}/.ant/lib"/>
      <copy file="lib/mysql-connector-java-5.1.13-bin.jar" todir="${user.home}/.ant/lib"/>

      <!-- ant already missed picking up the jar - we have to restart -->
      <fail message="JDBC mysql class copied to ${user.dir}/.ant/lib/ - please restart ant" />
  </target>

  <!-- BUILD DATA SOURCES -->
  <target name="build" depends="init,setup_mysql,clean_data" description="Create and populate tables">

    <sql driver="${sql.driver}" url="${sql.url}" userid="${sql.user}" password="${sql.pass}" >
      <transaction src="${sql.dir}/create_tables.sql"/>
      <transaction src="${sql.dir}/insert_data.sql"/>
    </sql>
  </target>

   <!-- CLEAN PROJECT -->
  <target name="clean" description="Cleans up project build">
    <!-- Don't clean data sources here - may get called by accident -->
  </target>

  <!-- Delete all tables and data -->
  <target name="clean_data" description="Deletes all data and tables">
    <echo>Dropping all database tables in ${sql.schema}...</echo>
    <property name="exec.command" value="mysqldump -u${sql.user} -p${sql.pass} --add-drop-table --no-data ${sql.schema} | grep ^DROP | mysql -u${sql.user} -p${sql.pass} ${sql.schema}" />
    <exec executable="sh">
      <arg value = "-c"/>
      <arg value="${exec.command}"/>
    </exec>

  </target>

</project>

Надеюсь, это поможет

1 голос
/ 27 сентября 2010

Это работает для меня, чтобы указать classpath непосредственно в задаче taskdef, как указано matt b . Для моего проекта я считаю полезным включить библиотеку taskdef в папку проекта и указать путь к классу в файле сборки ant, чтобы просто выполнить настройку для других компонентов разработки. Я использую следующую taskdef:

<taskdef resource="antenna.properties" classpath="${myprojectroot}/lib/antenna-bin-1.2.1-beta.jar"/>

Обратите внимание, что это может не работать для версий ant ранее 1.7.0.

1 голос
/ 27 января 2009

Почему бы просто не взять самый простой вариант и указать classpath в вашем <taskdef>?

<taskdef resource="axis-tasks.properties">
    <classpath>
        <fileset file="/path/to/axis/jars"/>
    </classpath>
</taskdef>

Или создайте вторую <classpath> запись, которая подмножества library.dir?

<path id="axis-tools-classpath">
    <fileset dir="/path/to/axis/home">
        <include name="*.jar"/>
    </fileset>
    <path refid="library.dir"/>
</path>

Возиться с ${ant.home}/lib не очень хорошая идея, и ее почти всегда можно избежать.

0 голосов
/ 15 апреля 2013

Я столкнулся с той же проблемой, когда копировал * .jar в {ant.home} / libs, затем я использую -lib, чтобы найти * .jar, он работает нормально! Я считаю, что новые банки не могут быть загружены, тогда я проверю это!

...