How can I use a list as reference in Spring configuration for JAX-WS handlers? - spring

I am using the Spring extension for JAX-WS and have a problem to use a list in my Spring configuration:
This is the working configuration:
<wss:binding url="/services/demo">
<wss:service>
<ws:service bean="#demoEndpoint">
<ws:handlers>
<ref bean="handler1"/>
<ref bean="handler2"/>
</ws:handlers>
</ws:service>
</wss:service>
</wss:binding>
As I have more endpoint, which should use the same set of handlers, I want to define the list of handlers in a single configuration.
But this config doesn't work:
<util:list id="myHandlers">
<ref bean="handler1"/>
<ref bean="handler2"/>
</util:list>
<wss:binding url="/services/demo">
<wss:service>
<ws:service bean="#demoEndpoint">
<ws:handlers>
<ref bean="myHandlers"/>
</ws:handlers>
</ws:service>
</wss:service>
</wss:binding>
I get the following exception:
Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.util.ArrayList] to required type [javax.xml.ws.handler.Handler] for property 'handlers[0]': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:264)
at org.springframework.beans.TypeConverterDelegate.convertToTypedCollection(TypeConverterDelegate.java:559)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:199)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:448)
... 66 more
This is the corresponding setter in org.jvnet.jax_ws_commons.spring.SpringService:
public void setHandlers(List<Handler> handlers) {
this.handlers = handlers;
}

Related

Spring cache Cache name must be non-null if specified excpetion

I have been trying to implement a basic caching for my project but i am getting an error while deploying the application .
Server : Tomcat 7
Spring Version : 4.1.4
Caused by: java.lang.IllegalArgumentException: Cache name must be non-null if specified
at org.springframework.util.Assert.hasText(Assert.java:162)
at org.springframework.cache.interceptor.CacheOperation.setCacheNames(CacheOperation.java:66)
at org.springframework.cache.annotation.SpringCacheAnnotationParser.parseCacheableAnnotation(SpringCacheAnnotationParser.java:102)
at org.springframework.cache.annotation.SpringCacheAnnotationParser.parseCacheAnnotations(SpringCacheAnnotationParser.java:67)
at org.springframework.cache.annotation.SpringCacheAnnotationParser.parseCacheAnnotations(SpringCacheAnnotationParser.java:57)
at org.springframework.cache.annotation.AnnotationCacheOperationSource$2.getCacheOperations(AnnotationCacheOperationSource.java:124)
at org.springframework.cache.annotation.AnnotationCacheOperationSource.determineCacheOperations(AnnotationCacheOperationSource.java:142)
at org.springframework.cache.annotation.AnnotationCacheOperationSource.findCacheOperations(AnnotationCacheOperationSource.java:121)
at org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource.computeCacheOperations(AbstractFallbackCacheOperationSource.java:140)
at org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource.getCacheOperations(AbstractFallbackCacheOperationSource.java:100)
at org.springframework.cache.interceptor.CacheOperationSourcePointcut.matches(CacheOperationSourcePointcut.java:39)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:225)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:262)
at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:294)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:118)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:330)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1571)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 64 more
I tried using different cache manager configuration with no luck
here is the xml configuarion
<cache:annotation-driven />
<bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager">
<constructor-arg>
<set>
<value>cache1</value>
<value>cache2</value>
<value>cache3</value>
</set>
</constructor-arg>
</bean>
I also tried the config given on the spring docs
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="cache1"/>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="cache2"/>
</set>
</property>
</bean>
the function I am trying to cache
#Cacheable(value = "cache1", key = "#root.methodName")
public List<ObjectDetails> getAllObjects() {
return objectDao.getAllObjects();
}
Can any one point me towards where this issue might arise from while implementing caching.
Thanks to Stéphane Nicoll I was able to find the issue
Cache name must be non-null if specified
This means I have provided an empty string in place of cache name like this.
#Cacheable(value = "", key = "#root.methodName")
public List<ObjectDetails> getAllObjects() {
return objectDao.getAllObjects();
}
Provided a suitable name and it was resolved . Thanks.

custom thymeleaf dialect registration causing exception

