我们正在使用Maven在构建服务器上编译我们的项目。我们从SVN更新源代码,然后从项目文件夹运行“mvn install”,构建一个jar然后部署到我们的生产服务器。
为了节省编译时间,我们在重新编译之前保留编译的类(在maven创建的target / classes文件夹中)。这样,Maven只需要重新编译新的或更改java文件。
但移动/删除文件存在问题:SVN更新会从源路径中删除.java文件,但Maven不会从目标/类中删除已编译的.class文件。从main / resourses文件夹中删除的文件也是如此。因此,删除/移动的类和已删除的资源仍然会在我们部署到生产服务器的jar文件中结束,这会导致问题。
我知道我们可以“清理”以删除任何已编译的文件,但这样我们需要在每次构建时重新编译整个项目,这需要花费很多时间。
有没有人知道在Maven编译之前或期间删除过时的.class文件和资源的方法?
答案 0 :(得分:4)
因此,删除/移动的类和已删除的资源仍然存在于我们部署到生产服务器的jar文件中,这会导致问题。
在构建要部署到生产服务器的工件时,确实执行完全清理构建。它不仅是可重现构建的最佳实践(例如Hudson Best Practices中提到的),但更重要的是,它是防止多模块构建运行时错误的唯一方法(除非您使用maven-incremental-build插件)。想象一下以下情况:
module-parent |--- module-api `--- module-impl
API模块定义由IMPL模块实现的接口(因此取决于API模块)。如果您通过修改方法签名更改API模块并且不更改IMPL模块中的任何内容,则从父模块执行构建将成功,IMPL将不会被重新编译并且整个事情将在运行时中断(有关此行为,请参阅this discussion)。你目前正在做的事情真的不安全!
有没有人知道在Maven编译之前或期间删除过时的.class文件和资源的方法?
我不知道有什么事情这样做。正如我所说,你目前的做法并不安全。您应该更改它,至少在持续集成服务器级别,尤其是“生产版本”。
答案 1 :(得分:1)
我认为不可能。看看javac documentation
javac 确定类文件是否过期。如果类文件已过期,javac将重新编译源文件并使用更新的类文件。否则,javac只使用类文件。 javac认为类文件只有在比源文件旧时才会过时。
Maven编译器插件(或ant任务)不会比javac做更多。
我强烈建议使用干净的目标。不使用它可能会导致很多问题,特别是如果你立即将工件部署到生产环境中(比如。依赖于文件时间戳的javac很脆弱,某些资源可能会被过滤等等。)
如果您在构建性能方面遇到问题,请尝试查找其他解决方案 - 例如将您的模块划分为更小的子模块。
答案 2 :(得分:0)
Alexander Malfait,
如果你的问题只是在集成环境中,我会和Pascal Thivent一起开心,cetnar,
但是,您的问题在其他情况下也是一个问题。 实际上,在发展阶段,我发现系统地清理以避免这种问题非常糟糕。 我认为Maven应该在源代码和编译器之间做一个差异,以便在你想要juste编译时不要作为盲人。 好的Javac没有这样做,但Maven不是javac。这是javac的一层。所以,它可能是它的角色。