Spring Boot can't find profile-specific properties files - java

I am following Spring documentation to use profile specific property files for my SpringBoot app. I have 2 property files under src/main/resources : datasource.properties for local development and datasource-prod.properties for server datasource config.
This is my DataSourceConfiguration.java config class :
#Configuration
#PropertySource("classpath:datasource-{profile}.properties")
#Slf4j
public class DataSourceConfiguration {
#Value("${flad.datasource.driver}")
private String dataSourceDriverClassName;
#Value("${flad.datasource.url}")
private String dataSourceUrl;
#Value("${flad.datasource.username}")
private String dataSourceUsername;
#Value("${flad.datasource.password}")
private String dataSourcePassword;
#Bean
public DataSource getDataBase(){
log.info("Datasource URL = {}", dataSourceUrl);
return DataSourceBuilder
.create()
.driverClassName(dataSourceDriverClassName)
.url(dataSourceUrl)
.username(dataSourceUsername)
.password(dataSourcePassword)
.build();
}
}
When I launch my SpringBootApplication main class I get the following error whether I use -Dspring.profiles.active=prod or not :
17:05:49.008 [restartedMain] ERROR org.springframework.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [fr.payet.flad.core.config.CoreConfig]; nested exception is java.io.FileNotFoundException: class path resource [datasource-{profile}.properties] cannot be opened because it does not exist

The solution that I found is to rename my property files datasource-local.properties and datasource-prod.properties, use #PropertySource this way #PropertySource("classpath:datasource-${profile}.properties") and when I launch my SpringBoot app I use -Dprofile=local as VM options

Related

Getting variables from application.properties using SmallRyeConfig in quarkus fails

I followed this documentation to get configs from application.properties in a quarkus service.
I am not using CDI, so here is what I am doing to get this config:
application.properties
redis.hosts=${REDIS_HOSTS}
redis.port=${REDIS_PORT}
redis.password=${REDIS_PASSWORD}
Note: I have set these environment variables.
RedisConfigInterface
import java.util.Set;
import io.smallrye.config.ConfigMapping;
#ConfigMapping(prefix = "redis")
interface RedisConfigInterface {
Set<String> hosts();
Integer port();
String password();
}
ConfigCreation
public class ConfigCreation {
public ConfigCreation() {
//Registering config
new SmallRyeConfigBuilder()
.withMapping(RedisConfigInterface.class)
.build();
// Getting config
RedisConfigInterface config = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class).getConfigMapping(RedisConfigInterface.class);
Integer port = config.port();
System.out.println(port);
}
}
It builds correctly but I got this error when executing the service:
12:17:02 ERROR [io.qu.ru.Application] (Quarkus Main Thread) Failed to start application (with profile dev): io.smallrye.config.ConfigValidationException: Configuration validation failed:
java.util.NoSuchElementException: SRCFG00014: The config property redis.hosts is required but it could not be found in any config source
java.util.NoSuchElementException: SRCFG00014: The config property redis.password is required but it could not be found in any config source
java.util.NoSuchElementException: SRCFG00014: The config property redis.port is required but it could not be found in any config source
Am I missing something here? Everything seems to be set correctly.

Inject property into applicationContext.xml as value (spring boot 2.2)

I am trying to inject a property into my applicationContext.xml file in my spring boot project:
Application file :
#SpringBootApplication
#PropertySource("classpath:navi.properties") // <== injection here
#ImportResource({"classpath*:applicationContext.xml"}) // <== load the xml setting file
public class CApplication {
public static void main(String[] args) {
SpringApplication.run(CApplication.class, args);
}
}
As you can see, nothing fancy here... In my src/main/resources/navi.properties file :
USER_INFO_CLS=jp.co.xxx.yyy.fw.service.UserInfoService
in my applicationContext.xml, I am trying to inject this value :
<bean id="userInfoService" class="${USER_INFO_CLS}"/>
But ./mvnw spring-boot:run returns the error below :
Caused by: org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [${USER_INFO_CLS}] for bean with name 'userInfoService' defined in class path resource [applicationContext.xml]; nested exception is java.lang.ClassNotFoundException: ${USER_INFO_CLS}
I read many articles about it (like this one) and it sounds good....
Thanks

Spring externalize configuration yml

