Properties not found with Spring PropertySource - java

Config
#Configuration
#PropertySources({
#PropertySource("classpath*:properties/test-database.properties")
})
public class DataSourceConfiguration {//...
}
Prop location
D:\Projects\opti\dao\src\main\resources\properties\test-database.properties
D:\Projects\opti\dao\src\main\resources marked as resource folder.

To avoid this kind of problem the issue is to set the jboss.server.config.dir in VM arguments like that :
-Djboss.server.config.dir="[jboss_repository]/server/[default-all-standard-standalone]/conf" –server
and u set PropertySource like this :
#Configuration
#PropertySource("file:${jboss.server.config.dir}/file.properties")
Or you set ur property like that
#PropertySource(value = "classpath:application.properties")
When executed, properties will be imported from the application.properties file, located in the classpath root.

It isn't clear well the your problem considering the details of your question, but a typical problem whit #PropertySource is that yuo have configure a spring bean for manage the properties. In old years in which xml was the best way for configure Spring you used a namespace configuration that configure a spring bean for use proeprties in your bean, mainly with #Value. In java config for benefit of same behaviour you have configure a bean like belove:
#Bean
public static PlaceholderConfigurerSupport propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
I hope that this can help you

Related

Binding spring boot application properties to java.util.properties

I am creating a spring-boot application which also creates bean for one of the classes of an external lib, this external java bean needs java.util.properties as one of the constructor parameter. Although I can use configurationPropeties with prefix to read properties from the spring boot loaded property file and convert it to java.util.properties.However, I don't want any additional prefix in the property file. is there any other way where I can convert the spring-boot loaded env or property source to java.util.properties
here is the code for reference
#Configuration
public class AppConfig {
#ConfigurationProperties(prefix = "some.prefix")
#Bean
public Properties getProperties() {
return new Properties();
}
#Bean
public ExternalClass externalClass() throws ConfigException {
return ExternalClass.getInstance(getProperties());
}
}
the above code work nicely, but I need to add an unnecessary prefix to the properties for conversion. could someone suggest any other approach apart from adding prefix to the propeties
Take a look at this documentation. It explains property binding techniques used in spring-boot.

How to configure intellij to find spring properties source

I'm looking for a way to follow source of spring configuration from annotation.
E.g. Having below Bean is any way to e.g. click on my-components-service.books.configurations and be redirect or list yaml files which contains config which would be injected in runtime?
#Bean
#ConfigurationProperties(prefix = "my-components-service.books.configurations")
Map<ComponentType, BooksConfiguration> booksConfiguration() {
return new HashMap<>();
}
If #ConfigurationProperties is at the class level then there should be some gutter icons that will show where the properties have been set.
It doesn't look like this works when it's specified on a #Bean like in your example however. A possible workaround is to use a nested #Configuration class, though that may be undesirable.

Removing PropertySourcesPlaceHolderConfigurer bean Autowiring doesn't work

