property-placeholder location from another property (Spring 3.1) - java

I need to load an environment-specific property file, and I'd like to be able to both set it from the JVM (using -D) and to provide a default value in the main properties file or, failing that, somewhere else (like the applicationContext.xml)
I'm using the new hotness Spring 3.1 with its unified property management, but I can't find a lot of info on the property system.
UPDATE:
To clarify:
<context:property-placeholder location="/WEB-INF/myapp.properties,
/WEB-INF/myapp-${deploy.env}.properties"/>

You can do it using Spring 3.1, JVM property will be put into placeholders and you can define default values using ":", for example:
${property1:defValue}
where defValue is default value, it can be overridden by JVM option -Dproperty1=newValue

You should read this API - it is pretty informative. Example here.
EDIT
As the example points to outdated version of Spring the more modern approach is illustrated here

Related

Injecting JVM params into spring property files

In short - is there a way to set the value of spring properties to what's been set as a JVM arg? E.g. I have a netflix turbine cluster which needs the following property set:
turbine.aggregator.clusterConfig=myCluster
Is it possible to a way of setting a JVM param as
-DturbineCluster=myCluster
and then in the property file setting:
turbine.aggregator.clusterConfig=${turbineCluster}
I did actually try this and it didn't work. Can this be done from a property file or does this kind of thing need to be done programatically?
(Apologies if this has been asked before - had a quick search and couldn't find anything.)
You can do this easily in spring boot, it may be supported by spring as well
-Dspring.application.json='{"turbine.aggregator.clusterConfig":"myCluster"}'
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Get list of Spring property placeholder and their resolved values

I would like to make all property placeholder and their resolved values of a running Spring (Boot) application available for process monitoring. In the first step this could be just by writing them to the logs or by creating a 'resolved.properties' file similar to the application.pid file.
All properties where property placeholder are used (implicit/explicit) should be considered.
Motivation: It is usually hard during operation to know the values of resolved properties. System properties or command line arguments are "visible" but e.g. hidden default values in the code (like #Value("${timeout:30000}")) are hard to find out. I would like to be able to answer the question "How does the configuration of the running application looks like?" in a generic way that I can use in all of my spring applications.
I know about the Spring Boot Actuator /configprops endpoint, but this only includes #ConfigurationProperties. I would like to get a list of all properties where placeholder are used.
The requirement does not seem to be new (see here or here) but I wonder if there is an appropriate (bootiful) way nowadays.
There is (currently) no way to obtain all the properties in the Environment abstraction. This is intentional as can be read here. This is also why it isn't possible to obtain all the values used for resolution.
The values and resolutions are logged at runtime telling which key was resolved from where at runtime. But that logging is quite verbose and logged each time a StringValueResolver is used.
You might get a partial result by providing your own customized PropertySourcesPlaceholderConfigurer which maintains a collection of resolved key/value pairs. But not every resolution uses the PropertySourcesPlaceholderConfigurer some directly use a StringValueResolver implementation bypassing the PropertySourcesPlaceholderConfigurer.
It doesn't cover all your needs (ie: properties from all files, default values, application arguments, etc.).
I'll still keep the answer for other readers/future reference.
Spring Boot's Actuator /env endpoint
You may use the /env endpoint. It lists a bunch of stuff but it also includes the content of application.properties (near the end):
applicationConfig: [classpath:/application.properties]={myproperty=blah, server.port=8080}

How to set contextName of log4j2 Mbean

While accessing log4j2 Mbeans using jvisualvm, I see that the type (contextName) inside log4j2 package is a number (for me it is 1482868390). Since this goes in as 'type' while specifying Object in query, I would like to specify it to a more recognizable name that I prefer. Is there a way to set the contextName in xml configuration.
I think there is a way to do it for web applications, but I would like to set this for a standalone java application.
Yes this is possible but not in configuration. You can achieve this by subclassing one of Log4j's ContextSelectors and overriding its defaultContextName() method.
You then tell Log4j to use your ContextSelector by starting your application with system property -DLog4jContextSelector=com.yourpackage.YourContextSelector.
If you're making all loggers async, you want to subclass AsyncLoggerContextSelector, otherwise ClassLoaderContextSelector.

Where is ${SHDP_AMSERVICE_PORT} for DefaultMindAppmasterServiceClient defined?

In the YARN Documentation, Section 11.12.2 Partitioning on Configuring Container the
DefaultMindAppmasterServiceClient is setup by the following:
<yarn-int:amservice-client
service-impl="org.springframework.yarn.integration.ip.mind.DefaultMindAppmasterServiceClient"
host="${SHDP_AMSERVICE_HOST}"
port="${SHDP_AMSERVICE_PORT}" />
How is the port SHDP_AMSERVICE_PORT defined for the amservice?
Your link includes this,
Through Spring's property placeholder support, SpEL and the environment abstraction (available in Spring 3.1). one can externalize environment specific properties from the main code base easing the deployment across multiple machines.
It also mentions support for Properties files. But it appears that it supports environment variables. On *nix type systems you might define it like
export SHDP_AMSERVICE_PORT=1234 # for example
On Windows that would look like
set SHDP_AMSERVICE_PORT 1234
Edit
Based on your comment I downloaded it and it's used in container-context.xml under
yarn/yarn/custom-amservice/src/main/resources/container-context.xml
yarn/yarn/batch-files/src/main/resources/container-context.xml
yarn/yarn/batch-partition/src/main/resources/container-context.xml
Nothing defines it, so it uses a default value. You can override it as above.

Pass properties to log4j before it loads

Is there a way to pass data or setting to log4j before it loads and then use that property within the config file.
I was assuming there is a system properties I could use:
log4j.appender.R.File=/usr/local/pfs/logs/${ws.host}/log4j.log
Where ws.host is the property I want to use.
But how can I set that value?
Also, I am in a web environment. How can I know at what point to set the property setting before log4j loads.
The default log4j PropertiesConfigurator supports variable substitution.
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PropertyConfigurator.html
So, you could pass system properties like this "-DmyProject.logFile="/temp/test.log" to your Java startup, and then in the properties files have "log4j.appender.R.File=${myProject.logFile}".
If working from a web environment, you might want to check out Spring's Log4jConfigListener. It uses a listener (Servlet API 2.4+) to initialization log4j ahead of other components. Even if not using Spring, you should be able to use the source as an example to easily create your own listener.

Categories

Resources