通过EXEC与其他JDK运行ANT(APT / WSGEN解决方法)

时间:2018-08-17 22:31:19

标签: ant java-8 java-7 apt wsgen

我希望这能找到一个ANT构建大师,他具有在同时运行不同JDK版本的ANT方面的一些经验!

我继承了一组相当老的库和ANT构建文件,这些文件当前可在Java 6/7下运行。在尝试使该系统现代化以利用Java 8或将来的任何JDK升级时,我一直在研究一种重构这些构建文件以与Java 8配合使用的方法。

当前的构建系统具有以下特征:

  • 蚂蚁1.7.0和Java 1.7.0_55
  • 通过ANT APT任务使用不赞成使用的APT工具
  • 通过ANT WSGEN任务(例如classname =“ com.sun.tools.ws.ant.WsGen”)使用wsgen(与Jaxws相关的库)
  • 有效地,构建文件将代码生成和编译混合在一起以创建所需的输出。

APT工具已在Java 1.7中弃用,您需要转向在1.8及更高版本中使用JAVAC!

在尝试用JAVAC替换APT的用法时,我发现不仅删除了该工具,而且还删除了与APT工具关联的许多软件包/类/接口。我已经在多个问答中看到了此主题的讨论,但是大多数提议的解决方案都不是入门级的。

我确实发现的一个建议是将代码生成(APT的使用)与编译(JAVAC)分开,以驻留在不同的ANT构建文件中。将构建文件分为“主”构建文件和“ codegen”构建文件后,这似乎可以正常工作。

示例:

    <property name="apt.output.file" value="codegen.apt.${java.version}.log" /> <!-- A different log file will exist when I run the "main" ant build file using Java 7 vs 8 for comparison purposes. -->
    <exec executable="${exec.ant.cmd}" osfamily="unix" failonerror="true" output="${apt.output.file}" >
        <arg line="${ant.apt.cmd.line.options}" />
        <env key="JAVA_HOME" value="${exec.java.home}"/> <!-- Java 1.7 -->
        <env key="ANT_HOME" value="${ant.home.path}"/> <!-- Ant 1.7.0 -->
        <env key="PATH" value="${exec.java.home}/bin" /> <!-- Reset PATH to be certain -->
        <!-- The various properties are defined in the build file, and would be fairly unsurprising. -->
    </exec>

现在“ codegen”片段是独立的,这使我能够:

  • 使用Java 8运行“主” ANT构建文件。
  • 对于“ codegen”片段,请按照上述方式使用EXEC来指定ANT / JAVA版本以进行* .java代码生成。

对于在类似情况下的您来说,好消息是,这似乎对APT很好。我将JAVA_HOME和PATH更改为指向Java 8,它似乎可以正常工作(假设APT仅限于* .java源代码生成,无需编译)。

现在是问题所在,我希望有人能对此有所了解。我发现APT工具还用于创建ANT构建文件(wsgen-build.xml)。该文件定义了WSGEN任务,然后多次使用它:

<project name="some-wsgen-fragment" default="wsgenall">
<target name="wsgenall">
    <taskdef name="wsgen" classname="com.sun.tools.ws.ant.WsGen" >
        <classpath>
            <pathelement path="${jaxws.home}/lib/jaxws-tools.jar" />
        </classpath>
    </taskdef>
    <echo message="wsgen for SomeWebServiceImpl" />
    <wsgen destdir="${classes.server.gen.dir}" sourcedestdir="${something.gen.dir}" sei="com.something.or.other.SomeWebServiceImpl">
        <classpath>
            <pathelement path="${classes.server.gen.dir}" />
            <path refid="classpath.all" />
        </classpath>
    </wsgen>
    ... Repeated usages of wsgen exactly as above, with different classes

类似于APT任务,“主”构建文件将调用EXEC来运行带有适当参数的“旧” ANT,以在与其工作的相同环境下调用此生成的构建文件。

在Java 1.7和ANT 1.7.0下,这可以正常工作。

将Java更改为1.8时,将JAVA_HOME的JDK更改为1.8,将“ java.target”更改为1.8,则出现以下神秘错误:

  [echo] wsgen for SomeWebServiceImpl
  Finding class com.something.or.other.SomeWebServiceImpl
  [antcall] Exiting codegen-buildfile.xml.

