Uploaded image for project: 'Aries'
  1. Aries
  2. ARIES-1288

ClassCastException with proxy set in bean of generic class

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • blueprint-core-1.4.2
    • blueprint-core-1.4.4
    • Blueprint
    • None

    Description

      I have a blueprint configuration as follows (actually from a third-party application):

      <?xml version="1.0" encoding="UTF-8"?>
      <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0"
                 xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"
                 xsi:schemaLocation="
                 http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
                 http://aries.apache.org/xmlns/jpa/v1.0.0 http://aries.apache.org/xmlns/jpa/v1.0.0
                 http://aries.apache.org/xmlns/transactions/v1.0.0 http://aries.apache.org/xmlns/transactions/v1.0.0">
      
          <bean id="meterDaoBean" class="com.third.party.impl.dao.jpa.JpaMeterDao">
              <jpa:context unitname="MeterUnit" property="entityManager" />
          </bean>
      
          <reference id="securityService" interface="com.third.party.api.SecurityService" availability="optional"/>
      
          <bean id="secureMeterDaoBean" class="com.third.party.impl.dao.secure.SecureMeterDao">
              <property name="dao" ref="meterDaoBean" />
              <property name="securityService" ref="securityService" />
          </bean>
      
          <bean id="meterBean" class="com.third.party.impl.MeterServiceImpl">
              <tx:transaction method="*" value="Required" />
      
              <property name="meterDao" ref="secureMeterDaoBean" />
          </bean>
      
          <service ref="meterBean" interface="com.third.party.api.MeterService"/>
      
      </blueprint>
      

      ...and the (for this issue relevant) class definitions look as follows:

      public interface CrudDao<T> {
      }
      
      public abstract class SecureDao<T, R extends CrudDao<T>> implements CrudDao<T> {
          protected R dao;
      
          // ...
      
          public void setDao(R dao) {
              this.dao = dao;
          }
      }
      
      public interface MeterDao extends CrudDao<MeterEntity> {
      }
      
      public class JpaMeterDao extends JpaCrudDao<MeterEntity> implements MeterDao {
      }
      
      public class SecureMeterDao extends SecureDao<MeterEntity, MeterDao> implements MeterDao {
      
          // ...
      
          public MeterEntity get(String id) {
              // some security stuff...
              dao.get(id);
          }
      }
      


      ...now with that usage of generics the proxy that gets created for the "dao" member in the SecureMeterDao bean instance only implements CrudDao, but not MeterDao.

      So, although the initial blueprint setup of beans and services is fine, any call traveling through the SecureMeterDao results in a ClassCastException:

      java.lang.ClassCastException: Proxyf427f861_7a7d_41e8_98c7_a09aea99f756 cannot be cast to com.third.party.impl.dao.MeterDao
      	at com.third.party.impl.dao.secure.SecureMeterDao.get(SecureMeterDao.java:47)
      	at com.third.party.impl.MeterServiceImpl.get(MeterServiceImpl.java:96)
      	at Proxy8bef53d7_0df3_4724_a67c_fb296af2aee2.get(Unknown Source)
      	at Proxya8f9ae87_fa39_42ae_bf11_baa82efa76cc.get(Unknown Source)
      	...
      

      Attachments

        Activity

          People

            gnodet Guillaume Nodet
            ancoron Ancoron Luciferis
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: