Is it possible to populate spring util:list via properties file? - spring

I would like to populate transport End points via properties file. I tried this but it didn't work
<util:properties id="cxfProperties" location="/WEB-INF/classes/cxf.properties" />
<util:list id="transportEndpoints">
<!--
<value>http://localhost:8080/doubleit/services/doubleit.*</value>
-->
<value>#{cxfProperties.service.wsdllocation}</value>
</util:list>
In my properties file I have
service.wsdllocation=http://localhost:8080/doubleit/services/doubleit.*
I get error:
Expression parsing failed; nested exception is
org.springframework.expression.spel.SpelEvaluationException:
EL1008E:(pos 14): Field or property 'service' cannot be found on
object of type 'java.util.Properties'

I don't think SpEL provides direct field access syntax for property in Properties. So I think the correct syntax should be:
#{cxfProperties.getProperty('service.wsdllocation')}
or
#{cxfProperties.getProperty('service.wsdllocation', 'SOME_DEFAULT_VAL')}

Related

#Value not resolving using <context:property-placeholder location=" />

Hey guys I have a problem. I'm using Spring and I have a class with an injected boolean
protected boolean ignoreVisibleFlag;
I have verified that indeed that property lives in my properties file:
and I have verified that I have this in my Application Context XML:
<context:property-placeholder location="classpath.properties" />
However I still get the following stack trace:
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value
at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:77)
Any ideas?
From past experience using primitive wasn't able to handle the casting from string (as read) to boolean.
What you need to do is use Object instead of the primitive which will enable the conversion process from String to boolean.
#Value("${mojo.ignoreAlertsVisibleFlag}")
protected Boolean ignoreVisibleFlag;
M. Deinum's fix worked. I needed to add the to my dispatcher servlet.

Spring EL template in a spring bean definition

I have a bean that has a map injected. The entries in the map are of type myBean (see below) and are defined in my spring XML. It may be that not all properties of myBean are defined in the xml, so I thought I would provide defaults in the form of a template where the variable bit in the template is provided by another property that will be present (p1 below). I hope that makes sense.
I am sure there are other ways to achieve this; well, I know there are, but I am new to Spring and I came across Spring EL and it sounded like it was suited to this kind of thing, so I tried this:
<bean id="myDefaults" class="com.myco.MyDefaults">
<property name="prop1" value="abc#{this.p1}def"/>
</bean>
<bean id="myBean" class="com.myco.MyBean" abstract="true">
<property name="theDefaults" ref="myDefaults"/>
</bean>
In MyBean the value of p1 is 100, and I was hoping that the value of theDefaults would be abc100def, but instead I get an error:
Error creating bean with name 'myDefaults' defined in class path resource [myapp-spring.xml]:
Initialization of bean failed; nested exception is
org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'this' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext'
Thanks for any help
Paul
The variable is #this, not this but in any case, it's not needed in this context, it's implied.
Use value="abc#{p1}def"

Spring batch/integration bean initialization error for remote directory in outbound adapter

I am trying to use spring batch/integration in the following way:
<bean id="ftpRemoteDirectory" class="java.lang.String" scope="step">
<constructor-arg type="java.lang.String" value="#{jobExecutionContext.get ('batchProperties').getProperty('remote.directory')}"/>
</bean>
<int-sftp:outbound-channel-adapter id="sftpOutboundAdapter"
channel="sftpChannel"
session-factory="sftpSessionFactory"
remote-directory-expression="#{ ftpRemoteDirectory }"
charset="UTF-8"
use-temporary-file-name="false"/>
However I receive the following error:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name '(inner bean)#13': Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]: Could not convert constructor argument value of type [com.sun.proxy.$Proxy12] to required type [java.lang.String]: Failed to convert value of type 'com.sun.proxy.$Proxy12 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'java.lang.String'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.sun.proxy.$Proxy12 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [java.lang.String]: no matching editors or conversion strategy found
The goal is to have remote-directory populated from the arguments passed into the JVM from spring batch admin. That is why scope="step" is present on the ftpRemoteDirectory bean - so that we have access to the jobExecutionContext object. So, i'm trying to get the property from the jobExecutionContext and then inject it into the remote-directory attribute of the outbound channel adapter.
I'd be open to suggestions for other ways to do this as well - I just can't get it to work. Thanks!

Spring task scheduler delay from jndi

I'm configuring a Spring task scheduler.
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="servicesConfigurationBean" method="loadResources" fixed-delay="300000" />
</task:scheduled-tasks>
It's working properly. Now I would like to set the delay value from a JNDI lookup. So I tried the following:
<task:scheduled ref="servicesConfigurationBean" method="loadResources">
<property name="fixed-delay"><ref local="servicesRefreshRate"/></property>
</task:scheduled>
But now I obtain the following exception:
[/WEB-INF/spring/applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.1: Element 'task:scheduled' must have no character or element information item [children], because the type's content type is empty.[/WEB-INF/spring/applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.1: Element 'task:scheduled' must have no character or element information item [children], because the type's content type is empty.
I understand the cause of the exception, so, is there a viable solution to my problem?
Thanks.
Using <property> won't work, because <task:scheduled> is a macro, not a bean definition. The two work very differently.
Try using Spring-EL instead:
<task:scheduled ref="servicesConfigurationBean"
method="loadResources"
fixed-delay="#servicesRefreshRate" />
I haven't tried it, but give it a go.

Can I use a property placeholder with Spring EL?

Before upgrading to Spring 3 I had this in my applicationContext.xml file:
<bean class="com.northgateis.pole.ws.PolePayloadValidatingInterceptor">
<property name="validateRequest" value="${validateRequest}" />
<property name="validateResponse" value="${validateResponse}" />
</bean>
where ${validateRequest) and ${validateRequest) refer to properties that may or may not be defined in my properties file.
In Spring 2, if these proeprties were not present in the properties file the setters on the bean were not called and so the defaults hard-coded in PolePayloadValidatingInterceptor were used.
After upgrading to Spring 3, it seems the behaviour is different: If the properties are not present in the properties file I get the following exception:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'annotationMapping' defined in class path resource [com/northgateis/pole/ws/applicationContext-ws.xml]: Could not resolve placeholder 'validateRequest'
at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:272)
at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:75)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:640)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:615)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:405)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:272)
I tried dabbling with Spring EL but the following doesn't seem to work:
<bean class="com.northgateis.pole.ws.PolePayloadValidatingInterceptor">
<property name="validateRequest" value="${validateRequest?:true}" />
<property name="validateResponse" value="${validateResponse?:false}" />
</bean>
The value after the Elvis operator is always used, even when the properties are defined in the proeprties file. Interesting that the syntax is accepted.
Any suggestions?
It looks like Spring 3's handling of default values with the Elvis operator was rather broken. This has apparently been fixed (see SPR-7209) in the fresh-out-of-the-oven Spring 3.0.3, and the correct syntax should be the rather baroque:
#{${validateRequest}?:true}
There's no need for Spring EL for setting a default value for a missing property when resolving it with a placeholder configurer. Simply use ${validateRequest:true}. The "Elvis operator" is not concerned with resolving placeholders, it just relies on whatever input the placeholder configurer provides.
See SPR-4785.

Resources