Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
blueprint-core-1.4.2
-
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) ...