Announcement Announcement Module
Collapse
No announcement yet.
Getting proxy class instead of class for a message consumer bean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Getting proxy class instead of class for a message consumer bean

    Hi!

    I have a message consumer defined in a bean as shown below (mdbQueryMessageBean). Everything works fine when the application is executed, but when I run my tests I get a

    NoSuchMethodException: $Proxy29.runMdbQuery(java.lang.String) (full stack trace below)

    For what I can see I'm getting a proxy instead of the proper bean.

    The same bean definitions are used for the application and the tests (on what relates to this), and the tests load the beans with a ClassPathXmlApplicationContext

    Any idea why I'm getting a proxy instead of the bean in this case? It does not happen for any other of my beans.

    If I try to get the bean from the context in the test class:

    MdbQueryMessageBean m = (MdbQueryMessageBean)getContext().getBean( "mdbQueryMessageBean" );

    I get a nice :

    $Proxy28 cannot be cast to com.aaa.bbb.listservice.MdbQueryMessageBean
    java.lang.ClassCastException: $Proxy28 cannot be cast to com.aaa.bbb.listservice.MdbQueryMessageBean


    Have been looking into it for quite a while and can't figure out what's going on. Some help greatly appreciated.

    Thanks a lot,

    Mon



    Code:
        context = new ClassPathXmlApplicationContext(
            new String[] { "classpath:directBeans.xml" } );
    Code:
        <bean id="mdbListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
            <property name="delegate" ref="mdbQueryMessageBean" />
            <property name="defaultListenerMethod" value="runMdbQuery" />
            <property name="defaultResponseDestination" ref="queryResponseQueue" />
        </bean>
    
        <bean id="mdbListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
            <property name="concurrentConsumers" value="2" />
            <property name="connectionFactory" ref="jmsFactory" />
            <property name="destination" ref="mdbQueue" />
            <property name="messageListener" ref="mdbListener" />
        </bean>
    
          <bean id="mdbQueryMessageBean" class="com.aaa.bbb.listservice.MdbQueryMessageBean">
            <property name="listDB" ref="ListDB" />
        </bean>
    Code:
        [junit] =13:53:31,233 WARN  [DefaultMessageListenerContainer:634] Execution of JMS message listener failed
        [junit] org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Failed to invoke target method 'runMdbQuery' with arg
    uments {Hi}; nested exception is java.lang.NoSuchMethodException: $Proxy29.runMdbQuery(java.lang.String)
        [junit]     at org.springframework.jms.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:459)
        [junit]     at org.springframework.jms.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:354)
        [junit]     at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:
    506)
        [junit]     at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:46
    3)
        [junit]     at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java
    :435)
        [junit]     at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListen
    erContainer.java:316)
        [junit]     at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListener
    Container.java:255)
        [junit]     at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessag
    eListenerContainer.java:887)
        [junit]     at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerCo
    ntainer.java:815)
    
    
    
        [junit]     at java.lang.Thread.run(Thread.java:619)
        [junit] Caused by: java.lang.NoSuchMethodException: $Proxy29.runMdbQuery(java.lang.String)
        [junit]     at java.lang.Class.getMethod(Class.java:1605)
        [junit]     at org.springframework.util.MethodInvoker.prepare(MethodInvoker.java:180)
        [junit]     at org.springframework.jms.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:451)
        [junit]     ... 9 more

  • #2
    If you use an interface, the proxy will assume the interface and then you can cast. There must be some AOP mechanism in place.

    Comment


    • #3
      Hi Jonnio,

      That's what I don't understand. As far as I can see I don't have any interfaces or AOP set up. MdbQueryMessageBean is just a class as seen below.

      I have another almost identical message consumer that is configured in the same way as far as I can see and works perfectly fine. So not sure where I'm going amiss....

      Thanks for your reply,

      Mon

      Code:
      @Transactional
      public class MdbQueryMessageBean {
          
          @PersistenceContext() private EntityManager em;    
          public void setEntityManager( EntityManager em ){
              this.em = em;
          }
         
          public boolean runMdbQuery( String msg ) {
              //[snip]
              log.debug( "I'm runMdbQuery " + msg );
              return true;
          }
      }

      Comment


      • #4
        Sorted!

        Hi!

        It turned out that the consumer bean needed to implement an interface for the unit tests to work, though it is not needed for the application itself to work.
        Just something like this does it:

        Code:
        public interface MdbQueryService {
            boolean runMdbQuery( MdbMessage msg );
        }
        
        public class MdbQueryMessageBean implements MdbQueryService{}
        Hope it helps someone else with the same issue!

        Mon

        Comment

        Working...
        X