1.遇到的主要问题
- 构建一个Maven项目时,无法将resources文件夹中的资源文件打包进构建后的目录中,具体情况如下图左边两子图。
可见,虽然已将源码中的resources文件夹Mark Directory As Resources Root,但是构建出的target文件夹中并没有resources文件夹下的内容,导致后续在Java文件中读取资源文件找不到(开始一直认为是读取的路径配置不正确,因为读取资源文件的API使用的不是JDK中的API而是第三方库,所以一直纠结是不是第三方库API读取资源文件时的默认位置没指定正确,去查阅API文档花费了一定时间,后来确认第三方库读取位置没问题后才发现是资源文件根本没有被打包进编译后的项目中,也就是说其实是项目构建阶段出了问题,而不是代码运行阶段出的问题)。
2.问题分析与解决方案
既然找到了问题所在,那么就要解决这个构建阶段的问题,需要想办法让IDEA把resources文件夹下的内容打包进去,在项目配置中翻阅了可配置的属性,发现除了将resources文件夹Mark Directory As Resources Root以外竟然别无他法,然而这波操作是无效的,还是打包不进去,这里如果有读者知道其他的额外配置方法还请评论告知,非常感谢!
后来一直调试了许久依旧不能解决,想着把项目从实验室拷贝回去再继续研究,到另一台电脑上用IDEA导入项目后直接构建,发现问题居然消失了!!资源文件被成功打包进去了,于是思考这是为什么,在将两台电脑上的项目配置与目录结构进行仔细对比之后终于发现了问题所在,关键就在于上图所示的蓝色方框与红色方框中的区别,红色方框内是Maven项目的符号,在新的电脑上导入项目时IDEA进行了Maven项目的检查,将其识别为了Maven项目,所以构建成功,而在原来的电脑上由于之前的配置问题导致IDEA没能识别出项目为Maven项目,解决方法是在pom.xml上右键进行+Add as Maven Project操作,如上图最右子图,之后即可使IDEA正确识别Maven项目类型构建成功,问题解决。
3.问题所引发的思考
(1)为什么只有在将项目标记为Maven项目时IDEA才能够打包resources中的资源文件,而在之前即使把resources文件夹Mark Directory As Resources Root也不行?
我想是因为src/main/(java,resources,webapp)这种目录结构是Maven所规定的默认目录结构,所以在IDEA不知道项目是Maven项目时它就不知道resources文件夹里面是资源文件,也就是说Mark Directory As Resources Root这波操作只对于Maven项目或其他规定有资源目录的项目类型是有效果的,对于普通的Java项目是没用的,要对普通Java项目打包资源文件还需要继续研究怎么做,若有读者知道还请告知。
(2)IDEA的Build Project操作到底为我们做了些什么事情?这个操作它又依赖于什么?
一开始以为,在将项目标记为Maven项目后,IDEA会直接调用mvn compile/package指令去编译与打包项目,后来发现不是的,IDEA的Build与Maven的构建是并列的两种构建体系,IDEA的Build调用系统中的javac对Java文件进行编译,并根据用户配置去打包资源文件,IDEA的Build依赖于其本身的.iml配置文件,里面存储了用户设置的配置信息,IDEA的Build不会去调用Maven的构建指令。Maven的构建则完全依赖于pom.xml文件中的内容,Maven的构建也调用系统中的javac,可通过IDEA的插件功能触发。
这里想着重讲的一点是二者之间的联系,也就是解决这个问题的过程中所发现的,IDEA的Build虽然与Maven构建是互相独立的,但是IDEA的构建会被项目的类型所影响,它会参考项目的类型来确定项目中哪些文件夹是资源文件,因此将项目标记为Maven项目会影响到IDEA的Build。
4.总结
(1)代码运行时出现资源找不到这种类型的问题时,应首先确定是运行阶段的问题还是构建阶段的问题,再进一步排查;
(2)特定目录结构(如src/main/java)是特定类型(如Maven)的项目所独有的,因此要识别这种结构也就必须参考相应的类型信息或额外配置,在未指定类型时IDE就不能做到默认识别了;
(3)IDEA的Build与Maven构建是互相独立的;
(3)IDEA的构建会被项目的类型所影响,它会参考项目的类型来确定项目中哪些文件夹是资源文件,因此将项目标记为Maven项目会影响到IDEA的Build。