I am trying to configure the spring-boot application with yml and properties. I might have made mistakes at multiple places :)
I run my application as below with following contents :
java -jar /opt/elast-search-0.0.1-SNAPSHOT.jar --spring.config.location=. --spring.config.name=elast.properties,ere.yml
My YAML file looks like :
log:
count: 1
searchText: someText
services:
- um
- sa
minutesTime: 1
count: 2
searchText: someMoreText
services:
- um2
- sa2
minutesTime: 2
Without the elast.properties file and the second bean content (i.e. from count to the minutesTime section in yaml) I see the yml is loading and I am running it with :
java -jar elast-search-0.0.1-SNAPSHOT.jar --spring.config.location=ere.yml
I am running multiple properties file because I want to have a default configuration as well and the module is still evolving. I have #Autowired the class in the spring boot application.
#Configuration
#EnableConfigurationProperties
#ConfigurationProperties(prefix = "log")
public class LogRule {
private int count;
private String searchText;
private String[] services;
private int minutesTime;
}
I want to read all YAML configuration as a list.
I want to read the configuration file if the file is changed or at regular intervals.

How do you create JDBC TokenStore in Spring Boot?

I tried to follow this answer to add JDBC TokenStore to my app.
https://stackoverflow.com/a/37595818/148844
It is working with an InMemoryTokenStore. I need to know where to put this code
#Bean(name = "OAuth")
#ConfigurationProperties(prefix="datasource.oauth")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
I tried to put it in
#Configuration
#EnableAuthorizationServer
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {
But I got the error
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'OAuth2Configuration': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'OAuth': Requested bean is currently in creation: Is there an unresolvable circular reference?
So I moved it to the main class
#SpringBootApplication
#MapperScan("com.example.mapper")
public class ExampleApplication extends SpringBootServletInitializer {
But then it gave a different error
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: The url cannot be null
So where do I put that snippet to define the bean?
You need to have the database configuration properties in your application-{profile}.properties, in particular they need to be prefixed by datasource.oauth. Here profile will be any of the profiles that your application is running on (e.g: dev, stage, prod).
The error that is showing clearly says that there is no datasource.oauth.url=.. property in the specific properties file.

spring load dynamically beans from xml which use property injection

I need to load bean definitions from XML. The file is in a remote location (http) which is configured by properties. The properties should also be loaded from a remote location (a spring cloud config server)
constraints:
Spring 4.3.14 (not boot)
should be in runtime and after my properties already loaded
beans defined in xml are referencing properties in context
server URI (to fetch the xml from) should be in properties and not environment variable or profile depandant
The current setup I have works well when MY_XML_URI is passed as environment variable:
${SPRING_CONFIG_URI}/master/application-${spring.profiles.active}.properties
<import resource="${MY_XML_URI}/myBeans.xml"/>
And in the remote location, myBeans.xml with lots of beans e.g.
<bean name="mySpecialBean" class="com.example.MyGenericBean">
<constructor-arg value="mySpecialBean"/>
<constructor-arg value="${special.bean.config.expression}"/>
</bean>
However trouble starts when I want to get MY_XML_URI from the properties context, it doesn't resolve
…
I have tried several approaches e.g:
java configuration class with #ImportResource({"${xml.server.uri}"})
but the properties are not loaded yet so it not converting to real value of xml.server.uri .
#Configuration
#ImportResource({"${xml.server.uri:http://localhost:8888}/myBeans.xml"})
public class MyConfiguration {}
expose dummy bean which fetch xml as resource and load the beans to parent applicationcontext - i must have it available to other beans dependant on those beans defined in xml. This solution was not injecting the properties context to my beans so failed to init them.
#Configuration
public class RiskConfig {
#Value("${xml.server.uri}")
private String xmlUri;
#Autowired
#Bean
public Object myBean(ApplicationContext applicationContext) {
Resource resource = applicationContext.getResource(xmlUri + "myBeans.xml");
// not working since its not loading the beans to the main context
// GenericApplicationContext genericApplicationContext = new GenericApplicationContext(applicationContext);
// XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(genericApplicationContext);
// reader.loadBeanDefinitions(resource);
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
reader.loadBeanDefinitions(resource);
return new Object();
}
}
Finally - is there a way to load the beans from xml programmatically to parent application context (which is already exist) though they are injected with properties.

Categories