Page 1 of 1

Extending Services and adding new method.

Posted: Sat Jun 28, 2014 5:38 am
by adarshkkumar
Hi,

What is the best way to extend an existing service eg: CustomerServiceImpl to MyCustomerServiceImpl and add couple of new methods to it and override some from CustomerServiceImpl . At run time how can I get an instance of MyCustoemrServiceImpl ?

I tried the following but failed,
public interface MyCustomerService extends CustomerService{
my_Method_here
}

MyCustomerServiceImpl extends CustomerServiceImpl implements MyCustomerService {

}
and overriding BLC CustomerService with my in spring ApplicationContext xml file.
Where ever required I try to typecast CustomerService to MyCustomerService which gives me a typecast exception:
java.lang.ClassCastException: $Proxy156 cannot be cast to com.sample.MyCustomerService

Re: Extending Services and adding new method.

Posted: Sun Jun 29, 2014 7:57 pm
by phillipuniverse
Because the root class (CustomerServiceImpl) has some @Transactional methods, Spring will proxy instances of it. The default proxying method is to only proxy interfaces and not implementations, so it will never work to try to cast an injected blCustomerService to MyCustomerServiceImpl (just like you could never cast it to CustomerServiceImpl).

Instead, if you want to expose some things from MyCustomerServiceImpl you will have to put them on the MyCustomerService interface and just cast to that.

You could also just inject the MyCustomerService bean like this:

Code: Select all

public class SomeBean {
    @
Resource(name "blCustomerService")
    protected 
MyCustomerService customerService;
}
 


but you cannot do something like this:

Code: Select all

public class SomeBean {
    @
Resource(name "blCustomerService")
    protected 
MyCustomerServiceImpl customerService;
}
 


If you really want Spring to proxy implementations, you can tell Spring to use CGLIB instead of normal JDK dynamic proxies by adding this to any applicationContext.xml:

Code: Select all

<tx:annotation-driven proxy-target-class="true"/>


You will also need CGLIB as a dependency:

Code: Select all

<dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib</artifactId>
   <version>3.1</version>
</dependency>


I think the reason that Spring uses JDK proxying OOB because of portability (it's baked into the JDK).

Re: Extending Services and adding new method.

Posted: Mon Jun 30, 2014 6:01 am
by adarshkkumar
Hi ,
Thanks for the reply.

Code: Select all

public interface MyCustomerService extends CustomerService {
// my new methods
}


public class MyCustomerServiceImpl extends CustomerServiceImpl implements MyCustomerService{
// my new methods implementations
}

myappcont.xml

Code: Select all


<bean id="blCustomerService" class="com.mypackage.MyCustomerServiceImpl"></bean>


And like you said im using the following

Code: Select all


@Resource(name = "blCustomerService")
protected MyCustomerService myCustomerService;

But still i'm getting the following error

Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'blCustomerService' must be of type [com.mypackage.MyCustomerService ],but was actually of type [$Proxy156]

Re: Extending Services and adding new method.

Posted: Sun Jul 27, 2014 12:38 am
by surfratwalt
Hi, I had this exact same problem when overriding a Service class to add my own methods.

I discovered that declaring the overridden bean in the default core:applicationContext-entity.xml file caused this issue for me (in case it is your issue too). When I moved the declaration into applicationContext.xml, I had no issue with the framework loading my bean override.

/core/src/main/resources/applicationContext.xml

Code: Select all

...
<bean id="blFulfillmentOptionService" class="example.order.service.MyFulfillmentOptionServiceImpl"/>


I didn't look too deep into it, but I presumed that this was the result of how broadleaf handles its blMergedEntityContexts defined in the site app, which uses the applicationContext-entity.xml file.

It's defined as follows,

Code: Select all

<!-- Set up custom entity overrides. These are defined in core/src/main/resources -->
    <bean id="blMergedEntityContexts" class="org.springframework.beans.factory.config.ListFactoryBean">
        <property name="sourceList">
            <list>
                <value>classpath:applicationContext-entity.xml</value>
            </list>
        </property>
    </bean>


Hope this helps.

Re: Extending Services and adding new method.

Posted: Fri Jul 15, 2016 3:15 pm
by SantoDE
Hey guys,

I currently try exactly the same. Have an own Interface which extends the CatalogService Interface and then let my own Service implement my Interface and my methods. However, it requires me to take ALL methods into my service which I definitely don't want to do.

I just wanna add one method.

Additionally, my code is not able to "get" my new method. It always errors me with "no symbol found". Any help?

Thanks guys!

Re: Extending Services and adding new method.

Posted: Tue Jul 25, 2017 2:42 pm
by phillipuniverse
If you just want to add a method, you should not extend or re-implement the entire CatalogService. That's unnecessary, you just need a Spring component that has an EntityManager that does whatever you want.

The Broadleaf forums are being retired as a readonly archive of questions. For active discussions and questions, check out the broadleaf-commerce tag on Stack Overflow which is actively monitored by the Broadleaf team.