简体   繁体   English

在 Java 中以编程方式执行 ANT 脚本

[英]Programmatically executing ANT script in Java

I've built a swing gui in eclipse that is supposed to run a bunch of code previously developed, part of which involves running ant to build the code.我在 eclipse 中构建了一个 Swing gui,它应该运行一堆以前开发的代码,其中一部分涉及运行 ant 来构建代码。 When I run the any script outside of the GUI (in the original project) the ant executes correctly and builds the project.当我在 GUI 之外(在原始项目中)运行任何脚本时,蚂蚁会正确执行并构建项目。 However when I try and run ant programmatically it throws errors that look like the project doesn't have the necessary .jars.但是,当我尝试以编程方式运行 ant 时,它会抛出看起来像项目没有必要的 .jars 的错误。 The code, top of the build.xml, and errors are listed below.下面列出了 build.xml 顶部的代码和错误。

Code Block代码块

File buildFile = new File("lib\\ePlay\\build.xml");
    Project p = new Project();
    p.setUserProperty("ant.file", buildFile.getAbsolutePath());
    DefaultLogger consoleLogger = new DefaultLogger();
    consoleLogger.setErrorPrintStream(System.err);
    consoleLogger.setOutputPrintStream(System.out);
    consoleLogger.setMessageOutputLevel(Project.MSG_INFO);
    p.addBuildListener(consoleLogger);

    try {
        p.fireBuildStarted();
        p.init();
        ProjectHelper helper = ProjectHelper.getProjectHelper();
        p.addReference("ant.projectHelper", helper);
        helper.parse(p, buildFile);
        p.executeTarget(p.getDefaultTarget());
        p.fireBuildFinished(null);
    } catch (BuildException e) {
        p.fireBuildFinished(e);
    }

Build.xml构建文件

<?xml version="1.0" encoding="UTF-8"?>
<project name="EPlay" xmlns:ivy="antlib:org.apache.ivy.ant" default="resolve">

<dirname file="${ant.file}" property="ant.dir" />
<property name="scm.user" value="scmrel"/>
<property name="scm.user.key" value="/.ssh/scmrel/id_rsa"/>
<property name="ivy.jar" value="ivy-2.0.0.jar" />
<property name="ivy.settings.dir" value="${ant.dir}/ivysettings" />
<property name="VERSION" value="LATEST" />
<property name="tasks.dir" value="${ant.dir}/.tasks" />
<property name="deploy.dir" value="${ant.dir}/deploy" />
...
<!-- retrieve the dependencies using Ivy -->
<target name="resolve" depends="_loadantcontrib,_getivy" description=" retrieve the dependencies with Ivy">
  <ivy:settings file="${ivy.settings.dir}/ivysettings.xml" />
  <ivy:resolve file="${ant.dir}/ivy.xml" transitive="false" />
  <ivy:retrieve pattern="${deploy.dir}/[conf]/[artifact].[ext]"/>
</target>

And the error和错误

resolve:
BUILD FAILED
H:\eclipse\CLDeploySwing\lib\ePlay\build.xml:66: Problem: failed to create task or type antlib:org.apache.ivy.ant:settings
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.
No types or tasks have been defined in this namespace yet

This appears to be an antlib declaration. 
Action: Check that the implementing library exists in one of:
        -ANT_HOME\lib
        -the IDE Ant configuration dialogs


Total time: 0 seconds

I've looked through my ant installation and it appears everything is there.我已经查看了我的 ant 安装,看起来一切都在那里。 Like I said, the original project builds successfully if build.xml is run outside of this application.就像我说的,如果 build.xml 在这个应用程序之外运行,原始项目就会成功构建。

I would suggest that this is causde because your java program does not have the same classpath, where it is running, as does the normal ant build - and thus the ANT_HOME isn't the right one.我建议这是因果关系,因为您的 Java 程序没有与正常 ant 构建相同的类路径,它在何处运行,因此 ANT_HOME 不是正确的。

You can make sure that this is correct by passing the right enviornmental variables into the JVM, or simply a call to System.getProperty("ANT_HOME"), to see where your ANT_HOME actually is residing.您可以通过将正确的环境变量传递到 JVM 中来确保这是正确的,或者只需调用 System.getProperty("ANT_HOME") 来查看您的 ANT_HOME 实际所在的位置。

rather than load the ivy library using the new method of using the namespace in the project declaration go old school on it.与其使用在项目声明中使用命名空间的新方法加载 ivy 库,不如去老派。

<path id="ivy.lib.path">
    <fileset dir="path/to/dir/with/ivy/jar" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
         uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>

I am doing something in Gradle that requires this我正在 Gradle 中做一些需要这个的事情

ant.taskdef(name: 'ivy-retrieve', classname: 'org.apache.ivy.ant.IvyRetrieve', classpath: '...path to ivy jar.../ivy-2.2.0.jar')

which in ant would be something like这在蚂蚁中会是这样的

<taskdef name="ivy-retrieve" classname="org.apache.ivy.ant.IvyRetrieve"/>

I know it's more klunky and simply not as nice as including the namespace declaration but it does remove some of the confusion regarding which libraries on which classpath are being loaded.我知道它更笨拙,而且不如包含命名空间声明那么好,但它确实消除了关于正在加载哪些类路径上的哪些库的一些混淆。

I think ${basedir} for your project is not properly calculated.我认为您项目的${basedir}计算不正确。

Add this line to your build.xml将此行添加到您的 build.xml

<echo message="basedir='${basedir}'/>

Looking at this line看着这条线

File buildFile = new File("lib\\ePlay\\build.xml");

It may be that it's 2 levels up ( I know the documentation says that it should be a parent directory of build.xml, but you are not running from the command line ).它可能是 2 个级别(我知道文档说它应该是 build.xml 的父目录,但您不是从命令行运行)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM