I am trying to read in a simple yml file for a Spring Boot application located at resources/wtf.yml. The following application works if the default application.yml filename is used, but not if I change the filename. Anyone know why this doesn't work?
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import javax.annotation.PostConstruct;
#EnableConfigurationProperties
#SpringBootApplication
#ConfigurationProperties(locations = {"wtf.yml"}) //classpath:wtf.yml
public class SomeApp {
public static void main(final String[] args) {
SpringApplication.run(SomeApp.class, args);
}
#PostConstruct
public void init() {
System.out.println(readTimeout);
}
#Value("${readTimeout}")
public int readTimeout;
}
You can use spring.config.name or spring.config.location properties as described in Spring Boot guide.
Related
So I've got a simple spring boot app, #SpringBootApplication, a stub #Configuration and a #RestController all in the same package. Spring-boot-web-starter is there and the webserver comes up fine, actuator endpoints and all. But I cannot for the life of me get the app to pick up the #RestControllers.
enter image description here
Main.class:
package com.iglossolalia.munin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(MuninContext.class, args);
}
}
MuninContext.class:
package com.iglossolalia.munin;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableAutoConfiguration
public class MuninContext {
}
MuninService.class:
package com.iglossolalia.munin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class MuninService {
private static final Logger LOG = LoggerFactory.getLogger(MuninService.class);
public MuninService() {
LOG.info("Started MuninService");
}
#GetMapping("/health")
public String healthCheck() {
return "pong";
}
}
Tried explicitly adding the rest controller to the component scan with no luck there.
You have no #ComponentScan annotation in your MuninContext. Actually you can write SpringApplication.run(Main.class, args) in main method as Spring Initializr generate by default, you don't really need your context, because #SpringBootApplication work as configuration and contains #EnableAutoConfiguration, #ComponentScan, and some other annotations. Otherwise, as you pass your config class as argument in SpringApplication.run method, annotation #SpringBootApplication in Main class has no effect
I am playing with a simple batch processing and I have a problem with a DataSource configuration despite having an H2 dependency.
Output from the console:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
My classes operates on Strings and use:
org.springframework.batch.item.ItemProcessor;
org.springframework.batch.item.ItemReader;
org.springframework.batch.item.ItemWriter;
Main
#SpringBootApplication
public class Boo2BatchApplication {
public static void main(String[] args) {
SpringApplication.run(Boo2BatchApplication.class, args);
}
}
Config:
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableBatchProcessing
public class BatchConfig {
#Bean
public Step recordsStep(StepBuilderFactory stepBuilderFactory, RecordReader recordReader,
RecordProcessor<String> recordProcessor, RecordWriter recordWriter) {
return stepBuilderFactory.get("recordsSetp").<String, String>chunk(4).reader(recordReader)
.processor(recordProcessor).writer(recordWriter).build();
}
#Bean
Job recordsJob(JobBuilderFactory jobBuilderFactory, Step recordsStep) {
return jobBuilderFactory.get("recordsJob").start(recordsStep).build();
}
}
When a Database like H2 is on the path the DataSource is configured by default (as #Alireza Khajavi said). No additional configuration is needed. My classpath was messed up and the dependency from a pom file was not available during startup.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
I am working on spring boot application where I want to completely externalize my environment variables dynamically by config server.
So below is the code I have written.
Application.java
package com.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
#Configuration
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan("com.myPackage, com.util")
#PropertySource("classpath:application.properties")
public class Application extends SpringBootServletInitializer {
static final Logger logger = LoggerFactory.getLogger(Application.class);
public static ApplicationContext ctx;
public static void main(String[] args) throws Exception {
logger.info("Application starting....");
ctx = SpringApplication.run(Application.class, args);
logger.info("Application started successfully....");
}
#Bean
public static PropertySourcesPlaceholderConfigurer
propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
application.properties
server.port=${server.port}
ENDPOINT_SHAN=${name.mya}
Config Server:
APPLICATION_NAME=myapp
server.port=8081
name.mya=myName
To Read Properties
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import com.apptium.Application;
#Component("configurationProperties")
public class ConfigurationProperties {
private static Environment prop;
public static String getConfigValue(String key) {
String value = null;
if (prop == null) {
prop = Application.ctx.getBean(Environment.class);
}
if (prop.getProperty(key) != null) {
value = prop.getProperty(key).trim();
}
if (value == null && System.getenv(key) !=null) {
value = System.getenv(key).trim();
}
return value;
}
}
so, when I try to get the property ENDPOINT_SHAN, it is returning
ENDPOINT_SHAN==${name.mya} but it needs to return ENDPOINT_SHAN==myName
And also am wondering how the property for server.port is taken correctly.
Anyways, I would like to know, how to get an actual property for ENDPOINT_SHAN.
You said that name.mya is defined in a "Config Server" but your code doesn't show any connection being established to this server. You need to read it from the server before ${name.mya} becomes resolvable.
I just started learning spring batch with no prior experience of Spring batch.
I downloaded a template from start.spring.io and selected following
After this I imported the project in IntelliJ IDE and made following changes
Added a job configuration class:
package io.spring.helloworld.configuration;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration //For spring configuration
#EnableBatchProcessing //bootstrap all the infra needed to run spring batch
public class jobConfiguration {
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.tasklet(new Tasklet() {
#Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
System.out.println("Hello World");
return RepeatStatus.FINISHED;
}
}).build();
}
#Bean
public Job HelloWorld() {
return jobBuilderFactory.get("HelloWorldJob")
.start(step1())
.build();
}
}
and this is how my entry class looks
package io.spring.helloworld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
System.exit(0);
}
}
I have not touched or modified any class\configuration. But when i run the app, I get following message:
Description:
Cannot determine embedded database driver class for database type NONE
Action:
If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
What Can i do to fix this error?
To resolve this error there are two methods:
Method 1:
Try adding below annotation:
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
example:
#SpringBootApplication
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class HelloWorldApplication {
-----
}
Method 2:
you can add the below line in application.properties file
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
I am having an issue since I moved to version 1.1.4.RELEASE of Spring Boot.
My variables that are annotated with #Value are presently not being populated with values despite them being present in the application.properties. Prior to this I was using Spring Boot # version 1.0.2, and that was working fine.
It all started since the upgrade, and I made no code change.
SampleApplication.java
package org.sample;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
#Configuration
#ComponentScan
#EnableAutoConfiguration
#PropertySource(value = "classpath:application.properties")
public class SampleApplication {
private static Logger logger = LoggerFactory
.getLogger(TaskManagerApplication.class);
#Value("${org.sample.sampleProperty}")
private static String sampleProperty;
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
System.out.print("SampleApplication started: " + sampleProperty);
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
application.properties
spring.datasource.url: jdbc:mysql://127.0.0.1:3306/mydb
spring.datasource.username: root
spring.datasource.password: root
spring.datasource.driverClassName: com.mysql.jdbc.Driver
spring.jpa.show-sql: true
#Disable the ddl-auto:create once tables have been created
#spring.jpa.hibernate.ddl-auto: create
org.sample.sampleProperty=This is a sample property
photos.upload.dir=C:/temp/UserPhotos/
# Server port
server.port=8081
I have tried to add a PropertySourcesPlaceholderConfigurer bean and even PropertySourcesPlaceholderConfigurer but still the issue persists.
Anyone experienced this ? Or is there a new way to load the properties file ?
Please note that my db connection and server port are being read properly since my application can connect to db and I have to access it through the specified port.
sampleProperty variable remains null though.
#Value is not meant to work on static fields
Properties from application.properties are available automatically without specifying #PropertySource for it.
Instead of printing out property in main() method, you should do it after bean is constructed, for example by using #PostConstruct
Fully working example:
package demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application {
#Value("${org.sample.sampleProperty}")
private String sampleProperty;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#PostConstruct
public void postConstruct() {
System.out.print("SampleApplication started: " + sampleProperty);
}
}