本文章案例是基于 IDEA2019 从Gitlab上拉取多模块maven项目,配置本地Tomcat服务器运行Spring Boot项目(不使用其自带Tomcat服务器)时,提示没有Artifact导致无法部署项目的情况。
现象
在IDEA中,如图,点击上面的的“Add Configuration”,弹出“Run/Debug Configuration”弹窗,再点击左边的+号,选择本地(local)“Tomcat Server”,再点击“Deployment”,再点击右边的+号,此时只弹出“External Source”,却并没有“Artifact”,说明本项目没有配置Artifact,需要先配置Artifact。
解决
打开Project Structure弹窗,方法:File → Project Structure。
下图是IDEA中的Project Structure弹窗的内容,结合图片进行分析。
要配置Artifacts,先要了解与之相关的Facets。
配置Facets
Facets表述了在Module中使用的各种各样的框架、技术和语言。这些Facets让Intellij IDEA知道怎么对待module内容,并保证与相应的框架和语言保持一致。使用Facets能让我们下载并配置framework所必须的组件,会自动生成各种各样的描述符,并存储在适当的位置,等等。大多数Facets可以无冲突得添加到Module中。Java开发中常用的Facets有:Web Facet(Web、EJB、Java EE Application的Facets大致相似)、Spring Facet等。
添加一个Web Facet:Facets → +号 → Web → 选择一个Module → 确定。
此时,Project Structure弹窗会自动跳到Modules中响相应的module,并显示刚刚添加的Web Facet(为方便讲解,此处上下两张图片使用的不是同一个模块,但道理和操作方式都是一样的)。
Name:输入该Web Facet的名称,此处使用默认的名称Web。
Deployment Descriptions:管理应用的部署描述符。
Type:只读字段,展示部署描述符类型(此处为Web Module Deployment Descriptor)。各自依赖的facet类型有:Web Module Deployment Descriptor、EJB Module Deployment Descriptor、 Application Module Deployment Descriptor。
Path:只读字段,展示部署描述符的位置(此处为web.xml
)。各自部署描述符有:web.xml,
ejb.xml
,application.xml。
path的值默值为当前模块的 根目录\web\WEB-INF\web.xml 。由于本项目所有Spring Boot模块的web资源都在src\main\webapp目录,所以此处配置为模块 根目录\src\main\webapp\WEB-INF\web.xml 。
Web Resource Directories:将第三方或未分类资源路径映射到部署根目录。
Web Resource Directory :只读字段,展示所需的Web Resource位置的本地目录。Web Resource目录包含Web开发所需的文件:HTML、XML、js等。Web Resource目录下的内容会被拷贝到由Relative Path所指定的Web模块部署目录。
Pah Relative to Deployment Root:只读字段,展示Web Resource相对于Web部署的根目录的相对路径。
此处配置:
webapp对应/:即将webapp目录下的内容拷贝到Web部署的根目录下。
resource对应WEB-INF:即将resource目录下的内容拷贝到Web部署的 根目录\WEB-INF。
Source Roots:标为此类的文件夹,IDEA会将此文件夹及其子文件夹作为构建过程的一部分进行编译(编译产物在生成的classes目录下)。
注意,Deployment Descriptions、Web Resource Directories不进行配置,即没有配置项也是可以的。如下图:
本项目所有的Spring Facet都被IDEA自动检测出来(Spring Boot启动类)并配置好,此处不对Spring Facet配置进行讲解。
配置Artifacts
Artifact是一个项目资源的组合体。例如,一个已编译的java类的集合,一个已打包的java应用。
Artifact可以是一个archive文件,也可以是一个包含以下结构元素的目录结构:
-- (一个或多个)module的编译Output;
-- 包含在module的依赖中的Libraries;
-- 资源的集合,如web页面,图片,descriptor文件;
-- 其他artifacts;
-- 个别文件、目录和archives;
Name :artifact配置的名称,又或是artifact的名称。
Type :artifact的类型
Output directory :当执行build(Build | Build Artifacts)时,artifact将被放到这个指定的目录下。
本项目所有maven工程模块的Artifacts配置的Output directory如下:
1、Type为Exploded:模块根目录\target\模块名。该类型的内容为在本地服务器运行时所需资源。
注意,这里target下的“模块名”目录一定要跟当前模块的pom.xml配置文件中的finalName标签中的值一致。否则就会导致项目启动时报错java.lang.ClassNotFoundException,因为IDEA找资源的路径跟配置的不一致。通常情况下,finalName标签中的值跟模块名是相同的,但也有可能出于其他原因考虑而设置成不相同的。比如,下面就是本人项目中的设置(项目组架构师设置的),我原以为finalName标签中的值跟模块名是相同的,就把Output directory设置为模块根目录\target\模块名,结果启动项目一直报错,还找不到原因(报错找不到的类文件确实存在,并且在pom.xml文件中已经添加依赖),浪费了我两天的时间才找到问题根源。
2、Type为Archive:模块根目录\target。该类型资源为模块打出来的war包。
注意,当配置了Type为Exploded的artifact,配置Type为archive的artifact时就可以选择 For “某个Type为Exploded的artifact”,如下图:
此时,就可以选择Artifact来配置本地Tomcat服务器运行项目了。
基于上面的配置,编译后生产的目录及资源。
PS:配置Tomcat运行web项目全流程如下。
在Server tab中,设置项目名,选择本地web服务器,取消勾选After launch(即取消程序启动后打开URL对应的页面,默认是勾选的),设置·VM options(比如日志编码格式,此处是UTF-8),选择JRE,设置Tomcat服务器的Http port、JMX port。
切换到Deployment tab,选择Artifact,配置Application context(这里设置的值会影响Server tab中的URL的值),点击OK。
选择配置好的启动配置,点击启动,等待项目启动完成。