有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

ant构建期间代码修改的java最佳实践

我承认,这听起来并不完全是一种最佳实践,但让我解释一下。在构建过程中,我们需要将构建编号和系统版本粘贴到一个类中,该类的唯一目的是包含这些值并使其可访问

我们的第一个想法是使用系统属性,但由于部署环境的易变性(另一种说法是“系统管理员正在做奇怪的、邪恶的、令人毛骨悚然的事情”),我们希望对它们进行硬编码

基本上,我认为在ant中实现这一点有四种可能性:

  1. 对类中的令牌使用<replace>

    这种方法的问题是文件被更改了,所以编译后必须用<replaceregexp>替换回标记。。。太难看了,我不想用正则表达式碰源代码。加上时间依赖性

  2. 复制文件、对副本进行替换、编译副本、删除副本

    必须注意顺序——必须先编译原始类,才能被副本覆盖。时间依赖也很难看

  3. 复制文件,替换原件上的标记,编译,用副本替换染色的原件

    相同的时间依赖性问题,除非嵌入到编译目标中。这也很难看,因为我们所有的构建文件都使用相同的导入编译目标

  4. 在构建脚本中从头开始创建文件/将文件存储在源路径之外

    与前三个相比是一个改进,因为没有时态依赖关系,但是编译器/IDE非常不满意,因为它忽略了类。红色标记令人不安地丑陋

你对其他选择有什么想法

这方面有什么最佳实践吗

我真希望我错过了一个完全理智的方法

谢谢!

编辑 最后,我们使用清单将构建编号和系统版本存储在Implementation-Version属性unsing MyClass.class.getPackage().getImplementationVersion()中。我发现这个解决方案是 this thread的答案之一,andersoj在评论中写道


共 (3) 个答案

  1. # 1 楼答案

    我正在寻找解决同一问题的方法,阅读了以下链接:http://ant.apache.org/manual/Tasks/propertyfile.html我找到了解决方法

    我使用netbeans,所以我只需要将这段代码添加到我的构建中。xml

    <target name="-post-init">
        <property name="header" value="##Generated file - do not modify!"/>
            <propertyfile file="${src.dir}/version.prop" comment="${header}">
                <entry key="product.build.major" type="int"  value="1" />
                <entry key="product.build.minor" type="int"  default="0" operation="+" />
                <entry key="product.build.date"  type="date" value="now" />
        </propertyfile>
    </target>
    

    这将在每次使用clean and build编译项目时增加次要版本。因此,您可以随时保存以运行该项目,而小版本将保持静止

    我只需要在运行时读取文件。我希望这能有所帮助

  2. # 2 楼答案

    我的解决方案是:

    1. 在类中的令牌上使用:

      <replace dir="${source.dir}" includes="**/BuildInfo.*" summary="yes">
          <replacefilter  token="{{BUILD}}" value="${build}" />
          <replacefilter  token="{{BUILDDATE}}" value="${builddate}" />
      </replace>
      

    这种替换只能在构建系统执行的构建步骤中进行,而不能在IDE中的编译/调试会话中进行

    构建系统安装程序无论如何都不应该将更改的源代码提交回源代码存储库,因此这种方法不存在代码更改的问题

    根据我的经验,将生成信息放在属性文件中是没有帮助的,因为管理员在升级时往往会保留属性文件,即替换安装时生成的属性文件。(属性文件中的生成信息对我们来说是信息性的。它提供了在启动期间检查属性文件是否与代码版本同步的机会。)

  3. # 3 楼答案

    我总是建议创建某种目录,并将所有构建的代码放在那里。不要触摸你签出的目录。我通常创建一个target目录,并将所有修改和构建的文件放在那里

    如果没有太多*。java文件(或*.cpp文件),将其复制到target/source' and compile there. You can use the{}`以在复制时修改一个带有内部版本号的文件

    <javac srcdir="${target.dir}/source"
        destdir="${target.dir}/classes"
        [yadda, yadda, yadda]
    </java>
    

    这样,您就不会对签出的源目录进行任何修改,因此不会有人意外地签入这些更改。另外,只需删除target目录,就可以进行清理

    如果有数千个,如果不是数百万个*.java文件,那么您可以将模板复制到target/source,然后在{$basedir}/sourcetarget/source中编译源代码。这样,您仍然不会弄乱签出的代码,并留下有人意外签入修改版本的机会。而且,您仍然可以通过简单地删除target来执行clean