I am getting the placeholder instead of its property value while loading the beans.
properties file
tm.web.keystore.key.password=WaheeD
tm.web.tcp.backlog=1024
tm.web.min.jetty.threads=8
tm.web.max.jetty.threads=25
appcontext.xml file
<bean class="com.intel.ssg.mconsole.core.web.WebServer" id="webServer">
<property name="port" value="${tm.web.port}" />
<property name="address" value="${tm.web.address}" />
<property name="warLocation" value="${tm.home}/mconsole.war" />
<property name="secure" value="${tm.web.secure}" />
<property name="keystoreLocation" value="${tm.web.keystore.location}" />
<property name="keystorePassword" value="WaheeD" />
<property name="keyPassword" value="${tm.web.keystore.key.password}" />
<property name="tcpBacklog" value="${tm.web.tcp.backlog}" />
<property name="minJettyThreads" value="${tm.web.min.jetty.threads}" />
<property name="maxJettyThreads" value="${tm.web.max.jetty.threads}" />
</bean>
Loading it via marshaller
try {
FileInputStream fis = new FileInputStream(getAppContextFile());
try {
return (Beans) JAXBUtil.getUnmarshaller().unmarshal(fis);
} finally {
fis.close();
}
In Beans,I am getting value as ${tm.weberver.port}for bean webServer port rathen than its exact value..suppose 8443 port.
You post a properties file that doesn't have any property for port number, a context file that uses ${tm.web.port}, and your text says that you're using ${tm.weberver.port}.
I see three possible places for your mistake. That's assuming that you are actually setting other properties. If not, see Andrey's comment.
You dont need need to expressly load beans from your ApplicationContext.xml.
Make sure the following are present:
In your ApplicationContext.xml there must be a property loader for your property file, e.g. PropertyPlaceholderConfigurer
In your application, a application context loader is required. There may one built into your current framework e.g. WebApplicationContext in DispatcherServlet for Spring MVC. If you're starting out you can use ClassPathXmlApplicationContext.
Related
Currently in my data context XML file, it's looking up values to substitute from a application.properties file:
<bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" lazy-init="default">
<property name="location" value="classpath:application.properties" />
</bean>
<bean id="appleDataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="url" value="${apple.url}" />
</bean>
I'd like to change this from being looked up from the application.properties file, to being read out of a Properties/Map object.
This is because the configuration could come from more than one place (i.e. not just the classpath), and this logic is already implemented in my application.
I've seen MapPropertySource but I think while that can be done when the bean is configured in Java, I'm not sure this logic can be implemented when working with the XML file alone?
I am training to integrate the Struts2 and Spring and Hibernate.I using a properties file to set the dataSource:
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
And this is the db.properties following:
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc\:mysql\://localhost\:3306/sp3
jdbc.username=root
jdbc.password=123456
I find the example about this in spring-reference,but I just don't know why I must use ${jdbc.XXXXX} but not ${XXXXX}.I try to write "username=root","password=123456",and then it cause "Access denied for user 'Administrator'#'localhost' (using password: YES)"
If using the Expression Language principle:${jdbc.username} meanings "getJdbc().getUsername();"because in the struts-tag,${model} means getModel(),is it right?
I find the source about PropertyPlaceholderConfigurer and ComboPooledDataSource ,but I can not find any code about getJdbc();
Thank you for your help.
I don't understand what you're asking. jdbc.username is just a text, or a key if you want. You could have used "BLABLABLA=root" in db.properties and in your xml <property name="user" value="${BLABLABLA}" />.
Probably you are confusing PropertyPlaceholderConfigurer with PropertyOverrideConfigurer.
If you had the problems with your properties, you would have got an exception something like->
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'XYZ' in string value "${XYZ}".
What do you mean by 'everything is ok'? Were you able to access DB with previous setup?
The exception you are getting seems related to username and password combination OR you don;t have proper rights/GRANTS.
jdbc.XXXXX is just a key in the property file. You could have used anything in place of it.When you perform ${something} it would just pick the value for key 'something' from the property file and use it for populating the properties of bean.
For example :
<property name="jdbcUrl" value="${jdbc.url}" /> is just setting the value for a field named 'jdbcUrl' in class ComboPooledDataSource.
i have the next properties files with Spring Framework
config.properties
with content
environment=devel //posible values: devel, testing, prod
and with the previous environment property, choose some of the following files to load dynamically
config-service1-devel.properties
config-service1-testing.properties
config-service1-prod.properties
config-serviceN-devel.properties
config-serviceN-testing.properties
config-serviceN-prod.properties
and then, with spring i want load the properties, i'm solve to load the first properties file but i dont understand how to use expression language to complete the values of the dependent properties.
<bean id="MainApplicationProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location"
value="file://#{systemProperties['jboss.server.home.dir']}/conf/services.properties" />
<property name="placeholderPrefix" value="$mainProperty{" />
<property name="placeholderSuffix" value="}" />
</bean>
<bean id="SecondApplicationProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="MainApplicationProperties">
<property name="locations">
<list>
<value>file://#{systemProperties['jboss.server.home.dir']}/conf/serviceOne/service1-$mainProperty{environment}.properties</value>
<value>file://#{systemProperties['jboss.server.home.dir']}/conf/serviceTwo/service2-$mainProperty{environment}.properties</value>
<value>file://#{systemProperties['jboss.server.home.dir']}/conf/serviceN/serviceN-$mainProperty{environment}.properties</value>
</list>
</property>
</bean>
the error output is the next,
java.io.FileNotFoundException: /..../conf/serviceOne/service1-$mainProperty{environment}.properties (No such file or directory)
my opinion is, the value has not replaced
helpme, thanks
The problem is that when BeanFactoryPostProcessors are starting to be invoked, they are already instantiated. So even thou the first PropertyPlaceholderConfigurer modifies the bean definition of the second PropertyPlaceholderConfigurer, it has no effect as both beans have been already instantiated.
Spring placeholder mechanism is very clean and robust, unfortunatelly it works only on Spring files.
I'm using EhCahe and I want to use the placeholder mechanism on the ehcache.xml file. I have my own factory bean for EhCache, and I can give to this library configuration as InputStream. So all I need to do to achieve my goal is:
read xml file content from classpath
access the property placeholder for current spring.xml file (those in that my bean is configured)
invoke the placeholder on the read resource
give the resource back to library as InputStream
So my question is, how to do that, as compact as the Spring allows it? I'd like to avoid creating placeholders itself, so the code will do as little 'magic' as possible, so I'd like to use the property configuration from xml file.
EhCache supports System Property placeholder substitution in the ehcache.xml file, so one option is to copy your Spring placeholder values to System properties so they can be used referenced in the ehcache.xml file:
In spring context xml...
<!-- Copy Spring placeholder value to System props -->
<bean id="systemProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:properties>
<prop key="cache.ttl">${cache.ttl}</prop>
</util:properties>
</property>
</bean>
Then in your ehcache.xml file you can now use ${cache.ttl} placeholder populated above:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<cache name="myCache" timeToLiveSeconds="${cache.ttl}" maxElementsInMemory="1000" overflowToDisk="false" />
</ehcache>
Ehcache has an api to programatically define new caches. Why couldn't you make a bean that starts up along with spring and is filled automagically? That way you don't have to create an automatich EhCache.xml, but you can define all the caches you want in a spring context file.
It is not necessary to use sytem properties. However you would have to resolve placeholders during build.
Put your properties to object like this:
<bean id="cacheProperties" class="java.util.Properties">
<constructor-arg>
<props>
<prop key="prop1">#{prop1}</prop>
<prop key="prop2">#{prop2}</prop>
</props>
</constructor-arg>
</bean>
And set them to your custom PlaceHolderHelper:
<bean id="cachePlaceholderHelper"
class="com.PlaceholderHelper" depends-on="cacheProperties">
<property name="configFileResource" value="classpath:cacheConfig.xml"/>
<property name="properties" ref="cacheProperties"/>
</bean>
PlaceholderHelper could look something like this:
private Resource configFileResource;
private Properties properties;
private Resource resolvedConfigResource;
#PostConstruct
public void replace() throws IOException {
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
if (this.properties != null && this.configFileResource != null) {
File file = this.configFileResource.getFile();
String content = FileUtils.readFileToString(file);
String result = helper.replacePlaceholders(content, this.properties);
File resolvedCacheConfigFile = new File("resolvedCacheConfig");
FileUtils.write(resolvedCacheConfigFile, result);
resolvedConfigResource = new FileSystemResource(resolvedCacheConfigFile);
logger.info(String.format("Placeholders in file %s were replaced.", file.getName()));
}
}
Change p:configLocation to resolved resource:
p:configLocation="#{cachePlaceholderHelper.resolvedConfigResource}
Now you can use ${prop1} expression anywhere in XML.
There is this tag <terracottaConfig url="host1:9510,host2:9510,host3:9510"/> in ehcache.xml file inside spring web application. I want to externalize url attribute of this tag. Value of URL should be replaced by a property from external file. It will be very helpful if you suggest any solution to this problem.
You can put something like this -
<terracottaConfig url="${terracotta.config.location}" /> , however the big catch is that this will be loaded only from the system properties. It is not resolved from PropertyPlaceHolder as it is not a Spring configuration file.
So if you want to use an external config file, you will basically have to programatically set this system property before the Spring Application starts loading up the ehcache.xml file - one way to do that will be write your custom ServletContextListener to load up your properties file and set the system property based on that, this way when the ehcache.xml is loaded up it would be able to resolve the place holder properly.
Your answer helped me to solve my problem. I just want to add that instead of setting system property through program, I am using util:properties as follows
<bean id="sysProperties" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}"/>
<property name="targetMethod" value="putAll"/>
<property name="arguments">
<util:properties>
<prop key="propertyname_used_in_ecache_xml">#{proerties_defined_using_property_factory['propertyname_defined_in_external_properties_file']}</prop>
</util:properties>
</property>
</bean>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" depends-on="sysProperties">
<property name="configLocation">
<value>classpath:ehcache.xml</value>
</property>
</bean>