PDA

View Full Version : org.springframework.beans.BeanInstantiationExcepti on



Nigel W
May 13th, 2011, 12:19 PM
Hi,

I am trying to use "spring mobile" but I am having little success so far.

I have made the following changes to my exisiting Spring 3.0 MVC project.

POM - move

spring-orm
spring-context
spring-beans
spring-core
spring-webmvc
spring-web
spring-jdbc
spring-context-support

org.springframework dependancies to 3.1.0.M1.


change:




<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<!-- Configures the @Controller programming model
-->
<mvc:annotation-driven />

</beans>


to




<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:device="http://www.springframework.org/schema/mobile/device"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/mobile/device http://www.springframework.org/schema/mobile/device/spring-mobile-device-1.0.xsd">
<!-- When went to Spring 3.1 change line above to 3.1 -->

<!-- Configures the @Controller programming model -->
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.mobile.device.DeviceWebArgumen tResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>

<mvc:interceptors>
<!-- On pre-handle, resolve the device that originated the web request -->
<bean class="org.springframework.mobile.device.DeviceResolverHa ndlerInterceptor" />
</mvc:interceptors>

</beans>





In my controller I am trying to bind 'Device'




public String showUserPage(Principal principal,
@RequestParam(value="userid") Long userid,
ModelMap model,
Device device){



but I am getting the following exception.

org.springframework.beans.BeanInstantiationExcepti on: Could not instantiate bean class [org.springframework.mobile.device.Device]: Specified class is an interface


Any help greatly appreciated.

Keith Donald
May 13th, 2011, 12:25 PM
Hmm. for some reason it seems the DeviceWebArgumentResolver is not getting picked up. Make sure you don't have any other AnnotationMethodHandlerAdapter beans floating around from your existing app. You might want to set a breakpoint on setCustomWebArgumentResolvers method of that class and see what gets injected there. Also I'd recommend referring to the lite-showcase sample app.

Nigel W
May 13th, 2011, 04:11 PM
Thanks again,

I have used the sample but as you correct pointed out I also had.




<bean class="org.springframework.web.servlet.mvc.annotation.Def aultAnnotationHandlerMapping" />


<bean class="org.springframework.web.servlet.mvc.annotation.Ann otationMethodHandlerAdapter" >
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJac ksonHttpMessageConverter" />
</list>
</property>
</bean




I have removed AnnotationMethodHandlerAdapter

and used




<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.mobile.device.DeviceWebArgumen tResolver" />
</mvc:argument-resolvers>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJac ksonHttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>



This seems to work.

I assume I can/should leave DefaultAnnotationHandlerMapping ?

Nigel W
May 13th, 2011, 05:51 PM
Also another question - does LiteDeviceResolver find the IPad as 'mobile' ?

Nigel W
May 14th, 2011, 07:19 AM
Realising the answer to my own question about IPADs (ie. will not be seen a 'mobile').

I decided to move to WURFL.

So I changed to:




<mvc:interceptors>
<!-- On pre-handle, use WURFL to detect the device that originated the web request -->
<bean class="org.springframework.mobile.device.DeviceResolverHa ndlerInterceptor">
<constructor-arg>
<!-- Inject a WurflDeviceResolver that populates its device repository from the specified file locations -->
<device:wurfl-device-resolver root-location="/WEB-INF/wurfl/wurfl-2.0.30.zip" patch-locations="/WEB-INF/wurfl/web_browsers_patch.xml" />
</constructor-arg>
</bean>
</mvc:interceptors>



Having set up the zip and xml files.

Changed:




public String showUserPage(Principal principal,
@RequestParam(value="userid") Long userid,
ModelMap model,
Device device){


file to

import net.sourceforge.wurfl.core.Device;

but I am now getting:

org.springframework.beans.BeanInstantiationExcepti on: Could not instantiate bean class [net.sourceforge.wurfl.core.Device]: Specified class is an interface


My mvc:annotation-driven is:



<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.mobile.device.DeviceWebArgumen tResolver" />
</mvc:argument-resolvers>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJac ksonHttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>


I appear to have a binding issue.

Again any help appreciated.

Keith Donald
May 14th, 2011, 08:11 AM
If you're using mvc:annotation-driven, you should not have DefaultAnnotationHandlerMapping or AnnotationMethodHandlerAdapter registered manually: this element registers them for you. Please refer to the wurfl-showcase sample and test it out and see how it's different then yours.

Keith

Nigel W
May 14th, 2011, 11:27 AM
Thanks again.

Moving forward but still a problem.

What I am confused about - and the WURFL showcase does not cover this - is for the WURFL case how do you "inject the Device into your @Controller".

I have this working for the non-WURFL case but cannot seem to get it to work when I move to the WURFL case.

Keith Donald
May 14th, 2011, 12:19 PM
Well, the WURFL showcase shows injection of a SitePreference, which is done using the same WebArgumentResolver machinery that the DeviceWebArgumentResolver uses. Something has to be wrong with your configuration. Fundamentally, a DeviceWebArgumentResolver MUST be registered with the AnnotationMethodHandlerAdapter that is used to invoke @Controllers dispatched by the DispatcherServlet. Having a duplicate AnnotationMethodHandlerAdapter floating around in your context that is not configured properly can definitely cause this problem.

You might want to try the following test:
- Take wurfl-showcase and try injecting a Device into a @Controller method. It should fail.
- Add DeviceWebArgumentResolver to the set of web-argument-resolvers, alongside SitePreferenceWebArgumentResolver, and try your @Controller test again. It should work.

Something has to be wrong with your configuration somewhere.

Nigel W
May 15th, 2011, 01:39 AM
Found the issue - thanks for all the help - I had not noticed that I needed to change.



public String showUserPage(Principal principal,
@RequestParam(value="userid") Long userid,
ModelMap model,
Device device){


to




public String showUserPage(Principal principal,
@RequestParam(value="userid") Long userid,
ModelMap model,
WurflDevice device){


Note: An update to the 'spring mobile' documentation might be useful ?

Keith Donald
May 15th, 2011, 09:35 AM
WurflDevice is not required there, a org.springframework.mobile.Device reference will work fine as long as the DeviceWebArgumentResolver is registered properly. You can review the code of DeviceWebArgumentResolver to see this for yourself. Of course, if you need a WurflDevice, you can inject it as well.

Keith

Keith Donald
May 15th, 2011, 09:41 AM
Looking back at this thread, it looks like you were trying to import net.sourceforge.wurf.core.Device. This will definitely NOT work, as this is part of the WURFL library. You can only import implementations of the Spring Mobile Device abstraction: org.springframework.mobile.Device, which includes the interface itself as well as the specific WurflDevice implementation, which is a Spring Mobile wrapper around net.sourceforge.wurfl.core.Device.

Keith

Keith Donald
May 15th, 2011, 09:44 AM
Just out of curiosity, did you actually test out the LiteDeviceResolver from a iPad User Agent and you ended up with a non-mobile version of your site? If so, that would be a defect in the LiteDeviceResolver implementation. If you could open a JIRA reporting the problem, that would be helpful.

Keith

Nigel W
May 15th, 2011, 12:50 PM
Thanks again,

I have ended up needing to test for 'touchscreen' so I did need pointing_method in WURFL.

I imported the following

import org.springframework.mobile.device.wurfl.WurflDevic e;

and had



public String showUserPage(Principal principal,
@RequestParam(value="userid") Long userid,
ModelMap model,
WurflDevice device)


This seems to work ok so far.

I believe I did test an IPAD user-agent (simulated with Firefox user-agent addon) on the LiteDeviceResolver and it did not pick it up as 'mobile'.

I will retest and try and raise a JIRA.