问题描述

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

IDE: IntelliJ IDEA

  1. 使用mvn compile编译项目,运行程序,报错FileNotFoundException
  2. 使用Build—>Make Project编译项目,运行程序,成功执行
  3. 先mvn compile,再make project,运行程序,报错FileNotFoundException
  4. 先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:

  1. 命令行激活
    mvn clean install –Pdev 激活开发环境的配置文件
  2. 默认激活
  3. settings文件显示激活
  4. 系统属性激活
  5. 操作系统环境激活
  6. 文件存在与否激活

另外,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种编译方式:

  1. Compile:对选定的目标(Java 类文件),进行强制性编译,不管目标是否是被修改过。
  2. Rebuild:对选定的目标(Project),进行强制性编译,不管目标是否是被修改过。
  3. 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

  1. clean:清理项目,包含pre-clean、clean、post-clean
  2. default:构建项目,主要包含compile、test、package、install、deploy等,其中compile编译 java文件和资源文件并输出到classpath
  3. site:建立项目站点,包含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. http://wiki.jikexueyuan.com/project/intellij-idea-tutorial/make-introduce.html
3. http://blog.csdn.net/qq_35246620/article/details/64958736?locationNum=4&fps=1

Idea编译无法输出profile资源文件问题相关推荐

  1. 反编译“微软纸牌集合”资源文件

    @[TOC]反编译"微软纸牌集合"资源文件 成功反编译"微软纸牌集合"资源文件 一天时间,终于成功反编译了"微软纸牌集合(Microsoft Soli ...

  2. 可视化反编译APK工具,查看部分JAVA代码与全部资源文件。

    ###前言 APK是安卓安装包,里面主要就是两大部分 资源文件,主要是图片与布局. dex文件,也就是各种代码转换成的Android可执行文件. 如果直接ZIP打开混淆打包过的APK的话,会出现dex ...

  3. Razor Page Library:开发独立通用RPL(内嵌wwwroot资源文件夹)

    Demo路径:https://github.com/yanshengjie/RPL.Demo 1. Introduction Razor Page Library 是ASP.NET Core 2.1引 ...

  4. 【buildroot适配】local.mk添加自带编译linux和uboot资源

    目录 1.make menuconfig 2.buildroot目录下创建local.mk文件 1.make menuconfig 添加local选择local.mk文件 前提:已经打开linux 和 ...

  5. 【Android 安装包优化】资源混淆 ( AAPT2 资源编译工具 | resources.arsc 资源映射表 工作机制 )

    文章目录 一.AAPT2 资源编译工具 二.resources.arsc 资源映射表 工作机制 三.参考资料 一.AAPT2 资源编译工具 资源的编译 , 生成 R.java 文件 , 都是通过 AA ...

  6. Java是如何加载资源文件的?(源码解毒)

    上文提到应老板要求开发一个测试工具能方便的加载存于文件中的测试参数,当时考虑既然是测试,把测试参数文件和测试类放在一起岂不是很方便,但是老板说:我的需求是你把测试参数文件放到统一文件夹下比如resou ...

  7. Android资源文件在配置文件中的使用

    Android资源文件大致可以分为两种: 第一种是res目录下存放的可编译的资源文件: 这种资源文件系统会在R.Java里面自动生成该资源文件的ID,所以访问这种资源文件比较简单,通过R.XXX.ID ...

  8. gin embed打包静态资源文件

    问题 在gin项目中如果单纯的只是实现api接口,那打包出来的是一个可执行文件.但如果项目中如果包含一些页面,则必定会引入一些css,jss,html文件.这样会使打包出来后会挂着对应的静态资源文件夹 ...

  9. java assetmanager_Android学习--Assets资源文件读取及AssetManager介绍

    APK安装过程 复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录,An ...

最新文章

  1. deepfakes怎么用_如何使用 Deepfakes 换脸
  2. sudo apt get linux,常用sudo apt-get命令
  3. 重走JAVA之路(一):复盘ButterKnife-编译时注解
  4. echarts词云图形状_怎么用Python画出好看的词云图?
  5. 手机扫一扫,现实物体隔空「复制粘贴」进电脑!北大校友的AI新研究,现在变成AR酷炫应用...
  6. 给ztree节点赋值
  7. Http与WWW服务精解
  8. testflight无法联网怎么办_互联网人最怕的,就是这一刻
  9. 给定一个数组 a[n], 输出b[n], 其中 b[i] = a[0]*a[1]...*a[i-1]*a[i+1]*....a[n]; 其中不能用除法 复杂度要求O(n)...
  10. 私有云计算保密技术谁家靠谱?云宏CNware®虚拟化平台安全体系设计
  11. 利用xshell通过公钥私钥连接linux服务器
  12. win7驱动程序未经签名可以使用吗_win7系统驱动强制数字签名的问题
  13. Win8之常用快捷键(1)
  14. Linux大批量文件rm命令无效
  15. 盘点澳洲留学性价比较高城市
  16. PaddlePaddle证件照换底换大小工具
  17. python中matplotlib调整图例位置
  18. 控制反转思想的理解实例
  19. 网证你申请了吗?怎么使用?
  20. 关于滤镜的使用,使图片默认为全灰色

热门文章

  1. 2013 08 12 Andrew:C语言的一点心得
  2. 计算机取消健,笔记本电脑的去除健失灵了,可以设置其他按键代替吗?
  3. VMware虚拟机克隆ubuntu20.04系统IP相同
  4. 【数据结构】实验五:树和二叉树
  5. 详细解析vue中的修饰符
  6. 用css做一个云朵的动画
  7. 服务器硬盘是什么接口类型 服务器硬盘和普通硬盘区别
  8. 一次完整的笔记本电脑拆机安装ddr4内存条记录(超详细)——以联想小新锐7000为例
  9. java如何输入字符数组
  10. 通过GLUT库学习OpenGL