Where does Spring EL wiring value from - spring

All:
I wonder how to find where does a spEL value located?
Such as :
<property name="jdbcUrl" value="jdbc:sybase:Tds:${brs.dsread}" />
I check all *.properties file in the eclipse project, but there is no definition. Other than those properties file, where else can I look for it?
Thanks

This is not SpEL it's a simple Property Placeholder.
It could be anywhere on the classpath (e.g. in a jar).
Turn on DEBUG logging for org.springframework to figure out where it comes from.

Related

Spring: exclude some properties files from context

suppose we have some jars with properties files with the same key/values.
configA.jar:
log4j.A.properties
configB.jar:
log4j.B.properties
The problem: Spring mixes values from the both properties files. So, how to exclude log4j.A.properties from the context and process only log4j.B.properties?
UPDATE (added some stuff): there is a maven build which produces two jars mentioned above. Here in webapp (applicationContext.xml) following setup:
<util:properties id="propertyConfigurer" location="classpath:common.properties,classpath*:edrive.properties,classpath*:job.properties,classpath*:log4j.B.properties"/>
After the startup Spring mixes both jars and takes random (or the last one) jar and it's log4j.properties. But we need only the log4j.B.properties. How to do that?
try adding the config file to be used in your properties file
logging.config=log4j.B.properties
I resolved the issue by myself. I've upgraded logging facility to Log4j2 with following configuration:
log4j2.component.properties in classpath:
log4j.configurationFile=classpath:log4j2.web.xml
That's it.

How to load a secret.properties file in apacheignite/docker stock image

I used gridgain’s webconsole to create a configuration file for my ignite node (ignite-config.xml). I’d like to see if I can get this running in apache’s docker ignite image (apacheignite/ignite). I’ve created a volume in my compose file that maps to a config folder that houses my ignite-config.xml.
I need to include the secret.properties (that has my jdbc url/username/password) file as well so I put it in the config folder too.
When I do a docker-compose up I get a java.io.FileNotFoundException: class path resource [config/secret.properties] cannot be opened because it does not exist]
This is the part of the xml config that deals with the secret.properties location:
<!-- Load external properties file. -->
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:secret.properties"/>
</bean>
What do I need to change so that the secret.properties file in the config folder is loaded? Is there a better way to do this?
I do not know how to easily deploy the secret.properties file without going through a full build and deploy, but in order to get past that for testing purposes, you could get rid of the secret.properties and use environment variables instead.
Which might look something like this for a JDBC connection to Postgres:
<!-- Data source beans will be initialized from external properties file. -->
<bean id="dsPostgreSQL_Daifcqkp30zkdj" class="org.postgresql.ds.PGPoolingDataSource">
<property name="url" value="#{systemEnvironment['dsPostgreSQL_Daifcqkp30zkdj_jdbc_url']}"/>
<property name="user" value="#{systemEnvironment['dsPostgreSQL_Daifcqkp30zkdj_jdbc_username']}"/>
<property name="password" value="#{systemEnvironment['dsPostgreSQL_Daifcqkp30zkdj_jdbc_password']}"/>
</bean>
Then, just set your environment variables:
IGNITE_VERSION=2.7.5
CONFIG_URI=https://raw.github.com/some/path/to/your/config.xml
OPTION_LIBS=ignite-zookeeper,ignite-rest-http
EXTERNAL_LIBS=https://github.com/some/path/to/your/jdbc-drivers/postgresql-42.2.6.jar?raw=true
dsPostgreSQL_Daifcqkp30zkdj_jdbc_username=0a9suf09asdfkjwel
dsPostgreSQL_Daifcqkp30zkdj_jdbc_password=8faskdfn94noiasnf09_s09fklajfealk
dsPostgreSQL_Daifcqkp30zkdj_jdbc_url=jdbc:postgresql://<host>:<port>/Daifcqkp30zkdj?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory
Had the same issue, probably didn't resolve it the "correct" way (whatever that is), but resolved it this way for a POC nonetheless:
Create a standalone jar file with only the secrets file
Give it the name dsPostgreSQL_Daifcqkp30zkdj_jdbc.jar or similar
Place the jar file in the libs directory
It seems the classpath is just the contents of all JAR files in the \libs subdir, so oblige it... This would have the advantage of allowing for a signed JAR - I believe - which would (in addition to file system permissions, visibility, etc.) at least ensure it isn't tampered with.

