【问题标题】:Tomcat Not reading Spring-Boot Application PropertiesTomcat 不读取 Spring-Boot 应用程序属性
【发布时间】:2014-01-07 04:37:18
【问题描述】:

我对 spring/java 还很陌生,并且一直在为我工作的项目检查 spring-boot。我一直在遵循指南,终于有了一个(半)工作的网络应用程序 MVC + JPA 用于数据访问。当我通过 Jar 方法部署应用程序时,一切正常:

java -jar build/libs/client.jar

但是,我们的应用程序最终将部署到 Tomcat (v7.0.40),因此我需要从项目中创建一个 war 文件。我遵循了 spring.io 网站上的converting jars to war 指南并遇到了问题。它似乎没有加载 application.properties 文件。以下是重要的代码sn-ps:

src/main/java/hello/GreetingController:

@Controller
@Configuration
public class GreetingController {
    @Value("${app.username}")
    private String username;

    @RequestMapping("/greeting")
    public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
        model.addAttribute("name", name);
        model.addAttribute("username", username);
        return "greeting";
    }
} 

src/main/java/hello/Application.java

@ComponentScan
@EnableAutoConfiguration
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

src/main/java/hello/HelloWebXml.java

public class HelloWebXml extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
}

src/main/resources/application.properties

app.username=foo

为了完整起见,这里是 build.gradle:

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-snapshot" }
        mavenLocal()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:0.5.0.M6")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'

war {
    baseName = 'client'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
    maven { url "http://repo.spring.io/libs-snapshot" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:0.5.0.M6")
    compile("org.thymeleaf:thymeleaf-spring3:2.0.16")
    testCompile("junit:junit:4.11")
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.8'
}

我构建应用程序:

gradle clean build

在tomcat中丢掉war,然后tail out日志看看如下:

SEVERE: ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina]
.StandardHost[localhost].StandardContext[/client]]
...
...
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating the bean
with name 'greetingController': Injection of autowired dependencies failed; nested exception
is java.lang.IllegalArgumentException: Could not resolve placeholder 'app.username' in string
value "${app.username}"
...
...
...

正如我所说,当我通过 jar 运行它时它可以工作,但当我将它部署到 Tomcat 时它不起作用。我还查看了$TOMCAT_HOME/webapps/client/WEB-INF/classes 内部,我看到了application.properties 文件。所以我认为它应该在类路径上。我的问题是,为什么tomcat不加载它?我已经尝试过全面搜索,但似乎没有其他人遇到这个问题,所以我不确定它是否只是我配置错误的东西,还是什么。

提前致谢。

【问题讨论】:

  • Spring boot 默认加载application.properties。尝试将 @PropertySource("application.properties") 添加到您的 @Configuration 类中,看看它是否真的找到它。
  • 嘿@SotiriosDelimanolis 感谢您的回复。不幸的是,这也不起作用。当 tomcat 尝试加载战争时,我得到了 FileNotFoundException。如果需要,我可以给你更多细节,请告诉我。
  • 对不起,应该是classpath:application.properties
  • 再次感谢,我继续添加,但注意到编译器警告:Cannot find annotation method 'value()' in type 'Repeatable': class file for java.lang.annotation.Repeatable not found. 当我将它放入 tomcat 时,我得到:Failed to load bean class: hello.Application; nested exception is org.springframework.core.NestedIOException: Unable to collect imports; nested exception is java.lang.ClassNotFoundException: java.lang.annotation.Repeatable
  • @SotiriosDelimanolis @PropertySource 注解可以与 Spring Boot 应用程序一起使用,但如果它是 classpath:application.properties 则不需要声明它(并且有一些框架功能不能配置为@PropertySource) - 不过这里不相关。

标签: java spring tomcat spring-boot


【解决方案1】:

听从这些人的建议:http://blog.codeleak.pl/2013/11/how-to-propertysource-annotations-in.html

尝试:

@PropertySources(value = {@PropertySource("classpath:application.properties")})

然后为胜利而繁荣。

【讨论】:

  • 连同上面的一些 cmets,这最终对我有用。我的问题仍然是,为什么它不首先加载属性?此外,将它添加到我的控制器文件中会给我一个编译器警告,我还没有完全弄清楚。
  • 重复我上面的评论:这在 Spring Boot 应用程序中不是必需的。
  • 这会导致一个相当奇怪的错误:“ClassCastException: PropertySource cannot be cast to java.util.Map” while using Spring Boot on Java 7
  • @MikeAdler 这个答案指的是PropertySources,它是复数,而不是PropertySource,它是单数
  • 谢谢!这没关系,但你知道如何从其他模块加载application-xxx.properties 文件吗?
【解决方案2】:

问题是您尝试在 @Configuration 类中使用 @Value 注释。来自@PropertySource的JavaDoc:

为了使用 PropertySource 中的属性解析 定义或 @Value 注释中的 ${...} 占位符,必须注册一个 PropertySourcesPlaceholderConfigurer。这在 XML 中使用 时会自动发生,但在使用 @Configuration 类时必须使用静态 @Bean 方法显式注册。

例如将以下行添加到 @Configuration 类:

@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

但是,在您的示例中,更合适的方法是将 @Configuration 注释从 GreetingController 类(它不包含任何配置)移动到 Application 类。由于Application 类不包含任何@Value 注释,它应该可以在不建议添加静态PropertySourcesPlaceholderConfigurer bean 的情况下工作。

【讨论】:

    【解决方案3】:

    我来这里是为了寻找同样的问题。当 Spring Boot 应用程序在 tomcat 中作为战争运行时,application.properties 未加载,但在使用嵌入式 tomcat 运行时它工作正常。问题出在文件名中。我使用了 Application.properties 而不是 application.properties 。从 tomcat 运行时,它看起来是区分大小写的。把它放在这里,如果有人犯了和我一样的愚蠢错误

    2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件 'file:./config/application.xml' 资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“file:./config/application.yml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“file:./config/application.properties”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“file:./config/application.yaml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“file:./application.xml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“file:./application.yml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“file:./application.properties”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“file:./application.yaml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“类路径:/config/application.xml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“类路径:/config/application.yml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“类路径:/config/application.properties”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“类路径:/config/application.yaml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“classpath:/application.xml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“classpath:/application.yml”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“类路径:/application.properties”资源未找到 2015-09-10 14:42:13,982 调试 o.s.b.c.c.ConfigFileApplicationListener [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 跳过配置文件“classpath:/application.yaml”资源未找到

    【讨论】:

    • 我遇到了同样的问题。但是文件 Application.properties 是在 Maven 构建期间默认生成的。谢谢@janardhan,我被困了好几个小时
    【解决方案4】:

    我认为对于那些将默认命名“application.[properties,yaml,etc]”更改为例如“service.[properties,yaml,etc]”的人,可以将其添加到 build.gradle 任务中:

    bootRun {
        systemProperties = [
           'spring.config.name':'service'
        ]
    }
    

    【讨论】:

      猜你喜欢
      • 2015-11-21
      • 1970-01-01
      • 2017-06-17
      • 2021-03-22
      • 2017-06-26
      • 2021-03-12
      • 2021-09-01
      • 2021-08-23
      • 1970-01-01
      相关资源
      最近更新 更多