Results 1 to 7 of 7

Thread: Problem with multiple contexts

  1. #1
    Join Date
    Oct 2005
    Posts
    27

    Default Problem with multiple contexts

    Hi there,

    I'm trying to setup a simple exception handling for my app. The app context is spread over several xml files. Consider the following code:
    Code:
        ...
        <aop:config>
            <aop:pointcut id="serviceMethod"
                expression="execution(* my.app.services.*.*(..))" />
            <aop:advisor pointcut-ref="serviceMethod"
                advice-ref="exceptionAdvice" />
        </aop:config>
    
        <bean id="exceptionAdvice"
              class="my.app.aop.MyExceptionAdvice" />
    
        <bean id="service"
              class="my.app.services.DummyServiceImpl" />
        ...
    Let's assume this code resides in aop-context.xml and let's assume I have a bunch of other context files. Now if I initialize the app using aop-context.xml as the single context descriptor - everything works fine, i.e. my Advice (see below) is called upon an exception. However if the other remaining xml files are added to app context, the Advice afterThrows method is not called.

    So, here's some code to make it all more clear:
    Code:
    // the advice
    public class MyExceptionAdvice
    implements ThrowsAdvice
    {
        public void afterThrowing(Exception e)
        {
            System.out.println("Yep, there was an exception, do something!");
        }
    }
    
    // service interface and implementation
    public interface DummyService
    {
        public void testService();
    }
    
    public class DummyServiceImpl
    {
        public void testService()
        {
             throw new IllegalArgumentException("WHOOOPS!");
         }
    }
    So, if I run a simple test app using the code below - everything works just fine:
    Code:
    public class AopTest
    {   
        public static void main(String[] args)
        {
            String[] paths = {"aop-context.xml"};
            ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(paths);  
            DummyService service = (DummyService) ctx.getBean("service");
            service.testService();
        }
    }
    This however doesn't - the advice doesn't receive any exceptions:

    Code:
    public class AopTest
    {   
        public static void main(String[] args)
        {
            String[] paths = {"aop-context.xml", "application-context", "jdbc-context.xml", "directory-context.xml"};
            ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(paths);  
            DummyService service = (DummyService) ctx.getBean("service");
            service.testService();
        }
    }

    Any ideas? It's really driving me mad

    TIA,
    jenner

  2. #2
    Join Date
    Jan 2005
    Location
    Sofia, Bulgaria
    Posts
    38

    Default

    Can you provide the other context configuration?
    Rostislav Georgiev

  3. #3
    Join Date
    Oct 2005
    Posts
    27

    Default

    Quote Originally Posted by rgeorgiev View Post
    Can you provide the other context configuration?
    Yep, see below (I'll split it up into three posts - the forum allows max. 10000 characters).
    The aop-context.xml is almost the same as above, only without the
    Code:
       <bean id="service"  class="my.app.services.DummyServiceImpl" />
    part.

    application-context.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
                               http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                               http://www.springframework.org/schema/aop
                               http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
    
        <bean id="placeholderConfig"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list><value>file:/etc/myapp/webapp.conf</value></list>
            </property>
        </bean>
    
        <bean id="userDao"
            class="my.app.data.dao.ldap.UserDaoLdap">
            <property name="ldapUserSearch">
                <ref bean="userSearch" />
            </property>
        </bean>
    
        <bean id="mailSender"
            class="org.springframework.mail.javamail.JavaMailSenderImpl">
            <property name="host">
                <value>${mail.smtp.server}</value>
            </property>
        </bean>
    
        <bean id="spamFilterMailSender"
            class="org.springframework.mail.javamail.JavaMailSenderImpl">
            <property name="host">
                <value>${spamfilter.mail.smtp.server}</value>
            </property>
        </bean>
    
        <bean id="mailboxService"
            class="my.app.services.MailboxServiceImpl">
            <property name="defaultRootFolderName">
                <value>${mail.imap.defaultRootFolder}</value>
            </property>
            <property name="imapServer">
                <value>${mail.imap.server.host}</value>
            </property>
            <property name="imapPort">
                <value>${mail.imap.server.port}</value>
            </property>
        </bean>
    
        <bean id="statisticsService"
            class="my.app.services.StatisticsServiceImpl">
        </bean>
    
        <bean id="unreadMessagesService"
            class="my.app.services.UnreadMessagesServiceImpl">
            <property name="mailboxService">
                <ref local="mailboxService" />
            </property>
            <property name="searchService">
                <ref local="searchService" />
            </property>
            <property name="messageConverterService">
                <ref local="messageConverterService" />
            </property>
        </bean>
    
        <bean id="readQuotaService"
            class="my.app.services.ReadQuotaServiceImpl">
            <property name="mailboxService">
                <ref local="mailboxService" />
            </property>
        </bean>
    
        <bean id="messageService"
            class="my.app.services.MessageServiceImpl">
            <property name="statisticsService">
                <ref local="statisticsService" />
            </property>
            <property name="mailboxService">
                <ref local="mailboxService" />
            </property>
            <property name="messageConverterService">
                <ref local="messageConverterService" />
            </property>
            <property name="userDao">
                <ref local="userDao" />
            </property>
            <property name="mailSender">
                <ref local="mailSender" />
            </property>
        </bean>
        
        <bean id="systemService"
            class="my.app.services.SystemServiceImpl">
            <property name="userDao">
                <ref local="userDao" />
            </property>
            <property name="messageService">
                <ref local="messageService" />
            </property>
            <property name="attachmentStorageService">
                <ref local="attachmentStorageService" />
            </property>
        </bean>
    
        <bean id="folderService"
            class="my.app.services.FolderServiceImpl">
            <property name="mailboxService">
                <ref local="mailboxService" />
            </property>
            <property name="messageConverterService">
                <ref local="messageConverterService" />
            </property>
        </bean>
    
        <bean id="searchService"
            class="my.app.services.SearchServiceImpl">
            <property name="mailboxService">
                <ref local="mailboxService" />
            </property>
            <property name="messageConverterService">
                <ref local="messageConverterService" />
            </property>
        </bean>
    
        <bean id="versionService"
            class="my.app.services.VersionServiceImpl">
            <property name="version">
                <value>0.7.7.3</value>
            </property>
        </bean>
    
        <bean id="mailFilterService"
            class="my.app.services.MailFilterServiceImpl">
            <property name="mailboxService">
                <ref local="mailboxService" />
            </property>
            <property name="mailSender">
                <ref local="spamFilterMailSender" />
            </property>
            <property name="mailFilterDao">
                <ref bean="mailFilterDao" />
            </property>
            <property name="whiteBlackListDao">
                <ref bean="whiteBlackListDao" />
            </property>
            <property name="notificationSender">
                <value>${spamassassin.mail.notificationSender}</value>
            </property>
            <property name="recipientHostPart">
                <value>${spamassassin.mail.recipientHostPart}</value>
            </property>
            <property name="recipientPrefix">
                <value>${spamassassin.mail.recipientPrefix}</value>
            </property>
            <property name="spamKeyword">
                <value>${spamassassin.spamKeyword}</value>
            </property>
            <property name="hamKeyword">
                <value>${spamassassin.hamKeyword}</value>
            </property>
        </bean>
        
        <bean id="messageConverterService"
            class="my.app.services.MessageConverterServiceImpl">
            <property name="attachmentStorageService">
                <ref local="attachmentStorageService" />
            </property>
    	    <property name="mimeFileTypeMap">
                <ref local="mimeFileTypeMap" />
            </property>
            <property name="userDao">
                <ref local="userDao" />
            </property>
            <property name="defaultCharset">
                <value>UTF-8</value>
            </property>
        </bean>
    
        <bean id="attachmentDownloadService"
            class="my.app.services.AttachmentDownloadServiceImpl">
           <property name="mailboxService">
                <ref local="mailboxService" />
           </property>
        </bean>
    
        <bean id="compoundService"
            class="my.app.services.CompoundServiceImpl">
            <property name="statisticsService">
                <ref local="statisticsService" />
            </property>
            <property name="folderService">
                <ref local="folderService" />
            </property>
            <property name="messageService">
                <ref local="messageService" />
            </property>
            <property name="readQuotaService">
                <ref local="readQuotaService" />
            </property>
            <property name="unreadMessagesService">
                <ref local="unreadMessagesService" />
            </property>
            <property name="searchService">
                <ref local="searchService" />
            </property>
            <property name="versionService">
                <ref local="versionService" />
            </property>
            <property name="mailFilterService">
                <ref local="mailFilterService" />
            </property>
            <property name="systemService">
                <ref local="systemService" />
            </property>
            
        </bean>
    
        <!--  services not exported by xfire -->
        <bean id="attachmentStorageService"
            class="my.app.services.SimpleAttachmentStorageService">
            <property name="chunkSize">
                <value>1024</value>
            </property>
            <property name="metadataSuffix">
                <value>.props.xml</value>
            </property>
            <property name="storagePath">
                <value>${attachments.storagePath}</value>
            </property>
        </bean>
        
        <bean id="mimeFileTypeMap"
            class="org.springframework.mail.javamail.ConfigurableMimeFileTypeMap">
            <property name="mappingLocation" value="file:/etc/mime.types" />
        </bean>
    </beans>
    Last edited by jenner; Mar 14th, 2007 at 03:35 AM.

  4. #4
    Join Date
    Oct 2005
    Posts
    27

    Default

    jdbc-context.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
                               http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                               http://www.springframework.org/schema/aop
                               http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
    
        <bean id="pgDataSource"
            class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="${jdbc.driver}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
            <property name="initialSize" value="${jdbc.poolsize}" />
        </bean>
    
        <bean id="hibernateFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource" ref="pgDataSource" />
            <property name="mappingResources">
                <list>
                    <value>MailMessageFilter.hbm.xml</value>
                    <value>MailMessageFilterRule.hbm.xml</value>
                    <value>WhiteBlackList.hbm.xml</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">
                        org.hibernate.dialect.PostgreSQLDialect
                    </prop>
                </props>
            </property>
        </bean>
    
        <bean id="mailFilterDao"
              class="my.app.data.dao.sql.MailFilterDaoHibernateImpl">
            <property name="sessionFactory" ref="hibernateFactory" />
            <property name="uniqQueryName" value="MailMessageFilter.getOneByUserId" />
            <property name="listQueryName" value="MailMessageFilter.listByUserId" />
            <property name="predQueryName" value="MailMessageFilter.getOneByPredecessorId" />
        </bean>
        
        <bean id="mailFilterRuleDao"
              class="my.app.data.dao.sql.MailFilterRuleDaoHibernateImpl">
            <property name="sessionFactory" ref="hibernateFactory" />
            <property name="uniqQueryName" value="MailMessageFilterRule.getOneById" />
            <property name="listQueryName" value="MailMessageFilterRule.listByFilterId" />
        </bean>
    
        <bean id="whiteBlackListDao"
              class="my.app.data.dao.sql.WhiteBlackListDaoHibernateImpl">
            <property name="sessionFactory" ref="hibernateFactory" />
        </bean>
        
        <bean name="openSessionInViewInterceptor"
            class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
            <property name="sessionFactory">
                <ref bean="hibernateFactory" />
            </property>
            <property name="flushModeName">
                <value>FLUSH_AUTO</value>
            </property>
        </bean>
        
    </beans>

  5. #5
    Join Date
    Oct 2005
    Posts
    27

    Default

    directory-context.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
                               http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                               http://www.springframework.org/schema/aop
                               http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
    
        <bean id="directoryContextFactory"
            class="my.app.ldap.InitialDirContextFactory">
            <property name="url">
                <value>${ldap.connection.url}</value>
            </property>
            <property name="bindDN">
                <value>${ldap.connection.bindDN}</value>
            </property>
            <property name="bindPassword">
                <value>${ldap.connection.bindPassword}</value>
            </property>
            <property name="connectionPoolEnabled">
                <value>${ldap.connection.connectionPoolEnabled}</value>
            </property>
        </bean>
    
        <bean id="userSearch"
            class="my.app.ldap.LdapUserSearch">
            <property name="searchScope">
                <value>${ldap.search.scope}</value>
            </property>
            <property name="baseFilter">
                <bean class="my.app.ldap.search.SimpleStringTerm">
                    <property name="attributeType" value="objectClass" />
                    <property name="value" value="dvagEmailPerson" />
                </bean>
            </property>
            <property name="uidAttribute">
                <value>${ldap.search.uidAttribute}</value>
            </property>
            <property name="directoryContextFactory">
                <ref local="directoryContextFactory" />
            </property>
        </bean>
    
    </beans>

  6. #6
    Join Date
    Oct 2005
    Posts
    27

    Default

    OK, I've managed to create a working setup. In my tests I'm calling systemService.testService() which just throws an IllegalStateException. The "systemService" bean is defined in application-context.xml. Now when I leave the setup as-is then I get a BeanCreationException:
    Code:
    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'systemService' defined in class path resource [application-context.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
    PropertyAccessException 1: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy9] to required type [my.app.service.MessageServiceImpl] for property 'messageService'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy9] to required type [my.app.service.MessageServiceImpl] for property 'messageService': no matching editors or conversion strategy found
    Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessException details (1) are:
    PropertyAccessException 1:
    org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy9] to required type [my.app.service.MessageServiceImpl] for property 'messageService'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy9] to required type [my.app.service.MessageServiceImpl] for property 'messageService': no matching editors or conversion strategy found
    Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy9] to required type [my.app.service.MessageServiceImpl] for property 'messageService': no matching editors or conversion strategy found
        at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:224)
        at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:139)
        at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:772)
        at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:606)
        at org.springframework.beans.AbstractPropertyAccessor.setPropertyValue(AbstractPropertyAccessor.java:49)
        at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:74)
        at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:57)
        at org.springframework.beans.factory.support.AbstractBeanFactory.applyPropertyValues(AbstractBeanFactory.java:840)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1026)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:809)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:425)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:250)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:247)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:161)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:273)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:346)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:92)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:77)
        at my.app.service.AopTest.main(AopTest.java:35)
    If I remove the <property name="messageService" local="messageService" /> the ApplicationContext is loaded just fine and my Advice is triggered in the right place.

    The problem is now - why do I get a BeanCreationException here? If I remove my <aop:config /> stuff from context everything works as it should, if I add it back - the BeanCreationException is thrown...
    Maybe my pointcut expression is crippled somehow? E.g. s.th. like 'execution(* my.app.*.*(..))' should take care of all exceptions which are thrown "underneath" my.app package, right? Well in my case the Advice isn't triggered at all. Only if I use 'execution(* my.app.services.*.*(..))' the Advice is triggered correctly (that is, if I don't inject the messageService bean into systemService).

    jenner.

  7. #7
    Join Date
    Aug 2006
    Location
    Brooklyn
    Posts
    556

    Default

    I think the exception says that the 'systemService' bean has a property called 'messageService' which couldn't be initialized with an aop proxy. This is so because the 'messageService' property of type [my.app.service.MessageServiceImpl] is not an interface and JDK Dynamic Proxies work on interfaces only. Either convert the field to an interface (preferable) or if not an option switch to CGLIB-based proxying using this:

    <aop:config proxy-target-class="true">
    ...
    </aop:conifg>

Posting Permissions

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