代码之家  ›  专栏  ›  技术社区  ›  Alexander Malfait

Maven编译:从目标中删除过时的类文件

  •  4
  • Alexander Malfait  · 技术社区  · 16 年前

    我们正在使用Maven在构建服务器上编译我们的项目。我们从SVN更新源代码,然后从项目文件夹运行“mvn install”,构建一个jar,然后部署到生产服务器。

    为了节省编译时间,我们在重新编译之前保留已编译的类(在Maven创建的目标/类文件夹中)。这样,Maven只需要重新编译新的或更改的Java文件。

    但是移动/删除文件有问题:Svn更新从源路径移除.java文件,但是Maven不会从目标/类中删除编译的.class文件。同样适用于从主/资源文件夹中删除的文件。因此,被删除/移动的类和被删除的资源仍然会出现在我们部署到生产服务器上的JAR文件中,这会导致问题。

    我知道我们可以“mvn-clean”除去任何编译的文件,但是这样我们就需要在每次构建时重新编译整个项目,这需要花费大量的时间。

    有人知道在Maven编译之前或编译期间删除过时的.class文件和资源的方法吗?

    3 回复  |  直到 16 年前
        1
  •  4
  •   Pascal Thivent    16 年前

    因此,被删除/移动的类和被删除的资源仍然会出现在我们部署到生产服务器上的JAR文件中,这会导致问题。

    真应该 表演一个 完全干净的构建 当构建要部署到生产服务器的工件时。这不仅是可复制构建的最佳实践(如中所述 Hudson Best Practices 例如),但更重要的是,它是防止多模块构建出现运行时错误的唯一方法(除非使用 maven-incremental-build 插件)。想象一下以下情况:

    module-parent
    |--- module-api
    `--- module-impl
    

    API模块定义由IMPL模块实现的接口(因此依赖于API模块)。如果通过修改方法签名来更改API模块,而不更改IMPL模块中的任何内容,则从父模块执行构建 会成功 不会重新编译IMPL和整个 将在运行时中断 (见 this discussion 关于这种行为)。你现在所做的真的不安全!

    有人知道在Maven编译之前或编译期间删除过时的.class文件和资源的方法吗?

    我什么都不知道。正如我所说,你现在的做法是不安全的。您应该至少在持续集成服务器级别更改它,尤其是对于“生产构建”。

        2
  •  1
  •   cetnar    16 年前

    我认为这不可能。看Javac documentation

    雅瓦克 确定类文件是否过期。如果类文件已过期,javac将重新编译源文件并使用更新的类文件。否则,javac只使用类文件。 只有当类文件比源文件旧时,javac才会认为它已过期。

    Maven编译器插件(或Ant任务)的功能不比Javac多。

    我强烈建议使用干净的靶子。不使用它可能会导致很多问题,特别是如果您立即将工件部署到生产环境中(比如。javac依赖于文件时间戳是脆弱的,一些资源可能被过滤等。)

    如果您对构建性能有问题,请尝试寻找其他解决方案-例如,将模块划分为较小的子模块。

        3
  •  0
  •   davidxxx    16 年前

    亚历山大·马尔法特,

    如果你的问题仅仅是在一个集成环境中,我会和PascalThivent,Cetnar一起思考,

    然而,你的问题在其他情况下都是一样的。 实际上,在开发阶段,我发现为了避免这种问题而进行系统的清理是非常糟糕的。 我认为Maven应该在源代码和编译代码之间做一个区分,以便在您希望juste编译时不充当盲人。 好吧,javac不做,但maven不是javac。这是一个javac的上层。所以,它可能是它的角色。

    推荐文章