Spring doesn't resolve classpath: in the file declaration in xml - java

I have the problem with resolve spring's "classpath:" feature. I a have my file in the next path:
src/main/java/resources/FederationMetadata.xml
Also, I have a bean:
<bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager">
<constructor-arg>
<list>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
<constructor-arg>
<bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider">
<constructor-arg>
<value type="java.io.File">classpath:FederationMetadata.xml</value>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
</bean>
</constructor-arg>
</bean>
</list>
</constructor-arg>
</bean>
So my problem is that application fails with the next exception:
D:\myFolder\myProject\classpath:FederationMetadata.xml does not exist
As I understand Spring doesn't resolve file location. I tried with classpath*:, and it didn't help. In another project I have the same settings (with "classpath:") and it works fine. What it can be?

This issue was driving me crazy as well.
At some point I realized that FilesystemMetadataProvider was replaced with ResourceBackedMetadataProvider.
So now if you have your Metadata XML inside of the classpath, do something like this:
<bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager">
<constructor-arg>
<list>
<bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider">
<constructor-arg>
<bean class="java.util.Timer"/>
</constructor-arg>
<constructor-arg>
<bean class="org.opensaml.util.resource.ClasspathResource">
<constructor-arg value="/FederationMetadata.xml"/>
</bean>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
</list>
</constructor-arg>
</bean>

Try
<value type="java.io.File">file:///FederationMetadata.xml</value>
instead of
<value type="java.io.File">classpath:FederationMetadata.xml</value>

If you want it accessed from class path you need to put it inside
WEB-INF/classes folder.
the path is relative to classes folder ie if the file is inside
WEB-INF/classes/configs/somefile.xml
then
classpath:configs/somefile.xml

Related

What is this error in spring mvc integrated via memcache

I want to use simple-spring-memcached to cache data. so using this https://code.google.com/p/simple-spring-memcached/wiki/Getting_Started for my purpose.
i add in my dispatcher-servlet.xml
<aop:aspectj-autoproxy />
<import resource="simplesm-context.xml" />
<bean name="cacheManager" class="com.google.code.ssm.spring.SSMCacheManager">
<property name="caches">
<set>
<bean class="com.google.code.ssm.spring.SSMCache">
<constructor-arg name="cache" index="0" ref="defaultCache"/>
<!-- 5 minutes -->
<constructor-arg name="expiration" index="1" value="0"/>
<!-- #CacheEvict(..., "allEntries" = true) doesn't work -->
<constructor-arg name="allowClear" index="2" value="false"/>
</bean>
</set>
</property>
</bean>
<bean name="defaultCache" class="com.google.code.ssm.CacheFactory">
<property name="cacheName" value="defaultCache"/>
<property name="cacheClientFactory">
<bean name="cacheClientFactory" class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl"/>
</property>
<property name="addressProvider">
<bean class="com.google.code.ssm.config.DefaultAddressProvider">
<property name="address" value="127.0.0.1:11211"/>
</bean>
</property>
<property name="configuration">
<bean class="com.google.code.ssm.providers.CacheConfiguration">
<property name="consistentHashing" value="true"/>
</bean>
</property>
</bean>
i also add simple-spring-memcached-3.5.0.jar and spymemcache.jar,spymemcache-provider.jar to lib folder. but when i run my project occur this exception:
Cannot find class **[net.nelz.simplesm.config.MemcachedClientFactory]** for bean with name 'memcachedClientFactory' defined in ServletContext resource [/WEB-INF/simplesm-context.xml]; nested exception is java.lang.ClassNotFoundException: net.nelz.simplesm.config.MemcachedClientFactory
you must add lib for this class.
It seams that you have also an old version of Simple Spring Memcached on your classpath. The class net.nelz.simplesm.config.MemcachedClientFactory is no longer available in 3.x. Check your classpath and remove all Simple Spring Memcached artifacts older than 3.5.0.

Pass parameters to Spring MethodInvokingFactoryBean arguments list

I am trying to find the way to pass objects to Spring MethodInvokingFactoryBean arguments list. Here is my Spring configuration:
<bean id="qName" class="javax.xml.namespace.QName">
<constructor-arg index="0" value="${com.groupgti.esb.online.tests.talentq.tns}"/>
<constructor-arg index="1" value="${com.groupgti.esb.online.tests.talentq.serviceName}"/>
</bean>
<bean id="wsdlUrl" class="java.net.URL">
<constructor-arg index="0" value="${com.groupgti.esb.online.tests.talentq.url}"/>
</bean>
<bean id="service" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<bean id="serviceObject" class="com.groupgti.onlinetest.talentq.jaxb.TQIntegrationV2"/>
</property>
<property name="targetMethod">
<value>create</value>
</property>
<property name="arguments">
<list>
<value type="java.net.URL">wsdlUrl</value>
<value type="javax.xml.namespace.QName">qName</value>
</list>
</property>
</bean>
This is not working:
<value type="java.net.URL">wsdlUrl</value>
<value type="javax.xml.namespace.QName">qName</value>
I am getting the exception:
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.net.URL'; nested exception is java.lang.IllegalArgumentException: Could not retrieve URL for OSGi resource[wsdlUrl|bnd.id=573|bnd.sym=com.groupgti.esb.online.tests.talentq]: OSGi resource[wsdlUrl|bnd.id=573|bnd.sym=com.groupgti.esb.online.tests.talentq] cannot be resolved to URL because it does not exist
This is because parameter is passed as String, just wsdlUrl and not as an java.net.URL object.
I have also tried this:
<property name="arguments">
<ref bean="wsdlUrl"/>
<ref bean="qName"/>
</property>
This gives me an exception that ref attribute does not belong here. So how then should I pass an object to arguments list?
Found a solution. I had to add <list> and then declare <ref>:
<property name="arguments">
<list>
<ref bean="wsdlUrl"/>
<ref bean="qName"/>
</list>
</property>
Like this, everything is working.

How to reduce duplication in Spring application context

I have some beans which I create which all use a similar pattern for bean instantiation. The top objects are all very similar, but the objects they contain differ by string constructor arguments. Everything in the each top-level bean is the same except for two instances of THIS CHANGES A and one instance of THIS CHANGES B. Below is one of my beans. The others are exactly the same except for the THIS CHANGES values.
<bean id="mover1" class="CustomDataMover">
<constructor-arg ref="session"/>
<constructor-arg>
<bean class="DataCache">
<constructor-arg>
<bean class="AllValuesReader">
<constructor-arg ref="databaseConnector"/>
<constructor-arg value="THIS CHANGES A"/>
<constructor-arg value="v1"/>
<constructor-arg value="v2"/>
</bean>
</constructor-arg>
</bean>
</constructor-arg>
<constructor-arg ref="customUpdate"/>
<constructor-arg value="THIS CHANGES B"/>
<constructor-arg>
<bean class="ValueGenerator">
<constructor-arg>
<bean class="LatestValueRetriever">
<constructor-arg ref="databaseConnector"/>
<constructor-arg value="v3"/>
<constructor-arg value="v4"/>
<constructor-arg value="THIS CHANGES A"/>
</bean>
</constructor-arg>
</bean>
</constructor-arg>
</bean>
How can I reduce the amount of duplication in my beans? I'm looking for some way to make some sort of template. Also, please note that I do have references to other beans.
You can use abstract bean definitions as templates to reduce duplication. For example:
<bean id="parent" abstract="true">
<constructor-arg value="ARG0"/>
<property name="propertyA" value="A"/>
<property name="propertyB" value="B"/>
<property name="propertyC" ref="beanC"/>
</bean>
<bean id="child1" class="SomeClass" parent="parent">
<property name="propertyD" value="D1"/>
</bean>
<bean id="child2" class="SomeOtherClass" parent="parent">
<property name="propertyD" value="D2"/>
</bean>
Beans "child1" and "child2" will share values from "parent" for arg0, "propertyA", "propertyB", and "propertyC", and still be able to configure their own values for "propertyD".
Note that "parent" has no class and therefore cannot be instantiated. Also note that "child1" and "child2" can be children of the same abstract bean definition while being completely different classes - this hierarchy has nothing to do with the class hierarchy.

How to write a spring bean with a constructor that contains a list?

