DWR

Problem when using DWR spring support within an OSGi environment

Details

  • Type: Bug Bug
  • Status: Open Open
  • Priority: Normal Normal
  • Resolution: Unresolved
  • Affects Version/s: 2.0.3
  • Fix Version/s: 4.0
  • Component/s: spring
  • Documentation Required:
    No
  • Description:
    Hide
    Hello,

    I saw a bug when using DWR 2 in an OSGI environment. It occurs when trying to directly expose an OSGi service configured with Spring DM as a DWR remote service like below. I don't have the problem when defining an intermediate class between dwr and the OSGi service referenced using Spring DM.

    <dwr:configuration>
        <dwr:create javascript="contactService" type="spring">
            <dwr:param name="beanName" value="contactService"/>
            <dwr:convert type="bean" class="com.manning.sdmia.directory.model.Contact"/>
        </dwr:create>
    </dwr:configuration>

    <dwr:controller id="dwrController" debug="true"/>

    <osgi:reference id="contactService"
            interface="com.manning.sdmia.directory.service.ContactService">
    </osgi:reference>

    I have the following error when calling a method on the service with DWR:

    10108 [http-8080-Processor4] WARN org.directwebremoting.impl.DefaultRemoter - Method execution failed:
    java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.directwebremoting.impl.ExecuteAjaxFilter.doFilter(ExecuteAjaxFilter.java:36)
    at org.directwebremoting.impl.DefaultRemoter$1.doFilter(DefaultRemoter.java:434)
    at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:437)
    at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:283)
            (...)

    The problem comes from the BeanCreator class when determining type of the bean corresponding to the call. Spring DM provides a proxy in front of the OSGi service. The method afterPropertiesSet of the BeanCreator class sets this type with the implementation class instead of the proxy class...

    To fix this bug, we can get this type directly using the proxy instance as shown below:

        public void afterPropertiesSet()
        {
            // make sure that either the bean or the beanId have been set correctly
            if (bean != null) {
                this.beanClass = bean.getClass();
            } else if (beanId != null) {
                //this.beanClass = beanFactory.getType(beanId);
                this.beanClass = beanFactory.getBean(beanId).getClass(); <----------------
            } else {
                throw new FatalBeanException(
                        "You should either set the bean property directly or set the beanId property");
            }

            // make sure to handle cglib proxies correctly
            if(AopUtils.isCglibProxyClass(this.beanClass)) {
                this.beanClass = this.beanClass.getSuperclass();
            }
        }

    Thierry
    Show
    Hello, I saw a bug when using DWR 2 in an OSGI environment. It occurs when trying to directly expose an OSGi service configured with Spring DM as a DWR remote service like below. I don't have the problem when defining an intermediate class between dwr and the OSGi service referenced using Spring DM. <dwr:configuration>     <dwr:create javascript="contactService" type="spring">         <dwr:param name="beanName" value="contactService"/>         <dwr:convert type="bean" class="com.manning.sdmia.directory.model.Contact"/>     </dwr:create> </dwr:configuration> <dwr:controller id="dwrController" debug="true"/> <osgi:reference id="contactService"         interface="com.manning.sdmia.directory.service.ContactService"> </osgi:reference> I have the following error when calling a method on the service with DWR: 10108 [http-8080-Processor4] WARN org.directwebremoting.impl.DefaultRemoter - Method execution failed: java.lang.IllegalArgumentException: object is not an instance of declaring class at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.directwebremoting.impl.ExecuteAjaxFilter.doFilter(ExecuteAjaxFilter.java:36) at org.directwebremoting.impl.DefaultRemoter$1.doFilter(DefaultRemoter.java:434) at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:437) at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:283)         (...) The problem comes from the BeanCreator class when determining type of the bean corresponding to the call. Spring DM provides a proxy in front of the OSGi service. The method afterPropertiesSet of the BeanCreator class sets this type with the implementation class instead of the proxy class... To fix this bug, we can get this type directly using the proxy instance as shown below:     public void afterPropertiesSet()     {         // make sure that either the bean or the beanId have been set correctly         if (bean != null) {             this.beanClass = bean.getClass();         } else if (beanId != null) {             //this.beanClass = beanFactory.getType(beanId);             this.beanClass = beanFactory.getBean(beanId).getClass(); <----------------         } else {             throw new FatalBeanException(                     "You should either set the bean property directly or set the beanId property");         }         // make sure to handle cglib proxies correctly         if(AopUtils.isCglibProxyClass(this.beanClass)) {             this.beanClass = this.beanClass.getSuperclass();         }     } Thierry

Activity

Hide
Jose Noheda added a comment - 04/Nov/09 6:31 AM
What's the actual class returned by getType() and by getBean().getClass() in this situation? The docs seem to imply that the result of both calls should be equal
Show
Jose Noheda added a comment - 04/Nov/09 6:31 AM What's the actual class returned by getType() and by getBean().getClass() in this situation? The docs seem to imply that the result of both calls should be equal
Hide
Thierry Templier added a comment - 05/Nov/09 12:31 AM
Hello,

It's very strange and it seems to be a bug of Spring...
If I add traces in the BeanCreator to get these informations, I have two different proxy instances:

beanFactory.getType(beanId) = class $Proxy3
beanFactory.getBean(beanId).getClass() = class $Proxy4

Feel free to tell if you want my complete workspace to make tests!

Thierry
Show
Thierry Templier added a comment - 05/Nov/09 12:31 AM Hello, It's very strange and it seems to be a bug of Spring... If I add traces in the BeanCreator to get these informations, I have two different proxy instances: beanFactory.getType(beanId) = class $Proxy3 beanFactory.getBean(beanId).getClass() = class $Proxy4 Feel free to tell if you want my complete workspace to make tests! Thierry

People

Dates

  • Created:
    04/Nov/09 6:03 AM
    Updated:
    06/Aug/10 9:10 PM