English 中文(简体)
Ant无法找到外部定义的taskdef所需的类。
原标题:
  • 时间:2009-01-27 04:20:56
  •  标签:

我正在尝试使用axis-java2wsdl ant任务从我的一个java类创建wsdl,但我无法正确设置类路径。

我正在使用Ubuntu的libaxis-java包,它将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

蚂蚁能够找到axis-java2wsdl任务的定义,因为axis-ant.jar在$ANT_HOME/lib中,但它无法找到axis.jar中的类,即使该jar在“libraries”定义的路径上。

我知道这是一个类路径问题,因为我可以通过在$ANT_HOME/lib中创建符号链接axis.jar来绕过DefaultAuthenticator到其他未找到的类。 如何让taskdef在不将所有内容都符号链接到$ANT_HOME/lib的情况下识别/usr/share/lib或我的项目的本地lib目录中的jar文件?

编辑:

最终,我成功生成了这个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中无法定义这些库是我做错了什么。

最佳回答

一般来说,这是可行的。但是你需要非常仔细地检查哪些课程在哪里。

如果您的任务类可以在类加载器层次结构中更高的类加载器中加载(如CLASSPATH或ANT_HOME / lib),则将忽略您的classpathref。

阅读常见问题解答了解更多细节。

Ant的类加载器实现使用Java的委托模型。

ClassLoader类使用委托模型来搜索类和资源。每个ClassLoader实例都有一个关联的父类加载器。当要查找类或资源时,ClassLoader实例将在尝试自己查找类或资源之前委托其父类加载器查找类或资源。虚拟机的内置类加载器,称为引导类加载器,本身没有父级,但可以作为ClassLoader实例的父级。

注意:运行ant -diagnostics也会有所帮助

问题回答

Ant添加库的机制是:

  • via command line argument -lib
  • adding to ${user.home}/.ant/lib
  • adding to ${ant.home}/lib

只有。 手册 没有提到使用 system.library.dir 属性的任何信息。可能它基本上被忽略了。

此外,以详细模式运行ant( -verbose)以查看其底层操作。

为什么不选择最简单的方法,在<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不是一个好主意,几乎总是可以避免。

matt b所述,通过在taskdef任务中直接指定classpath对我很有用。 我发现将taskdef库包含在项目文件夹中,并在ant构建文件中指定classpath,可以轻松地在其他开发计算机上进行设置。 我使用以下taskdef:

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

请注意,此方法可能不适用于早于1.7.0版本的Ant。

使用这里的答案和所有部分信息,我想出了一个解决方案。我将ant文件所需的jar添加到项目中的lib文件夹中(特别是mysql jdbc驱动程序)。然后我在ant中运行一个设置任务,将其复制到用户的home .ant/lib文件夹中,然后使用一条消息失败,要求重新启动。它只会因为用户失败一次,然后每次都能工作。如果你将这个jar更新到一个新版本,可能会很棘手...

这是蚂蚁构建的 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>

希望这有所帮助。

当我将一个*.jar复制到{ant.home}/libs时,我遇到了同样的问题,然后我使用-lib来定位 *.jar,它可以正常运行!我认为这是因为新的jar无法加载,所以我会进行测试!





相关问题
热门标签