I'm fairly new to spring/java and have been checking out spring-boot for a project I have at work. I've been following guides and finally have a (semi) working web app MVC + JPA for data access. Everything works when I deploy the app via the Jar method :
java -jar build/libs/client.jar
However, our application is eventually going to be deployed to Tomcat (v7.0.40) so I need to create a war file from the project. I've followed the converting jars to war's guide on the spring.io site and have run into a problem. It appears that it is not loading up the application.properties file. Here are the important code snippets:
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
for completeness, here is the 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' }
I build the application:
gradle clean build
Drop the war in tomcat, and then tail out the logs and see the following:
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}" ... ... ...
As I said, it works when I run it via a jar, but does not work when I deploy it to Tomcat. I also looked inside $TOMCAT_HOME/webapps/client/WEB-INF/classes
and I see the application.properties
file. So I think that it should be on the classpath. My question is, why isn't tomcat loading it? I've tried searching all over and no one else seems to be having this problem so I'm not sure if its just something I have incorrectly configured, or what.
Thanks in advance.
React + Spring Boot Microservices and SpringBy using Spring Boot application, we can create a war file to deploy into the web server. In this chapter, you are going to learn how to create a WAR file and deploy the Spring Boot application in Tomcat web server.
It doesn't "go in Tomcat". It goes in the web application (WAR). The best place to put a properties file would be in the webapp's WEB-INF/classes directory, which is part of the application classpath.
follow this guys advice: http://blog.codeleak.pl/2013/11/how-to-propertysource-annotations-in.html
try:
@PropertySources(value = {@PropertySource("classpath:application.properties")})
then boom sauce for the win.
The problem is that you attempt to use a @Value
annotation inside your @Configuration
class. From the JavaDoc of the @PropertySource:
In order to resolve ${...} placeholders in <bean> definitions or @Value annotations using properties from a PropertySource, one must register a PropertySourcesPlaceholderConfigurer. This happens automatically when using <context:property-placeholder> in XML, but must be explicitly registered using a static @Bean method when using @Configuration classes.
e.g. add the following lines to the @Configuration
class:
@Bean public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); }
However, in your example, a more suitable approach is to move the @Configuration
annotation from the GreetingController
class (it does not contain any configuration) to the Application
class. Since the Application
class does not contain any @Value
annotation it should work without the suggested addition of the static PropertySourcesPlaceholderConfigurer
bean.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With