How can I access 'spring.application.name' when defined in bootstrap.properties? - java

I have the following spring-boot 1.4.2.RELEASE sample app
#SpringBootApplication
public class Application {
#Value("${spring.application.name}")
private String applicationName;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
And I have the following configuration defined in bootstrap.properties:
spring.application.name=sample-app
When run it I get the following error:
java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.application.name' in string value "${spring.application.name}"
Any hint on why it fails to inject 'spring.application.name'?
Need to define it there to support other spring boot cloud.

The first answer is correct. The default properties file is application.properties or application.yml.
The bootstrap file is properly for Spring Cloud.
See http://projects.spring.io/spring-cloud/spring-cloud.html#_the_bootstrap_application_context
If you are using spring cloud, and the bootstrap file is not working, you need to enable the "cloud" Spring profile.
For example using:
./gradlew -Dspring.profiles.active=cloud bootrun
or
./mvnw spring-boot:run -Dspring.profiles.active=cloud

By default, if you don't specify any properties source, spring boot will lookup for your property in the file application.properties. Therefore, you should rename your property file to that default name or manually specify a properties source for your bootstrap.properties

Related

Automatization Spring Cloud Profile

Actually have a little problem.
I want switch the url of my bootstrap.yml
It looks as follows:
spring:
application:
name: <project-name>
profiles:
active: dev
cloud:
config:
uri: http://<git-repository>:8080
fail-fast: false
This works, but i want have an propertie or anything what can switch if are in local or another enviroment.
I try to see this documentation but dont see any work for me.
I don't think Spring Cloud is any different from any Spring application, so you could use the Spring profiles.
Something similar is suggested on this answer: https://stackoverflow.com/a/22759706/6908551.
You could define a separate .yml file just for your cloud config uri, like cloud-config-dev.yml, cloud-config-prod.yml. Then, for a Java config, you could have something like:
#Configuration
public class MyApplicationConfiguration {
#Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
String activeProfile = System.getProperty("spring.profiles.active", "production");
String ymlFilename = "cloud-config-" + activeProfile + ".yml";
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocation(new ClassPathResource(ymlFilename));
return configurer;
}
}
I would define a bootstrap.yml file by environment.
Define a default bootstrap.yml in src/main/resources and define a specific bootstrap.yml file for each environment.
Then there are multiple ways.
Not exhaustive :
1) For each environment where the configuration file differs, run your spring boot jar by specifying the system property spring.cloud.bootstrap.location with the expected value such as :
java -jar ... -Dspring.cloud.bootstrap.location=bootstrap-dev.yml ....
That overrides the current location of that file.
2) Take advantage of Spring Boot profile feature : bootstrap.yml is compatible with. For example if the dev profile is enabled, the bootstrap-dev.properties in the classpath will be used.
I tend to use the first way because that is more explicit for non Spring Boot users.
Source : 1.3 Changing the Location of Bootstrap Properties

Spring boot application start without proper application name