What is the purpose of adding "PropertySourcesPlaceholderConfigurer" as a bean in spring? . As far as I researched it says when you name your property file as application.properties, spring will automatically take the file when it is in src/main/resources Folder. Having so, when I remove the Bean Declaration for PropertySourcesPlaceholderConfigurer, it says couldn't autowire the property.
What am I missing, Why isn't it working without PropertySourcesPlaceholderConfigurer
Sample 1:
#Configuration
#PropertySource(value = { "application.properties" }, ignoreResourceNotFound = true)
#ComponentScan(basePackages = { Some Package })
public class ApplicationConfig {
ApplicationConfig() {
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Sample 1 works fine, When I remove #PropertySources and #PropertySourcesPlaceholderConfigurer bean since spring will pick up application.properties automatically, it doesn't work.
it says when you name your property file as application.properties,
spring will automatically take the file when it is in
src/main/resources Folder
As I know - this is correct only for Spring Boot.
For spring core you should define you prps in contxet.
There are several ways.
In xml
< context:property-placeholder location="classpath:application.properties" />
or using Java annotation
#Configuration
#PropertySource("classpath:application.properties")
It's not necessary to define PropertySourcesPlaceholderConfigurer since Spring 4.3RC2

#refreshScope and #PropertySource how to?

Anybody know if #RefreshScope, applied to class for reloading properties/yml files dinamically works with a configuration class annotated only with #PropertySource?
I have to refresh an external configuration file, but i cant do something like :
#Bean
#RefreshScope
public FileProperties refreshListConfig() {
return new FileProperties(); //why ?
}
#Configuration //Configuration or new instance as above?
#PropertySource("file:${path.properties}")
#ConfigurationProperties(prefix="multitenancy")
public class FileProperties {
private List<DirProps> dir =new ArrayList<DirProps>();
private String tenantsFilePath;
..
class DirProps { ..}
...
}
I know that #RefreshScope doesn't work with #Configuration, but can I use #PropertySource without #Configuration?
Javadoc :
Annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment. To be used in conjunction with #Configuration classes.
So, can't i use #RefreshScope without move external properties in application properties and removing #PropertySource and #Configuration annotations from FileProperties class? Do you know if exists a working approach without move the properties?
Thanks

How to load a properties file based on the server environment with spring so that the values can be injected?

To my surprise I have had a difficult time finding an answer to this question. I have Seen many examples where you can use #PropertySource to load a specific properties file for a class. I have also seen examples where you can easily add different property files in spring boot projects. But what I want to do is to do this for a spring project that is NOT spring boot and load a properties file so that the values of this file can be injected in classes annotated with #Component which is dependent on the server environment. So for example if I am on development server I want a particular properties file loaded and on production a different properties file. The reason that I am doing it like this is because my data and service layers are their own modules. These modules contain their own unit tests and can be imported as their own modules in other spring boot projects. I need properties files to be loaded to serve these modules which use spring but not spring boot. I have tried the following, but this does not work.
#Configuration
#Profile("test")
#EnableJpaRepositories("com.hi.repository")
#EnableTransactionManagement
#EnableScheduling
public class InfrastructureConfig {
...
#Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
Map<String, String> env = System.getenv();
String propertiesFile=null;
String e = env.get("SERVER_ENV");
if (e.equals("dev")) {
propertiesFile = "environment/development.properties";
} else if (e.equals("prod")) {
propertiesFile = "environment/production.properties";
}
configurer.setLocation(new ClassPathResource(propertiesFile));
return configurer;
}
Then I have a test which looks like this
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:/spring/DealServiceTest-context.xml"})
#ActiveProfiles("test")
public class LogTest {
private static final Logger log = LogManager.getLogger(LogTest.class);
#Autowired
PathsService pathsService;
#Autowired
Environment environment;
#Test
public void testBeans(){
System.out.println("********** WASSUP from LogTest");
System.out.println(environment.getProperty("imageBucket"));
}
Although the test prints out null which indicates to me the properties file has not been loaded and prepared for its values to be injected. How can I achieve this?
You don't really need to set properties yourself, but you can do this using spring configuration. Check the documentation: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties
If you're using spring boot - all you need to do is create multiple properties file for your environments. And only for properties you need to override.
So your main properties file would be at
src/main/resources/application.properties
Production
src/main/resources/application-prod.properties
Development
src/main/resources/application-dev.properties
Testing
src/main/resources/application-test.properties
And then just use the profile name as your environment variable
java -jar -Dspring.profiles.active=prod demo-0.0.1-SNAPSHOT.jar
Actually, you can just use a placeholder in #PropertySource annotation.
See documentation:
Any ${...} placeholders present in a #PropertySource resource location will be resolved against the set of property sources already registered against the environment.
Assuming that placeholder is present in one of the property sources already registered, e.g. system properties or environment variables, the placeholder will be resolved to the corresponding value.
I've made a simple example, it receives a 'property.environment' value to choose, which .properties file should be used as property source. I have two resource files in my classpath - application-test.properties and application-dev.properties, each one contains a 'test.property' value ('test-env' and 'dev-env' respectively).
Property configuration:
#Configuration
#PropertySource("classpath:/config/application-${property.environment}.properties")
public class PropertyConfig {
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
return propertySourcesPlaceholderConfigurer;
}
}
Component with #Value
#Component
public class TestService {
#Value("${test.property}")
String testProperty;
#PostConstruct
void init() {
System.out.println("---------------------------------------------------------");
System.out.println("Running in " + testProperty + " environment");
System.out.println("---------------------------------------------------------");
}
}
Build command line example (it runs tests with test environment properties)
mvn clean install -DargLine="-Dproperty.environment=test"
Output
---------------------------------------------------------
Running in test-env environment
---------------------------------------------------------
Run command line example
java -jar -Dproperty.environment=dev PATH_TO_YOUR_JAR.jar
Output
---------------------------------------------------------
Running in dev-env environment
---------------------------------------------------------
Don't hard code based on different environment, in spring boot you can able to maintain properties specific environment easily. Refer https://spapas.github.io/2016/03/31/spring-boot-settings/
I would try to take advantage of the profile mechanism already in place in Spring. You basically have done the job yourself already, the only thing you need to change is to have different configurations for "test" and "production" profiles. I prefer to keep everything related to test away from production code (allowing me to place the TestConfig class below in the test source path), so I would probably do something like this:
#Configuration
#Profile("!test")
#PropertySource(value = "classpath:/environment/production.properties")
#Import(AppConfig.class)
public class ProductionConfig
{
// Your production-specific config goes here
}
#Configuration
#Profile("test")
#PropertySource(value = "classpath:/environment/development.properties")
#Import(AppConfig.class)
public class TestConfig
{
// Your test-specific config goes here
}
#Configuration
public class AppConfig
{
// Needed for spring to handle ${property:default} syntax
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigIn() {
return new PropertySourcesPlaceholderConfigurer();
}
}
If you prefer to have one config for both cases, you can let the AppConfig import the TestConfig and the ProductionConfig instead, but that will put test code in to production...
Good luck with your project!

Categories

Resources