IntelliJ 中的“更新资源”从目标目录中删除更新的文件

Posted

技术标签:

【中文标题】IntelliJ 中的“更新资源”从目标目录中删除更新的文件【英文标题】:"Update Resources" in IntelliJ deletes updated files from target directory 【发布时间】:2015-06-20 20:03:57 【问题描述】:

短版

当我更改应用程序中的资源,然后尝试热部署它们时,文件被删除而不是从 target/ 目录更新,我不明白为什么。

加长版

我有一个 Java 8 + Tomcat 8 + Spring Boot + Thymeleaf 项目,我的 IntelliJ 快用完了。当我从src/main/resources/static/css 目录更改文件(例如CSS 文件)并运行Update ResourcesUpdate classes and resources 时,该文件从target/classes/static/css删除,而不是更新。 Tomcat 日志中没有打印任何关于该文件的信息,IntelliJ 日志(~/Library/Logs/IntelliJIdea13/idea.log)中也没有打印任何关于删除文件的信息……它只是消失了。

Tomcat 8 设置为外部应用服务器(不是内置的 Spring Boot 嵌入式服务器),配置如下。我在 IntelliJ 运行配置设置中自定义的唯一内容是将 CATALINA_BASE 指定为与​​“Tomcat Base”相同的值,如下所示:

Tomcat Home: /usr/local/tomcat8
Tomcat Base: /path/to/my/catalina/base
Java Env Vars: CATALINA_BASE=/path/to/my/catalina/base

...如果我不这样做,CATALINA_BASE 将设置为 /Users/me/Library/Caches/IntelliJIdea13/tomcat/Unnamed_demo_app,这似乎是我的 真实 catalina 基地的非工作克隆,我到处都得到 404。这可能是这里的红鲱鱼,或者是解开谜团的关键。

额外的,可能没用的信息

这是idea.log 中相关(但无趣)的输出:

INFO - ij.compiler.impl.CompileDriver - COMPILATION STARTED (BUILD PROCESS)
INFO - j.compiler.server.BuildManager - BUILDER_PROCESS [stdout]: Build process started. Classpath: /Applications/IntelliJ IDEA 13.app/lib/jps-launcher.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/lib/tools.jar:/Applications/IntelliJ IDEA 13.app/lib/optimizedFileManager.jar:/Applications/IntelliJ IDEA 13.app/lib/ecj-4.3.2.jar
INFO - lij.compiler.impl.CompilerUtil -   COMPILATION FINISHED (BUILD PROCESS); Errors: 0; warnings: 0 took 3709 ms: 0 min 3sec

该应用程序配置为进行 WAR 部署,使用自定义 catalina 库,其中包含库存 conf/server.xmlconf/web.xml,以及 lib 中提供的各种第 3 方库。

这是我的 POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>myapp</artifactId>
    <version>0.1-BETA</version>
    <packaging>war</packaging>

    <properties>
        <spring-boot-version>1.2.1.RELEASE</spring-boot-version>
        <spring-version>4.1.4.RELEASE</spring-version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.1.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>$spring-boot-version</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>$spring-boot-version</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>$spring-boot-version</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>dojo</artifactId>
            <version>1.10.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- for equals/hash/toString builder -->
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- Spring/Mail integration -->
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- Spring/Mail integration -->
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>$spring-version</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- connection pooling -->
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>2.3.5</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

我不确定关于这个问题还有什么值得讲述的,尽管我觉得我提供的东西没有用。如果有任何我应该添加的信息,请添加评论。

【问题讨论】:

我通过 VM 选项定义了要使用的 cataline:see this question 【参考方案1】:

我猜你正在使用 maven 插件。

默认情况下,当您运行应用程序时,任何 src/main/resources 文件夹都将添加到应用程序类路径中,并且在 target/classes 中找到的任何重复项都将被删除。这允许热刷新资源,这在开发 Web 应用程序时非常有用。例如,您可以处理 html、CSS 或 JavaScipt 文件并立即查看您的更改,而无需重新编译您的应用程序。这也是一种让前端开发人员无需下载和安装 Java IDE 即可工作的有用方式。

如果您可以直接从 IDEA 启动应用程序(只需运行主类),我会这样做。否则,通过配置插件禁用该功能:

<build>
  ...
  <plugins>
    ...
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>1.2.3.RELEASE</version>
      <configuration>
        <addResources>false</addResources>
      </configuration>
    </plugin>
    ...
  </plugins>
  ...
</build>

http://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html

【讨论】:

我没有使用 maven-plugin,我使用的是外部 Tomcat。但是我尝试转换为使用 maven-plugin 我还尝试将 springloaded 作为依赖项引入,并尝试左右配置,但仍然无法识别 src/main/resources 目录的更改。在看到我的更改之前,我必须将其显式添加为“类”运行时模块依赖项。我终于可以在不重新启动Tomcat的情况下进行JS更改了。【参考方案2】:

我必须在 IDEA 中明确提供 src/main/resources 作为运行时 Module Dependency,然后才能热交换对我的 Web 文件(Thymeleaf 模板、静态文件等)的更改。

更新 -- 虽然明确设置src/main/resources 仍然感觉像是对我的错误配置的一种补偿控制,它确实让我更新了我的文件。但是,我仍然发现了另一个问题,即我的 电子邮件模板 打包在 Spring-Boot jar 中时无法解析,这给了我这样的错误:

org.thymeleaf.exceptions.TemplateInputException: 
    Error resolving template "foo", template might not exist 
    or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:246)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:924)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:898)
[...]

我有以下代码,其中我有一个前导斜杠。当我被配置为使用外部 Tomcat 时,前导斜杠无关紧要,但在 jar 中打包时,前导斜杠会中断类路径搜索。

@Bean
public ClassLoaderTemplateResolver emailTemplateResolver()
    ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver();
  //emailTemplateResolver.setPrefix("/templates/mail/");   // <-- The problem!
    emailTemplateResolver.setPrefix("templates/mail/");    // <-- The fix!
    emailTemplateResolver.setSuffix(".html");
    emailTemplateResolver.setTemplateMode("HTML5");
    emailTemplateResolver.setCharacterEncoding("UTF-8");
    emailTemplateResolver.setOrder(1);

    return emailTemplateResolver;

【讨论】:

以上是关于IntelliJ 中的“更新资源”从目标目录中删除更新的文件的主要内容,如果未能解决你的问题,请参考以下文章

可以从 IntelliJ IDEA 的打开文件列表中删除 .class 文件吗?

Intellij IDEA。总是显示 maven 的 `target` 目录

Intellij Idea 自动更新资源和类

IntelliJ 中的目标字节码总是回落到 1.5

为啥 IntelliJ 不断从这个 JavaScript 模板字符串中删除反引号?

IntelliJ/GIT:如何从提交窗口清除/删除文件?