When running
./mvnw spring-boot:run
current spring boot application can open in the browser with current URL
http://localhost:8080/
but not
http://localhost:8080/AppName
So even in Swagger the APIs has to retrieve like this
http://localhost:8080/api/swagger.json
instead of this
http://localhost:8080/AppName/api/swagger.json
So how to add the AppName in the context? Easy in the old days where web.xml is xml based, in java based config I have add
spring.application.name=AppName
but still don't resolve the issue.
So how to add the AppName in the context?
Spring Boot, by default, serves content on the root context path (“/”), But we can change it in different ways.
1) Using application.properties / yml
For Boot 1.x, the property is server.context-path=/AppName
For Boot 2.x, the property is server.servlet.context-path=/AppName
2) Using Java system property
public static void main(String[] args) {
System.setProperty("server.servlet.context-path", "/AppName");
SpringApplication.run(Application.class, args);
}
3) Using OS Environment Variable
On Linux:- $ export SERVER_SERVLET_CONTEXT_PATH=/AppName
On Windows:- set SERVER_SERVLET_CONTEXT_PATH=/AppName
4) Using Command Line Arguments
$ java -jar app.jar --server.servlet.context-path=/AppName
5) Using Java Config
With Spring Boot 2, we can use WebServerFactoryCustomizer:
#Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
webServerFactoryCustomizer() {
return factory -> factory.setContextPath("/AppName");
}
With Spring Boot 1, we can create an instance of EmbeddedServletContainerCustomizer:
#Bean
public EmbeddedServletContainerCustomizer
embeddedServletContainerCustomizer() {
return container -> container.setContextPath("/AppName");
}
Note:- Priority order in descending order, which Spring Boot uses to select the effective configuration:
Java Config
Command Line Arguments
Java System Properties
OS Environment Variables
application.properties in Current Directory
application.properties in the classpath (src/main/resources or the packaged jar file)
Set the context path
Spring Boot 1.x: server.contextPath=/AppName
Spring Boot 2.x: server.servlet.contextPath=/AppName
You should use
server.servlet.context-path for Spring Boot 2.x
server.context-path for Spring 1.x
in your application.properties file.
Add the following line in your application.properties (works with Spring Boot 1.x):
server.contextPath=/AppName
if your version is 2.x, the use the following:
server.servlet.contextPath=/AppName

Unable to read application.properties in spring boot application

I am unable to read application.properties value in my project in classes that are injected as a bean from another project. My project is using another project which has classes which needs to read configuration from application.properties.
Mine is a maven project and a spring boot application having application.properties in src/main/resources folder and those properties values are defined in it.
What is it that I am missing that it is unable to read file values? Or is there is any other mechanism for setting these properties for classes loaded via component-scan
Below line of code works fine, it is able to read value from the application.properties:
#PostConstruct
void init() throws ClassNotFoundException, IOException {
System.out.println(context.getEnvironment().getProperty("env.host",
"default value"));
}
Now there is another project which I am using in mine. When loading the classes those beans are getting initialized as dependency of another class, there also it tries to read same value in constants file as
static final String HOST_PROPERTY = "${env.host}";
There this value is not getting initialized to value from applictaion.properties
If you want to get application.properties values,you have to two option.
1) you can autowire Environment class and use its getProperty() method as
#Autowired
Environment env;
env.getProperty("${env.host}");
2)#Value annotation
#Value("${env.host}")
String HOST_PROPERTY;

spring autoconfiguration class is missing in META-INF/spring.factories

I'm trying to create spring based application but after the build i'm getting exception while initializing the spring context -> No auto configuration classes found in META-INF/spring.factories.
I'm working heavily with spark in my application and i'm forced to use maven-assembly-plugin to package my jar (otherwise i'm unable to run spark job).
sample of my main class:
#SpringBootApplication
#EnableAutoConfiguration
public class MyMainClass {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(MyMainClass.class).web(false)
.run(args);
SparkJob job = ctx.getBean(SparkJob.class);
job.prepareJobAndRun();
ctx.close();
}
}
when i add
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mypackage.MyMainClass
everything works as expected, but i don't want to add them manually.
Any chance to make this work without the spring-boot-maven-plugin?
I was able to found out, that you can add your own META-INF/spring.factories to src/main/resources. This custom spring.factories will be then packed to jar. Tested, working.

What is the difference between spring cloud config server exec.jar and .jar suffix

We are currently using spring cloud config server spring-cloud-config-server-1.1.0.M2-exec.jar and would like to upgrade to the latest version. However, i've noticed that beyond 1.1.0.M2 version there's only standard jars and no exec.jar in Maven repo http://maven.springframework.org/milestone/org/springframework/cloud/spring-cloud-config-server/
Could someone please explain what the difference is? Will I be able to just substitute the exec one with the standard non exec one?
Thanks
The exec jar contains an executable version of the config server (as a Spring Boot application). The non-exec jar contains only the config server classes. So you can't just replace the exec jar with the other one. What you basically have to do is to create a basic Spring Boot application with the config server dependencies and the appropriate annotations (like in the example):
#SpringBootApplication
#EnableDiscoveryClient
#EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}

Categories

Resources