【问题标题】:mkdir in ant fails. How can i handle this errorant 中的 mkdir 失败。我该如何处理这个错误
【发布时间】:2012-02-15 09:14:40
【问题描述】:

我拥有的 ANT 构建脚本执行以下操作:

  1. 在 Windows 服务器上执行构建并压缩二进制文件
  2. 使用net use 将具有不同凭据的网络驱动器映射到本地驱动器(例如 P:)
  3. 我正在使用<mkdir> 在已安装的驱动器上创建一个目录 (P:)
  4. 将二进制文件复制到该驱动器

下面是我的mkdir代码

<echo>Creating ${buildRequesterUserId} folder at mirroring site starts</echo>
<mkdir dir="P:\build_output\${buildRequesterUserId}"/>
<echo>Creating ${buildRequesterUserId} folder at mirroring site ends</echo>

有时会创建文件夹,有时会失败并出现以下错误

creation was not successful for an unknown reason 并导致构建失败

此错误随机发生。 Mkdir 工作了一段时间。我不确定它为什么会失败,也不确定是不是因为网络滞后

我尝试创建的目录可能已经存在也可能不存在。我读到如果目录已经存在,mkdir 不会做任何事情

我查了一下,mkdir 没有failonerror。我不希望构建因此而失败。

我已经处理了copy 部分的错误,但不知道如何处理这个mkdir

我怎样才能做到这一点?任何帮助将不胜感激

问候

卡提克

【问题讨论】:

  • 如果您不介意,请对我的回答发表评论并描述它的哪一部分为您解决了问题(如果真的解决了:)
  • 你有写权限吗?

标签: java ant mkdirs


【解决方案1】:

Apache Ant Mkdir 任务正在调用File.mkdirs() 方法,即vulnerable to race conditions

File.mkdirs() 不是原子操作 - 我猜它是作为mkdir 调用序列实现的。

在远程文件系统的情况下,您的主机很有可能在File.mkdirs() 操作过程中发现文件系统更改并且失败。

Ant 似乎试图修复它,因为 Mkdir 代码从 1.8.0 中的此更改

boolean result = mkdirs(dir);
if (!result) {
  String msg = "Directory " + dir.getAbsolutePath()
         + " creation was not successful for an unknown reason";
  throw new BuildException(msg, getLocation());
}

到这个1.8.2

boolean result = mkdirs(dir);
if (!result) {
  if (dir.exists()) {
    log("A different process or task has already created "
         + "dir " + dir.getAbsolutePath(),
         Project.MSG_VERBOSE);
    return;
  }
  String msg = "Directory " + dir.getAbsolutePath()
         + " creation was not successful for an unknown reason";
  throw new BuildException(msg, getLocation());
}

所以也许升级到最新的 Ant 会有所帮助?

如果不是 - 可以使用您自己的 execute() 方法实现创建一些蛮力 Mkdir 任务扩展。

如果没有 - Ant Contrib 的 Trycatch task 将起作用。

【讨论】:

  • 升级 ANT。我用 1.7x 测试过,还是失败了。我没有尝试过 TryCatch,因为我没有 AntContrib。但我认为这也将帮助我捕捉错误
  • 他说变化是在 1.8.0 和 1.8.2 之间,所以升级到 1.7.x 不会有帮助...
【解决方案2】:

对我来说,我在 1.9 版本的 ant 中遇到了类似的问题。

我正在删除一个目录并立即重新创建它:

<delete dir="${jar.dir}"/>
<mkdir dir="${jar.dir}"/>

即使目录是本地的(不是网络驱动器),在两个操作之间添加 1 秒的睡眠时间也解决了我的问题:

<delete dir="${jar.dir}"/>
<sleep seconds="2"/>
<mkdir dir="${jar.dir}"/>

【讨论】:

    【解决方案3】:

    您可以使用 COPY 任务来创建目录(包括子目录)。

    【讨论】:

      【解决方案4】:

      对我来说,在 linux 中解决问题就像以 sudo 用户身份运行一样简单

      “须藤蚂蚁”

      【讨论】:

        【解决方案5】:

        我是这样解决的:

        1. 打开您的 build.properties 文件(实际上是打开所有属性文件) 引用自 build.xml)
        2. 检查文件任何行上的任何尾随空格和制表符。
        3. 在文件末尾添加一个额外的空行。

        【讨论】:

        • 我可以知道这背后的基本原理是什么吗?
        猜你喜欢
        • 1970-01-01
        • 2020-04-25
        • 2016-05-23
        • 1970-01-01
        • 2020-02-29
        • 1970-01-01
        • 2013-03-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多