15

我正在尝试使用 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

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

我知道这是一个类路径问题,因为通过将axis.jar 符号链接到$ANT_HOME/lib 中,我能够通过DefaultAuthenticator 到其他未找到的类。如何在不将所有内容符号链接到 $ANT_HOME/lib 的情况下让 taskdef 识别 /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 中定义这些库,我仍然会非常感激

4

6 回答 6

16

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

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

阅读常见问题解答条目以获取更多详细信息。

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

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

注意:跑步ant -diagnostics 也有帮助

于 2009-01-27T06:58:13.630 回答
5

Ant添加库的机制是:

  • 通过命令行参数 -lib
  • 添加到 ${user.home}/.ant/lib
  • 添加到 ${ant.home}/lib

仅有的。该手册没有提及有关使用system.library.dir属性的任何内容。为此目的,它可能几乎被忽略了。

此外,以详细模式(和 -verbose)运行 ant 以查看幕后操作。

于 2009-01-27T05:05:36.027 回答
1

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

于 2009-01-27T17:12:37.027 回答
1

正如matt b所提到的,我可以直接在 taskdef 任务中指定类路径。对于我的项目,我发现在项目文件夹中包含 taskdef 库并在 ant 构建文件中指定类路径很有用,以便在其他开发 PC 上简单地设置。我使用以下任务定义:

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

请注意,这可能不适用于 1.7.0 之前的 ant 版本。

于 2010-09-27T12:09:47.170 回答
1

使用此处的答案和所有部分信息,我想出了一个解决方案。我将 jar 所需的 ant 文件添加到项目中的 lib 文件夹(特别是 mysql jdbc 驱动程序)。然后我在 ant 中运行一个设置任务,该任务复制到用户的主 .ant/lib 文件夹,然后让 ant 失败并显示一条消息以重新启动。它只对用户失败一次,然后每次都有效。如果将 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>

希望这可以帮助

于 2010-12-07T13:33:50.047 回答
0

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

于 2013-04-15T07:46:50.747 回答