Results 1 to 6 of 6

Thread: Apache CXF, AOP, and dependency injection

  1. #1
    Join Date
    Feb 2010
    Posts
    14

    Default Apache CXF, AOP, and dependency injection

    Hello,

    Not sure if this is the place to post this, here is my problem:

    1. I have the following architecture (Apache CXF for webservices, service layer, spring roo, db)
    2. I created a simple LoggingAspect and specified the following execution:
    @Around("execution(* com.company.pkg.services.impl.*.*(..))")

    Here are my problems:
    1. One of my service methods has the following signature Long getSomething(), my other methods are void. With the LoggingAspect enabled and CXF present, void methods work, but the method returning a Long throws an exception. If I remove the LoggingAspect all methods work.
    2. For some reason the Autowired injected objects are null on services annotated with CXF @WebService tags.

    Has anyone seen anything similar or have any idea what maybe happening. I am baffled why the injected objects are null.

    FYI. I placed a breakpoint in the constructor of the service and on spring initialization the service gets initialized 3 times, while the injected object setter gets called once.

  2. #2
    Join Date
    Jun 2006
    Location
    SF Bay Area, California
    Posts
    524

    Default

    How does your around advice body look? I suspect that you may not be returning a right kind of object from it (typically you should have something to effect of "return pjp.proceed()").

    A bit more code might be helpful to resolve the other issue.

    -Ramnivas
    Ramnivas Laddad (Follow me on Twitter)
    AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available!

  3. #3
    Join Date
    Feb 2010
    Posts
    14

    Default

    Quote Originally Posted by ramnivas View Post
    How does your around advice body look? I suspect that you may not be returning a right kind of object from it (typically you should have something to effect of "return pjp.proceed()").

    A bit more code might be helpful to resolve the other issue.

    -Ramnivas
    Ramnivas,

    Here is the aspect code, I'll provide additional info on the second point tomorrow.

    package project.pkg.framework.spring;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;

    @Aspect
    public class LoggingAspect
    {
    private static Log log = null;

    @Around("execution(* project.pkg.service.TemplateService*.*(..))")
    public Object log(ProceedingJoinPoint call) throws Throwable
    {
    log = LogFactory.getLog(call.getClass());
    log.info("from logging aspect: entering method [" +call.toShortString()+"] with param:"+call.getArgs()[0]);
    Object point = call.proceed();
    log.info("from logging aspect: exiting method [" + call.toShortString() + "with return as:" +point);
    return point;
    }

    }

  4. #4
    Join Date
    Jun 2006
    Location
    SF Bay Area, California
    Posts
    524

    Default

    Could it be that your method takes zero argument and you are using getArgs()[0] leading to an ArrayIndexOutOfBoundsException?

    -Ramnivas
    Ramnivas Laddad (Follow me on Twitter)
    AspectJ in Action: Enterprise AOP with Spring Applications (2nd edition). Now available!

  5. #5
    Join Date
    Feb 2010
    Posts
    14

    Default

    Quote Originally Posted by ramnivas View Post
    Could it be that your method takes zero argument and you are using getArgs()[0] leading to an ArrayIndexOutOfBoundsException?

    -Ramnivas
    Ramnivas,

    Great catch, its one of those I've been staring at the code for too long Thanks !

    Regarding the second issues here is some code, its pretty much boiler plate but here goes, nothing fancy.

    1. EmailServiceImpl
    package services.impl;

    import javax.jws.WebService;

    import org.springframework.beans.factory.annotation.Autow ired;
    import org.springframework.stereotype.Service;

    import framework.ServiceContext;
    import services.EmailService;
    import services.exception.ServicesException;


    @Service
    @WebService(endpointInterface = "services.EmailService")
    public class EmailServiceImpl implements EmailService {

    @Autowired
    private transient org.springframework.mail.MailSender mailTemplate;

    @Override
    public void sendMessage(ServiceContext context, String mailFrom, String subject, String mailTo, String message)
    throws ServicesException
    {
    org.springframework.mail.SimpleMailMessage simpleMailMessage = new org.springframework.mail.SimpleMailMessage();
    simpleMailMessage.setFrom(mailFrom);
    simpleMailMessage.setSubject(subject);
    simpleMailMessage.setTo(mailTo);
    simpleMailMessage.setText(message);
    mailTemplate.send(simpleMailMessage);
    }
    }

    2. applicationContext.xml (generated by Roo)
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cxf="http://cxf.apache.org/core"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schem...ng-jee-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schem...ng-aop-3.0.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schem...g-task-3.0.xsd
    http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-3.0.xsd
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schem...ing-tx-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

    <!-- Enable message logging using the CXF logging feature -->
    <cxf:bus>
    <cxf:features>
    <cxf:logging/>
    </cxf:features>
    </cxf:bus>

    <!--
    This will automatically locate any and all property files you have
    within your classpath, provided they fall under the META-INF/spring
    directory. The located property files are parsed and their values can
    then be used within application context files in the form of
    ${propertyKey}.
    -->
    <contextroperty-placeholder location="classpath*:META-INF/spring/*.properties"/>

    <!--
    Turn on AspectJ @Configurable support. As a result, any time you
    instantiate an object, Spring will attempt to perform dependency
    injection on that object. This occurs for instantiation via the "new"
    keyword, as well as via reflection. This is possible because AspectJ
    is used to "weave" Roo-based applications at compile time. In effect
    this feature allows dependency injection of any object at all in your
    system, which is a very useful feature (without @Configurable you'd
    only be able to dependency inject objects acquired from Spring or
    subsequently presented to a specific Spring dependency injection
    method). Roo applications use this useful feature in a number of
    areas, such as @PersistenceContext injection into entities.
    -->
    <context:spring-configured/>

    <!--
    This declaration will cause Spring to locate every @Component,
    @Repository and @Service in your application. In practical terms this
    allows you to write a POJO and then simply annotate the new POJO as an
    @Service and Spring will automatically detect, instantiate and
    dependency inject your service at startup time. Importantly, you can
    then also have your new service injected into any other class that
    requires it simply by declaring a field for your service inside the
    relying class and Spring will inject it. Note that two exclude filters
    are declared. The first ensures that Spring doesn't spend time
    introspecting Roo-specific ITD aspects. The second ensures Roo doesn't
    instantiate your @Controller classes, as these should be instantiated
    by a web tier application context. Refer to web.xml for more details
    about the web tier application context setup services.

    Furthermore, this turns on @Autowired, @PostConstruct etc support. These
    annotations allow you to use common Spring and Java Enterprise Edition
    annotations in your classes without needing to do any special configuration.
    The most commonly used annotation is @Autowired, which instructs Spring to
    dependency inject an object into your class.
    -->
    <context:component-scan base-package="com.fox.dv">
    <context:exclude-filter expression=".*_Roo_.*" type="regex"/>
    <context:exclude-filter expression="org.springframework.stereotype.Control ler" type="annotation"/>
    </context:component-scan>

    <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
    <property name="driverClassName" value="${database.driverClassName}"/>
    <property name="url" value="${database.url}"/>
    <property name="username" value="${database.username}"/>
    <property name="password" value="${database.password}"/>
    </bean>
    <bean class="org.springframework.orm.jpa.JpaTransactionM anager" id="transactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
    <bean class="org.springframework.orm.jpa.LocalContainerE ntityManagerFactoryBean" id="entityManagerFactory">
    <property name="dataSource" ref="dataSource"/>
    </bean>


    <!-- CXF Web Services end points -->
    <jaxws:endpoint address="/Email" id="email" implementor="services.impl.EmailServiceImpl"/>

    <!-- Email Service setup -->
    <bean class="org.springframework.mail.javamail.JavaMailS enderImpl" id="mailSender">
    <property name="host" value="${email.host}"/>
    </bean>


    </beans>

  6. #6
    Join Date
    Feb 2010
    Posts
    14

    Default

    Quote Originally Posted by ramnivas View Post
    Could it be that your method takes zero argument and you are using getArgs()[0] leading to an ArrayIndexOutOfBoundsException?

    -Ramnivas
    Ramnivas, thanks !! that was it. I submitted additional info on item 2, but waiting for approval. Second pair of eyes always helps.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •