失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Idea编译无法输出profile资源文件问题

Idea编译无法输出profile资源文件问题

时间:2020-09-04 09:06:10

相关推荐

Idea编译无法输出profile资源文件问题

问题描述

背景:一个基于maven的spring mvc项目,提供三种环境配置dev、beta、prod,选择dev环境配置(右键Mark Directory as…将profile/dev设置成Resources Root)

IDE: IntelliJ IDEA

使用mvn compile编译项目,运行程序,报错FileNotFoundException使用Build—>Make Project编译项目,运行程序,成功执行先mvn compile,再make project,运行程序,报错FileNotFoundException先make project,再mvn compile,运行程序,成功执行

FileNotFoundException: class path resource [db.properties] cannot be opened because it does not exist

问题分析

报FileNotFoundException异常是因为profile/dev中的db.properties没有输出到主源码编译输出目录target/classes中,明明已经将profile/dev设置成了Resource Root,为什么编译的时候没有输出呢?

查阅相关资料,《Maven实战》中讲到,maven支持6种方式激活profile:

命令行激活

mvn clean install –Pdev 激活开发环境的配置文件默认激活settings文件显示激活系统属性激活操作系统环境激活文件存在与否激活

另外,Maven的超级pom定义了项目默认的主源码目录src/main/java、测试源码目录src/test/java、主资源目录src/main/resources、测试资源目录src/test/resources,构建输出目录target/,主源码编译输出目录target/classes,测试源码编译输出目录target/test-classes,插件maven-resources-plugin负责处理资源文件,其默认将主资源文件复制到主源码编译输出目录target/classes,将测试资源文件复制到测试源码编译输出目录target/test-classes。

由于一开始没有使用maven的方式激活profile,所以使用maven命令编译项目的时候,没有检测到有效的profile,导致profile文件没有copy到主源码输出目录target/classes中,选择以上方式激活profile/dev后,profile文件正常输出,程序也可正常运行。

为什么make project可以正常输出profile文件呢?为什么先mvn compile,再make project,运行程序报错呢?

这里先了解一下IntelliJ IDEA的编译方式,idea提供3种编译方式:

Compile:对选定的目标(Java 类文件),进行强制性编译,不管目标是否是被修改过。Rebuild:对选定的目标(Project),进行强制性编译,不管目标是否是被修改过。Make:对选定的目标(Project 或 Module)进行编译,但只在有文件修改时编译,没有修改过的文件不会编译,最常用的编译方式。

由于idea使用的编译器是Javac(在settings—Java Compiler里配置),右键Mark Directory as…将profile/dev设置成Resources Root,其实就是将profile/dev设置成主资源目录, Javac会将主资源目录里的文件copy到编译输出目录target/classes(在Project Structure—Modules—Paths中设置),所以使用make project可以正常输出profile文件,当然使用Compile、Rebuild也是可以正常输出profile文件的。

而先mvn compile,再make project,idea可能没有检测到有效的文件修改,实际上没有触发编译行为,运行程序仍然使用的是mvn compile的编译结果。

设置编译器和编译输出目录如下图所示:

为什么先make project,再mvn compile,仍然可以正常输出profile文件?为什么mvn compile没有覆盖make project的编译结果?

在这里需要先了解一下maven的生命周期和命令行的相关知识:

maven有三套生命周期:clean,default,sitte

clean:清理项目,包含pre-clean、clean、post-cleandefault:构建项目,主要包含compile、test、package、install、deploy等,其中compile编译 java文件和资源文件并输出到classpathsite:建立项目站点,包含pre-site、site、post-site、site-deploy

maven不同生命周期的各个阶段相互独立,同一个生命周期的各个阶段是有前后依赖关系的,例如调用clean生命周期的clean阶段不会触发default生命周期的任何阶段,调用default生命周期的compile阶段,也不会触发clean生命周期的任何阶段,但是调用某个生命周期的某个阶段,会执行该生命周期内该阶段前的所有阶段。

maven命令行通过调用maven的生命周期阶段来执行maven任务,典型的maven命令有:

mvn clean:调用clean生命周期的clean阶段,实际执行clean生命周期的pre-clean和clean阶段。

mvn clean install:调用clean生命周期的clean阶段和default生命周期的install阶段,实际执行clean生命周期的pre-clean、clean阶段,以及default生命周期install和install之前的所有阶段。

根据以上可知, 命令行mvn compile调用default生命周期的compile阶段,实际执行default生命周期compile和compile之前的所有阶段,未执行clean不会清空target目录,同样地,maven在编译的也会检测是否有文件修改,如果没有文件修改,就不会触发编译行为。通过maven执行的日志信息“Nothing to compile - all classes are up to date”可以知道,mvn compile没有进行实际的编译操作,运行程序仍然使用的make project的编译结果,而前文已述,make project可以正常输出profile文件,所以程序可以成功运行。

至此结束。

参考资料

1.《Maven实战》

2. /project/intellij-idea-tutorial/make-introduce.html

3. /qq_35246620/article/details/64958736?locationNum=4&fps=1

如果觉得《Idea编译无法输出profile资源文件问题》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。