in applicationContext.xml
<bean id="templateEngine"
class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="additionalDialects">
<set>
<bean class="org.test.custom.CustomDialact" />
</set>
</property>
</bean>
Stacktrace:
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'additionalDialects' of bean class [org.thymeleaf.spring3.SpringTemplateEngine]: Bean property 'additionalDialects' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1042)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:902)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:57)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1424)
... 50 more
i don't know but it was fixed after restarting machine. but mean while i find another solution
by extend a custom class with HashSet and in constructor add custom dialect in it and declare it in xml. provide it reference to additionalDialects . thats it .it will start running . it think it is problem related to generics as spring sometimes supply empty type
like HashSet<V> .

spring bean initializing instances differently via property wiring

I have the following properties in a property file:
context1.property1=value1
context1.property2=value2
context1.property3=value3
context2.property1=value4
context2.property2=value5
context2.property3=value6
I have a bean with the following structure:
class Bean {
private property1;
private property2;
private property3;
}
Is there any way better to initialize 2 instances of Bean without writing something like:
<bean id="bean1" class="com.test.Bean">
<property name="property1" value="${context1.value1}" />
<property name="property2" value="${context1.value2}" />
<property name="property3" value="${context1.value3}" />
</bean>
<bean id="bean2" class="com.test.Bean">
<property name="property1" value="${context2.value1}" />
<property name="property2" value="${context2.value2}" />
<property name="property3" value="${context2.value3}" />
</bean>
Thanks!
Have a look at PropertyOverrideConfigurer:
Property resource configurer that overrides bean property values in an application context definition. It pushes values from a properties file into bean definitions.
Configuration lines are expected to be of the following form:
beanName.property=value
Example properties file:
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql:mydb
See also
Using PropertyOverrideConfigurer with Annotated Classes in Spring 3

groovy + Spring add list in different order will throw NotWritablePropertyException

I am trying to integrate Groovy with Spring.
In one bean I would need to put in a list as property
However that only work if I define the item in list before the bean definition.
To avoid future errors...I would like to ask what is the mechanism behind compiling the context and causing the error?
The Item.groovy is a simple bean with field String itemName
My config is like
Not-working
<lang:groovy id="handler" script-source="ItemHandlerImpl.groovy">
<lang:property name="itemList">
<list>
<lang:groovy id="item1" script-source="Item.groovy">
<lang:property name="itemName" value="name1" />
</lang:groovy>
</list>
</lang:property>
</lang:groovy>
This throws
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'itemName' of bean class [org.springframework.scripting.groovy.GroovyScriptFactory]: Bean property 'itemName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1024)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:900)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1358)
... 70 more
After many attempts, this is my working config
<lang:groovy id="item1" script-source="Item.groovy">
<lang:property name="itemName" value="name1" />
</lang:groovy>
<lang:groovy id="handler" script-source="ItemHandlerImpl.groovy">
<lang:property name="itemList">
<list>
<ref bean ="item1">
</list>
</lang:property>
</lang:groovy>

spring: how to omit bean-name in a list?

Do I have to give ids to the elements of a list of Bars ?
<list value-type="foo.Bar">
<bean p:p1="someP1Value" p:p2="aP2Value" />
</list>
I get
Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
Configuration problem: Unnamed bean definition specifies neither 'class' nor 'parent'
nor 'factory-bean' - can't generate bean name
for this.
How can I omit the bean ids?
Well, the error message is pretty clear. When defining a <bean/> you must either specify class or parent attribute:
<list>
<bean class="foo.Bar" p:p1="someP1ValueA" p:p2="aP2ValueA"/>
<bean class="foo.Bar" p:p1="someP1ValueB" p:p2="aP2ValueB"/>
<bean class="foo.BarSubclass" p:p1="someP1ValueC" p:p2="aP2ValueC"/>
</list>
If you want to avoid exceesive use of class attribute, you can take advantage of parent feature:
<bean id="bar" abstract="true" class="foo.Bar"/>
<list value-type="foo.Bar">
<bean parent="bar" p:p1="someP1ValueA" p:p2="aP2ValueA"/>
<bean parent="bar" p:p1="someP1ValueB" p:p2="aP2ValueB"/>
<bean parent="bar" p:p1="someP1ValueC" p:p2="aP2ValueC" class="foo.BarSubclass"/>
</list>
What are the p:p1 and p:p2 namespaces?

Resources