I have a list as follows:
ArrayList<DiameterMessageHandler> handlers = new ArrayList<>();
handlers.add(new AARHandler());
handlers.add(new CERHandler());
handlers.add(new PPAHandler());
handlers.add(new STRHandler());
handlers.add(new DWRHandler());
I am wondering how to create a spring bean that takes handlers as one of its arguments, i.e. is it possible to do this in the applicationContext.xml - Do I have to create separate beans for the list and each of the handlers(AARHandler etc) first? Here is my applicationContext.xml
<bean id="DiameterClient" class="com.rory.ptspsim.diameterclient.DiameterClient" scope="singleton" init-method="start">
<constructor-arg type="java.lang.String" index="0"><value>${pcca.host}</value></constructor-arg>
<constructor-arg index="1">WHAT GOES HERE?</constructor-arg>
</bean>
Probably you want all these handlers be Spring beans too. This is the configuration:
<bean id="DiameterClient" class="com.rory.ptspsim.diameterclient.DiameterClient" init-method="start">
<constructor-arg value="${pcca.host}" />
<constructor-arg>
<list>
<ref bean="aarHandler" />
...
</list>
</constructor-arg>
</bean>
<bean id="aarHandler" class="com.rory.ptspsim.diameterclient.AARHandler" />
I think the most appropriate way to do that is:
<bean id="DiameterClient" class="com.rory.ptspsim.diameterclient.DiameterClient" scope="singleton" init-method="start">
<constructor-arg type="java.lang.String" index="0"><value>${pcca.host}</value></constructor-arg>
<constructor-arg index="1">
<list>
<ref bean="aarHandler" />
<ref bean="cerHandler" />
<ref bean="ppaHandler" />
<ref bean="strHandler" />
<ref bean="dwrHandler" />
</list>
</constructor>
</bean>
If you want all available Handlers, Spring will also collect them for you via Autowiring:
public DiameterClient(#Autowired List<DiameterMessageHandler> handlers){
this.handlers = handlers;
}
Now Spring will inject a List of all available Handlers.
See Spring Reference 4.9.2: #Autowired
<bean id="DiameterClient" class="com.rory.ptspsim.diameterclient.DiameterClient" scope="singleton" init-method="start">
<constructor-arg type="java.lang.String" index="0"><value>${pcca.host}</value></constructor-arg>
<constructor-arg index="1">
<list>
<bean class="AARHandler"/>
<bean class="CERHandler"/>
</list>
</constructor-arg>
</bean>
<list>
<ref bean="handler1" />
<ref bean="handler2" />
<ref bean="handler3" />
<ref bean="handler4" />
<ref bean="handler5" />
</list>
<bean id="handler1" class="AARHandler"/>
<bean id="handler2" class="CERHandler"/>
<bean id="handler3" class="PPAHandler"/>
<bean id="handler4" class="STRHandler"/>
<bean id="handler5" class="DWRHandler"/>

Declaring an array of objects in a Spring bean context

I'm trying to create an array of objects in a Spring context file so I can inject it to a constructor that's declared like this:
public RandomGeocodingService(GeocodingService... services) { }
I'm trying to use the <array> tag:
<bean id="googleGeocodingService" class="geocoding.GoogleGeocodingService">
<constructor-arg ref="proxy" />
<constructor-arg value="" />
</bean>
<bean id="geocodingService" class="geocoding.RandomGeocodingService">
<constructor-arg>
<array value-type="geocoding.GeocodingService">
<!-- How do I reference the google geocoding service here? -->
</array>
</constructor-arg>
</bean>
I haven't been able to find an example or something in the in the documentation on how to do this. Also, you have any suggestions for a better way of acheiving what I'm trying to do, please let me know :).
That's because there's no such thing as <array>, there's only <list>.
The good news is that Spring will auto-convert between lists and arrays as required, so defined your array as a <list>, and Spring will be coerce it into an array for you.
This should work:
<bean id="googleGeocodingService" class="geocoding.GoogleGeocodingService">
<constructor-arg ref="proxy" />
<constructor-arg value="" />
</bean>
<bean id="geocodingService" class="geocoding.RandomGeocodingService">
<constructor-arg>
<list>
<ref bean="googleGeocodingService"/>
</list>
</constructor-arg>
</bean>
Spring will also coerce a single bean into a list, if required:
<bean id="geocodingService" class="geocoding.RandomGeocodingService">
<constructor-arg>
<ref bean="googleGeocodingService"/>
</constructor-arg>
</bean>
Spring can automatically convert a list into an array[]
check it out http://forum.springsource.org/showthread.php?37767-Injecting-String-Array
<bean name="test" class="Test">
<property name="values" value="hugo,emil"></property>
</bean>
Check out the util schema.
I'm actually using <array> tag to inject an array of objects into a bean and it works.
Take a look at the following code...
<bean id="song1" class="mx.com.company.songs.Song">
<property name="name" value="Have you ever seen the rain?"/>
</bean>
<bean id="song2" class="mx.com.company.songs.Song">
<property name="name" value="La bamba"/>
</bean>
<bean id="guitarPlayer" class="mx.com.company.musician.GuitarPlayer">
<property name="songs">
<array>
<ref bean="song1"/>
<ref bean="song2"/>
</array>
</property>
</bean>

Categories

Resources