BUILD FAILED
codegen-buildfile.xml:58: The following error occurred while executing this line:
wsgen-build.xml:9: Requires JDK 5.0 or later. Please download it from http://java.sun.com/j2se/1.5/
    at org.apache.tools.ant.ProjectHelper.addLocationToBuildException(ProjectHelper.java:541)
    at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:418)
    at org.apache.tools.ant.taskdefs.CallTarget.execute(CallTarget.java:105)

对我来说,这个问题“感觉”如下:

为什么运行Java 8的ANT会干扰运行Java 7的ANT?如何补救?

一些问答使我想到了这个问题:

您是否尝试过使用ANT -v -d来解决这个问题? 是的,我正在基于用于“主”构建文件的$ {java.version}生成日志文件。我为Java 8生成一个文件,为Java 7生成一个文件,然后对这两个文件进行比较。直到我遇到上面提到的错误,两者(Java 7与Java 8)之间的环境/属性/设置没有区别。加载的订单类有微小的变化,就是这样。

当您在Java 7和Java 8之间进行更改时,是否确定所做的更改不会影响您的EXEC任务? 上面引用的日志文件的diff验证了这一点,但是当我调用EXEC时,上面的第一个示例中的属性有效地进行了硬编码,并使用ENV标记来确保环境变量也相同,而与所使用的Java版本无关在“主”构建文件中。

是否确实有一些环境变量差异导致此问题? 我正在记录许多试图诊断问题的变量。到目前为止,“ codegen” ANT构建文件具有相同的功能,无论“ main” ANT是在Java 7还是8中运行:ANT_HOME,JAVA_HOME,PATH,ant.version,java.version,java.vm.version, java.class.path,java.ext.dirs。详细的ANT日志也证明了这一点,它们之间没有属性/环境/类路径问题。

我无法从您的EXEC示例中看出来,但是您使用的是完整路径吗?也许PATH变量有问题吗? 尽管未显示,但我正在指定ANT和JAVA的完整路径,因为我需要精确地指定ANT / JDK以确保我正在运行所需的特定版本。

如何使用出现问题的wsgen任务(wsgen-build.xml)调用生成的构建文件? 根据上面的示例,“主”构建文件将在“ codegen”构建文件上调用EXEC。唯一的区别是构建目标不同,一个目标用于APT,另一个目标用于WSGEN。在“ codegen”构建文件中的所述WSGEN目标中,当前已导入wsgen-build.xml并通过ANTCALL调用该目标。我也尝试过仅使用ANT任务,两者的结果相同。

可以从命令外壳运行EXEC命令吗? 是的,如果我在命令行上运行该步骤,则该步骤是否起作用取决于Java 7或8是否设置为JAVA_HOME,并且该方法首先出现在PATH中。例如,如果我将JAVA_HOME更新为Java 8,则会收到以下错误:java.lang.NoClassDefFoundError:com / sun / mirror / apt / AnnotationProcessorFactory。这是正确的,因为该类在Java 8中不再存在(但在7中确实存在)。

您是否尝试过使用脚本或批处理文件,而不是对ANT可执行文件使用EXEC? 是的,导致同样的错误。我用一个简单的.bat文件进行了尝试,该文件设置了必需的环境变量并从shell调用了命令。

您使用的是什么操作系统,是否尝试过使用其他计算机/操作系统来查看它是否特定于环境? 我有一个Win7和RHEL 7环境,这两个问题均会发生,并且我正在使用osfamily属性对每个平台的EXEC命令进行条件化。

Ant 1.7.0相当老,您是否尝试过更新的Ant? 使用Ant 1.9.4也会发生相同的问题。 1.9.4 Ant仅针对“主”构建文件运行,“ codegen”构建文件将使用1.7.0,因为我通过EXEC任务明确设置了该设置。我确实为“ codegen”蚂蚁构建文件尝试了1.9.4,但在错误方面没有任何区别。

如果您能通读全部内容,那么先生或女士,请您向我致敬!感谢您提供的任何见解/建议!

0 个答案:

没有答案