This question already has answers here:
How to fill HashMap from java property file with Spring #Value
(8 answers)
Closed 2 years ago.
property file looks like this:
url1=path_to_binary1
url2=path_to_binary2
According this I tried following approach:
#Component
#EnableConfigurationProperties
public class ApplicationProperties {
private Map<String, String> pathMapper;
//get and set
}
and in another component I autowired ApplicationProperties:
#Autowired
private ApplicationProperties properties;
//inside some method:
properties.getPathMapper().get(appName);
produces NullPointerException.
How to correct it?
update
I have correct according user7757360 advice:
#Component
#EnableConfigurationProperties
#ConfigurationProperties(prefix="app")
public class ApplicationProperties {
and properties file:
app.url1=path_to_binary1
app.url2=path_to_binary2
Still doesn't work
Update 2
#Component
#EnableConfigurationProperties
#ConfigurationProperties(prefix="app")
public class ApplicationProperties {
private Map<String, String> app;
and inside application.properties:
app.url1=path_to_binary1
app.url2=path_to_binary2
Still doesn't work
it would be helpful if you can give a more specific example for property file. You should have the same prefix in the url1 and url2 and then you can use
#ConfigurationProperties(prefix="my")
as in
my.pathMapper.url1=path_to_binary1
my.pathMapper.url2=path_to_binary2
#Component
#EnableConfigurationProperties
#ConfigurationProperties(prefix="my")
public class ApplicationProperties {
private Map<String, String> pathMapper;
//get and set for pathMapper are important
}
see more at https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-loading-yaml
NullPointerException is probably from empty ApplicationProperties.
All custom properties should be annotated #ConfigurationProperties(prefix="custom").
After that, on your main class (class with main method) you must add #EnableConfigurationProperties(CustomProperties.class).
For autocomplete you can use:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
If you use #ConfigurationProperties without prefix you use only field name. Field name in you properites. In your case path-mapper, next you specific key and value. Example:
path-mapper.key=value
Remeber after changes in your own properites you need to reload application. Example:
https://github.com/kchrusciel/SpringPropertiesExample
There are two things need you need to feed map from properties file. First you need to have a class which has the configuration and target fields to hold data from properties file.
#Configuration
#PropertySource("classpath:myprops.properties")
#ConfigurationProperties("props")
#Component
public class Properties{
private Map<String,String> map = new HashMap<String,String>();
// getter setter
}
Secondly define the properties file named myprops.properties with all properties as props
props.map.port = 443
props.map.active = true
props.map.user = aUser
Have the your.properties file under src/main/resources and either have it as a
#Configuration
#PropertySource("classpath:your.properties")
public class SpringConfig(){}
or have it as a PropertyPlaceholderConfigurer in your Spring yourApplicationContext.xml.
Then use the property values like
#Value("app.url1")
String path_to_binary1;
#Value("app.url2")
String path_to_binary2;
// ...
System.out.println(path_to_binary1+path_to_binary2);
Related
I have a project that has two different runtimes in it (one a lambda and one a fargate). I have two different configs but only want one to run.
How do I exclude and include config classes? This didn't seem to work:
#SpringBootApplication(exclude = DynamoConfig.class)
And since they are in the same "path", I can't exclude just the package
com.cat.lakitu.runner
because the "persist" package will be excluded as well.
I would use the #ConditonalOnProperty annotation here on two configs, and add the properties in the main of one of the runtimes , take for example lambda (since you said each run uses a different one)
public static void main(String[] args) {
SpringApplication application = new SpringApplication(DemoApplication.class);
Properties properties = new Properties();
properties.put("lambda.application", "true");
application.setDefaultProperties(properties);
application.run(args);
}
then on the config needed when run time is lambda you can annotate the bean as such
#ConditionalOnProperty(
value="lambda.application",
havingValue = "true")
public class DyanmoConfig {
Then the other bean could have the following conditional properties
#ConditionalOnProperty(
value="lambda.application",
havingValue = "false",
matchIfMissing= true)
public class PersistConfig {
This way you only need to set the properties programatically in one of the two main's
There are different ways of solving this. Which one you choose depends on your specific use case and needs.
Using profiles: https://www.baeldung.com/spring-profiles
Example:
#Component
#Profile("runtime1")
public class DynamoConfig
Using conditional beans (multiple possibilities): https://reflectoring.io/spring-boot-conditionals/
#Component
#ConditionalOnProperty(
value="module.enabled",
havingValue = "true",
matchIfMissing = true)
public class DynamoConfig
I am new to Spring-bot and I need to add a configuration file inside the resources folder and read values from it.
Right now what I have done is that I have created a 'Configuration.properties' file in the classpath folder and have invoked the properties inside the program
FileReader reader=new FileReader("Configuration.properties");
Properties p=new Properties();
p.load(reader);
return p;
Can somebody please help how can i make it to call from the application.properties file of the spring-boot(or similar files) and thus make my configurations available inside the jar which I create.
PS: The Configurations i have given is project specific and am using them for avoiding the hardcoding inside the code.
Create application.properties file in the resource folder, spring boot will automatically find it.
Say you use these properties
test.stringProperty=will_be_used
test.integerProperty=42
stringProperty=not_used
You can then create a configuration properties class like so
import org.springframework.boot.context.properties.ConfigurationProperties;
#ConfigurationProperties(prefix = "test")
public static class TestProperties {
private String stringProperty;
private Integer integerProperty;
// getters and setters
}
and use it
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
#Configuration
#EnableConfigurationProperties(TestProperties.class)
public class TestConfiguration {
#Autowired
private TestProperties config;
// do whatever with properties
}
The autowired object will then have the values you specified in application.propertiesfile with the name 'prefix'.'name of the variable'.
Or you can use the
#Value("${stringProperty}")
private String value;
which is easier at first, but not very maintainable for higher number of properties.
You can use the #Value annotation to get the property file values.
Ex :
#Value("${rest_api_url}")
private String restApiUrl;
Need to define Property file as per requirement of your app.
You can use the #Value annotation in bean.
refer : Externalized Configuration and Properties and Configuration
Create a file in resource folder by the name application.properties which will be taken automatically as the default property file.
If you want to specify some other file as a property, do the below-mentioned changes.
Snippet :
#SpringBootApplication
#ImportResource("classpath:filename.properties")
public class Example{
public static void main(String[] args) {
SpringApplication.run(Example.class, args);
}
}
I have a properties file called xyz.properties. Right now, I am able to load individual property of this file in my class annotated with #Component which is working perfectly fine.
However, I am thinking of making my project more modular, for which I need to read the whole xyz.properties file as one properties object so that i can pass it along. How can I do so ?
Update
Right now, I am loading individual property from the file like this
my applicationContext.xml has following entry
<context:property-placeholder location="classpath:xyz.properties" order="2" ignore-unresolvable="true"/>
and then i have the respective class as
#Component
public class XyzConfiguration {
#Value("${client.id}")
private String clientId;
#Value("${client.secret}")
private String clientSecret;
...
}
What I mean by pass it along
Right now, for each individual property I have to create a respective field in a class and then annotate it with respective property name. By doing so, I am making my nested module very spring framework specific. I might someday put this module on github for others as well and they may or may not use spring framework. For them it would be easier to create an object of this module by passing required parameters (ideally in case of a Properties object) so that my module will fetch the properties by itself.
You can try below code.
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.io.ResourceLoader;
import java.util.Properties;
private String fileLocator;
private Properties prop;
private ResourceLoader resourceLoader;
public void init() throws IOException {
//"fileLocator" must be set as a path of file.
final Resource resource = resourceLoader.getResource(fileLocator);
prop = PropertiesLoaderUtils.loadProperties(resource);
}
prop will have all values from your property file and then you can get any value by calling prop.getProperty() method.
I have a simple web-app that includes a dependency jar for some functionality and needs to use a property value defined in main app code.
Thanks in advance to help me out on this.
dependency.jar contains
public class MyClass {
#Value("${abc.def}")
private String abc; // DOES NOT GET RESOLVED. IS ALWAYS NULL
}
dependency-context.xml
my-app.war contains
public class LocalClass {
#Value("${abc.def}")
private String abc; // GETS RESOLVED TO CORRECT PROPERTY VALUE
}
context.xml
imports dependency-context.xml
You may be running into this bug. It makes it very difficult to use the #Value with multiple PropertyPlaceholderConfigurers from different projects using import context. To solve this problem try to autowire the existing PropertyPlaceholderConfigurer into your bean configuration method (assuming you can use #Configuration) and update the object in the method with the values from your project.
#scottmf is on the right lines, but you can't read properties directly from PropertyPlaceholderConfigurer :(
Instead, I created a String #Bean in the war...
<bean id="myProperty" class="java.lang.String">
<constructor-arg value="ABC"/>
</bean>
which can be #Autowired into the jar class:
#Bean
public Object myBean(String myProperty) { ... }
I have a properties file myprops.properties as follows:
Wsdl=someurl
UserName=user
UserPassword=pasword
Application=appName
And inside my controller I'm trying to access to set values in my service as follows
Properties prop = new Properties();
prop.load(new FileInputStream("resources/myprops.properties"));
myService.setWsdl(prop.getProperty("Wsdl"));
myService.setUserName(prop.getProperty("UserName"));
myService.setUserPassword(prop.getProperty("UserPassword"));
myService.setApplication(prop.getProperty("Application"));
my Issue is I just do not know what path to use. Its a Spring project if that makes any difference. and Idealy I would like to have the properties file in my "src/main/resources" folder
I realise this may be very simple to some but I have tried searching for the solution both here and on Google and I cannot seem to find a solution that has helped. I've tried moving the file around the project but cannot seem to figure it out
The Error I get is
java.io.FileNotFoundException: resources\drm.properties (The system cannot find the path specified)
any advice/explanation or even a link that clearly explains it would be great
well, src/main/resources are on the classpath, you just need to do.
Properties properties = PropertiesLoaderUtils.loadAllProperties("your properties file name");
If you are using spring, you could set your property placeholder.
<context:property-placeholder location="classpath:resources/myprops.properties" />
and in your beans you can inject the values from the properteis using the #Value annotation
#Autowired
public Foo(#Value("${Wsdl}") String wsdl) {
...
}
in the case above I used in the constructor, but its possible to use by Autowired field/setter.
So in your service you could have something like:
#Service
public class MyService {
private final String wsdl;
private final String username;
private final String password;
private final String application;
#Autowired
public MyService(
#Value("${Wsdl}") String wsdl,
#Value("${UserName}") String username,
#Value("${UserPassword}") String password,
#Value("${Application}") String application
) {
// set it to each field.
}
}
Given that src/main/resources is on the classpath, you could do:
Resource resource = new ClassPathResource("/myprops.properties");
Properties props = PropertiesLoaderUtils.loadProperties(resource);
Don't use a FileInputStream; use getResourceAsStream() to read it from the servlet context.
You can always count on mkyong. This is an example/tutorial on how to load and read property files.
http://www.mkyong.com/java/java-properties-file-examples/
This question should be marked as a duplicate:
Loading a properties file from Java package
How to use Java property files?
Load a property file in Java
Java Properties File not loading
Java NullPointerException on loading properties file
Not able to load properties file in Java