I have a Spring Boot Application, which have a connection to a MongoDB database.
The connection I can configurate in the server.properties.
For the current development I can use the localhost.
But for the later server implementation, I need configurate a new server.properties.
How I can change it, if I start the programm, please use the development.server.properties or the consumer.server.properties with different server connection?
Option 1:
For most real word applications, the properties are not directly packaged with the sources as it can contain sensible info (database password for instance). A simple solution to this, is to put application properties on filesystem and then reference them with the spring.config.location argument
java java -jar demo-0.0.1-SNAPSHOT.jar -Dspring.config.location=/etc/demo/application.properties
this way you keep application.properties away of the packaged jar and you can parse and subsitute values into the application.properties file with your deployment toolchain (like ansible) for each environment accordingly.
some useful doc can be found here: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Option 2:
use profiles. In classpath resources you can have a main application.properties which stores the properties which are common for all environments and then one application-{env}.properties for each environment with specific keys e.g application-dev.properties, application-int.properties, application-prod.properties...
At startup you specify the active profile with then environment variable spring.profiles.active :
java -jar -Dspring.profiles.active=prod demo-0.0.1-SNAPSHOT.jar
Related
I need two application.properties in my Spring Boot App.
I know that using the annotation #PropertySource I can specify more than 1 property files.
I tried to use: #PropertySource({"classpath:application.properties","classpath:external.properties"})
The idea of it is having application.properties with the machine independent properties and this file will be included inside the war file.
The other file (external.properties), will leave in the machine, and won't be included in the war file. Here I want to leave properties like the database connection and so on.
I've already changed catalina.properties for adding the external.properties location into the classpath, but unfortunately when running on Eclipse it doesn't work (complains about the missing database properties.).
If the external properties file will be available in a known location on the machine, then have an environment variable, system property, or command-line argument set up with the path to the file. Then, reference the file in you #PropertySource annotation using file: rather than classpath:
Example: #PropertySource("file:${CONF_DIR}/external.properties")
References:
Spring boot docs on external configuration
PropertySource documentation
Blog post regarding PropertySource
In my project I have seperate application.yml files for each environments, inside each folder for an environment.
NOTE: Below red color yml file made temporarily, to make the code work. But should remove this after fixing. So what I want is to use separate application.yml file according to environment. Specially I need to use local/application.yml for local development
Below has an example of getting env variables in my project
#Component
#Configuration
public class ApplicationProperties {
#Value("${ex.my.url}")
private String myServiceUrl;
// getters setters and nedded stuff
}
But it doesn't work, since could not find a way to mention the needed environment. Because it is in a seperate folder. All the other examples mention the way to get the yml file inside resource folder, without seperate folders.
Any fix for the issue?
in my projects, I specify a profile with the VM option :
-Dspring.profiles.active=local
Then I have a file named application-local.yml
in production :
-Dspring.profiles.active=prod , will use the file application-prod.yml
In the resources folder
Do make file of application.yml, application-local.yml, application-dev.yml etc.. what ever you want
and then in application.yml
spring.profile.active = ${ENV}
now during the run specify the ENV variables from run/debug configuration under Intellij or mention the profile for which you want to build the jar in application.yml.
Alternative, you can use the -D spring.profile.active=dev
at-first, from the documentation:
SpringApplication loads properties from application.properties files in the following locations and adds them to the Spring Environment:
A /config subdirectory of the current directory
The current directory
A classpath /config package
The classpath root
So, with passed directory hierarchy you'll get problems.
at-second, for file specification, you could use Profiles. This works as follows:
if no specified profiles - application.properties would be used
for any additional profile also would be used profile with name application-<name>.properties
Thus, if you specify dev and cool profiles, properties application.properties, application-dev.properties, `application-cool.properties, would be in use
UPDATE:
You could pass spring.config.location for property file path specify, but if you want directory hierarchy as you have - you need some customizations using context.initializers.classes and ApplicationContextInitializer
The classic solution is to setup one config file
(I prefer properties because I'm sane)
and allow for an overrides file to be placed on each installed host.
Spring supports this out-of-the-box.
Here is an example:
public static void main(final String[] argumentArray)
{
final StringApplicationBuilder springApplicationBuilder;
springApplicationBuilder = new SpringApplicationBuilder(YourSpringBootApplication.class)
springApplicationBuilder.properties(
"spring.config.location=classpath:/yourConfig.properties,/some/path/to/overrides/directory/yourConfig.properties");
springApplicationBuilder.build().run(argumentArray);
}
I am new with Maven/SpringBoot and trying to deploy a repository with different Tomcat Server port.
By default, I would be happy to run tomcat on :8080. But today, I wanted to add Jenkins pipelines to my project and I deployed tomcat on :8080 (with jenkins on it) before my spring cloud gateway repository.
Now, once I try to deploy gateway, compiler obviously says address :8080 already in use.
Now, I want my gateway to deploy Tomcat on another port, (or use already-existing tomcat on :8080 if possible?) so I wanted to deploy it using this command:
$ mvn spring-boot:run -Dserver.port=8181
However, same error based on :8080 happens to appear:
[ERROR] Failed to execute goal
org.springframework.boot:spring-boot-maven-plugin:1.5.8.RELEASE:run
(default-cli) on project crw-gateway: An exception occurred while
running. null: InvocationTargetException: Connector configured to
listen on port 8080 failed to start.
I tried putting server.port=8080 to application.properties or application-dev.properties files but I cant override it.
Any ideas? How can I override the port? Is there a possibility that I can use already existing tomcat-server on :8080?
Thank you for your time!
EDIT: I had my configurations under ~/config folder. There, I had gateway.properties, which included the line server.port=8080. It has overridden the command line interface as the accepted answer asserts. Changing it to 8888 worked.
According to Spring Boot documentation :
Spring Boot uses a very particular PropertySource order that is designed to allow sensible overriding of values. Properties are
considered in the following order:
Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
#TestPropertySource annotations on your tests.
#SpringBootTest#properties annotation attribute on your tests.
Command line arguments.
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
ServletConfig init parameters.
ServletContext init parameters.
JNDI attributes from java:comp/env.
Java System properties (System.getProperties()).
OS environment variables.
A RandomValuePropertySource that has properties only in random.*.
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
Application properties outside of your packaged jar (application.properties and YAML variants).
Application properties packaged inside your jar (application.properties and YAML variants).
#PropertySource annotations on your #Configuration classes.
Default properties (specified by setting SpringApplication.setDefaultProperties).
So your problem is that your command line (4.) can not override the application.properties file configuration (13., 14., 15.).
If you want to override the server.port property, you need to ensure to respect this order in your configuration.
We are using a spring boot application, where properties are loaded from application.yml file instead of application.properties, located at src/main/resources/ which looks like below:
config:
host: localhost:8080
server: 123
And they are being pulled in a .java file like this
#ConfigurationProperties( prefix="config")
public class ConnectionImpl implements Connection{
#Value("${config.host}")
private Stringhost;
}
I am able to retrieve properties this way.
But we are trying to move the config properties from application.yml to a different .yml file which is located at a different location. (src/main/resources/env-config).
Now I am not able to retrieve properties same way, i.e, using #Value annotation. Is there any other annotation I need to add ?
From the documentation:
SpringApplication will load properties from application.properties (or application.yml) files in the following locations and add them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The class path root
If you don’t like application.properties as the configuration file name you can switch to another by specifying a spring.config.name environment property. You can also refer to an explicit location using the spring.config.location environment property (comma-separated list of directory locations, or file paths).
The default search path classpath:,classpath:/config,file:,file:config/ is always used, irrespective of the value of spring.config.location. This search path is ordered from lowest to highest precedence (file:config/ wins). If you do specify your own locations, they take precedence over all of the default locations and use the same lowest to highest precedence ordering. In that way you can set up default values for your application in application.properties (or whatever other basename you choose with spring.config.name) and override it at runtime with a different file, keeping the defaults.
You need to supply a command line argument that tells SpringApplication where specifically to look. If everything in resources/ is added to the classpath root, then your command line would look like:
java -jar myproject.jar --Dspring.config.location=classpath:/env-config/service-config.yml
If you have a general application.yml under resources/, the properties in there will still be loaded but will take a lower precedence to the properties file specified on the command line.
Your question doesn't really say what you intend to do, but if you want to have a different configuration for different environments (e.g. development, test, production), there is a simple solution for that.
Place your config files in a file hierarchy like this inside your project:
src/
main/
resources/
application.yml
application-development.yml
application-test.yml
application-production.yml
When you now start your application with
java -jar mySpringApplication.jar -Dspring.profiles.active=development
the configuration from application.yml will be taken as a "base layer", overridden by the configuration in application-development.yml. By this, you can have "default" settings for all environments in application.yml and environment-specific configuration in the application-ENV.yml files. The same works for test and production.
No.
You'll be in a much better position if you avoid hard-coding file path like that within your code base. #ConfigurationProperties used to have a locations attribute but it's deprecated and already removed in 1.5.
In Spring Boot, you configure the Environment which is a single source of truth for your configuration. Rather than having settings buried in code, you should configure Spring Boot to read the files that you want. Read the documentation for spring.config.location. If you want to do this in a more transparent manner, perhaps EnvironmentPostProcessor is what you need
I have several java projects which use hibernate to persist to a DB. At the moment, I have hibernate.properties file embedded in one persistence project.
However, I would like to be able to specify to have two different files one for prod and one for dev.
What is the best practise....should I embed the config files into my jars? How do I build my projects to use the correct properties with Maven?
Thanks.
You probably want to have the key database properties (name/user/password) set as properties at runtime either from a properties file that's itself specified as a property (the URL of the file can be specified as a property) or a set of properties (a property for each of name/user/password). The former is probably the preferred approach.
You could ask your system/database administrator type what they like :)