where spring defines variable value, which is referred by some xml file

I am trying to understand from where does the value of a variable comes from, when it is referred in Spring xml file.
For example:
<context:property-placeholder location="classpath:/${com.example.deploy.environment}/com.example.config/mysql.properties" ignore-resource-not-found="false" />
Where is the value of com.example.deploy.environment defined? In my project I searched all over, however i couldn't find anywhere where this values is defined.
Any information in understanding this would be of great help.
This value can come from a variety of source:
application.properties file which you can define in PropertyPlaceholderConfigurer bean.
<bean id="mailProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:application.properties" />
</bean>
...
//Inside application.properties
com.example.deploy.environment=prod
You can provide via command-line:
With Maven vm arguments for JVM System property:
mvn package -Dcom.example.deploy.environment=prod
Running Spring Boot Application:
java -jar app.jar --com.example.deploy.environment="prod"
From System Environment variable of the Operating System. You might have to restart after setting environment variable. See below for windows:
Refer this doc and this article for more info.

Spring how to load file path of a text file in spring property file

This might be an extremely simple question but I'm really new to spring framework and am just getting my feet wet. I am trying to specify a text file property as part of a bean, the value for which I am specifying from a properties file.
The relevant code is as follows in context.xml file
<bean id="myAssembler"
class="com.pkg.search.myclass.collector.assembler.myAssembler">
<property name="popularUrlsFileName" value="${POPULAR_URLS_FILE}"/>
</bean>
The POPULAR_URLS_FILE is specified in a .properties file as :
POPULAR_URLS_FILE="README.md"
But I am getting an error in the xml file as it says it can't find the file with README.md path. What exactly are we supposed to specify as far as the path is concerned for it to find the text file?
Exact error is "Cannot Resolve File README.md"
Any help would be much appreciated. Thanks in advance!
You have two options, if the file is on the classpath than
POPULAR_URLS_FILE="classpath:path/to/README.md"
or, if not on the classpath, use the file URL syntax
POPULAR_URLS_FILE="file:path/to/README.md"

Can I default a system property for a constructor-arg in a spring config file?

I have a spring config file which includes the following elements:
<context:property-placeholder location="classpath:default.properties"/>
<bean id="theVar" class="java.lang.String">
<constructor-arg value="${varName}"/>
</bean>
"varName" is now moved from the properties file to a system property. It is being added when I start a Maven build:
mvn clean install -DvarName=data
I want to also run my build without specifying varName:
mvn clean install
Is there some way to default varName in my spring config? Though this does not work, a conceptual example of what I am looking for is:
<bean id="theVar" class="java.lang.String">
<constructor-arg value="${varName}" default="theDefaultValue"/>
</bean>
Spring 3.0.x supports a syntax like this:
value="${varName:defaultValue}"
References:
SPR-4785
Changes in version 3.0.0.RC1 (2009-09-25) (PropertyPlaceholderConfigurer supports "${myKey:myDefaultValue}" defaulting syntax)
It turns out that in spring v2.5+, if there is a system property defined, it can be used instead of a property defined in the properties file. You just need to ensure the same name is used and that the 'override' option is enabled.
For example, given:
<!-- my spring config file -->
<context:property-placeholder location="classpath:default.properties" system-properties-mode="OVERRIDE"/>
And:
# default.properties file
theVariable=One
When I execute:
mvn clean install
"One" is picked-up for theVariable. If I execute:
mvn clean install -DtheVariable=Two
"Two" is picked-up instead.
I'm not sure If this will help but if you are annotating classes and want a default value when a system property is not present this is what I currently do:
#Value("#{systemProperties['fee.cc']?:'0.0225'}")
public void setCcFeePercentage(BigDecimal ccFeePercentage) {
this.setCcFeePercentage(ccFeePercentage);
}
It can be done as #sebastien has described but in the configuration file as you want:
<bean id="theVar" class="java.lang.String">
<constructor-arg value="#{systemProperties['varName'] == null ? 'default_value' : systemProperties['varName']}"/>
</bean>
If your varName variable is not present, default value will be set.

Resources