--- title: VSCode 运行 Spring Boot 项目时找不到主类的问题 date: 2020-12-09 16:42:30 tags: - VS Code - Spring - Spring Boot categories: - Spring Boot --- ## 开发环境 VSCode 众多的插件极大地扩展了它的功能,使得它可以做很多开发,如 C/C++、Java、Python、Vue 等。有时候,我会拿它来做 Spring Boot 的开发。 我安装的插件有: - [Spring Boot Extension Pack](https://marketplace.visualstudio.com/items?itemName=Pivotal.vscode-boot-dev-pack) - [Java Extension Pack](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack) > 这两个扩展包中包含了必要的插件。 > 本文默认你已经安装配置好了 JDK 和 maven。 ## 问题描述 当我们执行了 maven 的 clean 操作之后,点击 `main` 函数上面的 `run` 视图运行项目时,会出现“找不到主类”的问题,如下所示: ``` 错误: 找不到或无法加载主类 xyz.zhouxy.demo.DemoApplication 原因: java.lang.ClassNotFoundException: xyz.zhouxy.demo.DemoApplication ``` ## 问题分析 这是因为,当我们执行 clean 之后,target 文件夹被删除了,也就是编译后的 class 文件都被删掉了,所以当我们点击 run 试图运行项目时,Java 找不到主类。 ### 为什么 IDEA 不会出现这种问题? IDEA 默认在运行项目之前,有一个 build 的过程。我们打开“运行/调试配置”窗口可以看到,在“执行前”列表中有一个“构建”,如果我们按下方的减号(-)把它去掉,并执行 `mvn clean`,点击“运行”或者“调试”按钮的话,也会同样“找不到主类”。 ## 解决方法 我们可以在运行项目前,先执行 `mvn compile` 命令,或者打开 pom.xml 文件,然后右键,点击“Update Project”,完成对项目的编译。 ## 配置 每次运行项目之前都得先执行编译命令,这样的开发体验并不好,我们可以通过 VSCode 的一些配置来解决。 ### 1. 配置 launch.json 如果你安装前面所说装好了插件,那么在左侧的资源管理器面板中,应该会出现一个 **SPRING-BOOT DASHBOARD** 面板,上面列出了当前 Spring Boot 项目的名称,在改项目名称上右键,点击“start”。 这时候,如果你的项目已经编译好的话,则可以在下方的“调试控制台”看到输出;如果你执行了 `mvn clean` 的话,也可以在“调试控制台”看到讨厌的“找不到主类”。 实际上,你会发现在项目中多了一个 `.vscode` 文件夹,里面有一个 `launch.json` 文件,内容类似于下面这样: ```JSON { "configurations": [ { "type": "java", "name": "Spring Boot-DemoApplication", "request": "launch", "cwd": "${workspaceFolder}", "console": "internalConsole", "mainClass": "xyz.zhouxy.demo.DemoApplication", "projectName": "demo", "args": "" } ] } ``` 其中,mainClass 和 projectName 的值会与这里的不同,是插件根据你的项目生成的,不用改。我们要做的是,在 `args` 后面再添加一个 `preLaunchTask` 属性,值为 `"build"`: ```JSON { "configurations": [ { "type": "java", "name": "Spring Boot-DemoApplication", "request": "launch", "cwd": "${workspaceFolder}", "console": "internalConsole", "mainClass": "xyz.zhouxy.demo.DemoApplication", "projectName": "demo", "args": "", "preLaunchTask": "build" } ] } ``` 也就是说,我们希望在运行/调试这个项目之前,都执行一遍 `build` 这个任务。`build` 的具体内容,则是在 tasks.json 中配置的。 ### 2. 配置 tasks.json 在 `.vscode` 文件夹中,新建一个名为 `tasks.json` 的文件,内容如下: ```JSON { "version": "2.0.0", "options": { "cwd": "${workspaceRoot}" }, "tasks": [ { "label": "build", "type": "shell", "command": "mvn clean compile" } ] } ``` 我们在其中配置了一个名为 `build` 的任务,让它在 shell 中执行 `mvn clean compile` 命令,这样在每次运行/调试项目之前,都会在“**终端**”中执行一次 `mvn clean compile` 命令,而 Spring Boot 的输出,会在“调试控制台”显示。 > 其实,launch.json 中的 `console` 属性的值,我们可以配置为 `integratedTerminal`,这样 Spring Boot 的输出也会在终端中显示,但我还是建议 `console` 的值保持为 `internalConsole`,因为它可以设置筛选器,过滤出需要的输出。 现在,不论你 **点击主函数上的 run 或者 debug**、**在运行面板中点击运行按钮**,还是**在 SPRING-BOOT DASHBOARD 面板中点击运行项目**,都会调用 maven 进行编译,然后再运行。