Announcement Announcement Module
Collapse
No announcement yet.
Problem with Domain Objects DI Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem with Domain Objects DI

    I have been experimenting with domain objects dependency-injection(DI) but without much success. I am using the latest spring 3.0.0. Here are the codes:

    Account.java
    Code:
    package com.simple.busobj;
    @Component
    public class Account
    {
    	private String lastName = null;
    	private String firstName = null;
    	private int age = 0;
    	private String position = null;
    	private String level = null;
    
    	public Account (String lastName, String firstName, int age,
    			String position, String level) 
    	{
    		this.lastName = lastName;
    		this.firstName = firstName;
    		this.age = age;
    		this.position = position;
    		this.level = level;
    	}
    }
    Teller.java
    Code:
    package com.simple.busobj;
    @Configurable(dependencyCheck=true)
    public class Teller
    {
    	@Autowired
    	private AccountService accountService;
    
    	public Teller()
    	{
    	}
    
    	public void debit(Account account, Double amount)
    	{
    		accountService.debit(account, amount);
    	}
    
    	public void deposit(Account account, Double amount)
    	{
    		accountService.deposit(account, amount);
    	}
    }
    AccountService.java
    Code:
    package com.simple.service;
    @Service
    public class AccountService
    {
    	private static Log log = LogFactory.getLog(AccountService.class);
    
    
    	public AccountService()
    	{
    	}
    
    	public void debit(Account account, Double amount)
    	{
    	 log.info("Debiting Account: [" + account + 
                   "] with Amount: [" + amount + "]");		
    	}
    
    	public void deposit(Account account, Double amount)
    	{
    		log.info("Depositing Account: [" + account + 
                     "] with Amount: [" + amount + "]");
    	}
    }
    Main.java
    Code:
    public class Main
    {
    	public static void main (String [] args) throws Exception
    	{
    	     ApplicationContext ctx = new 
                   ClassPathXmlApplicationContext("classpath:simple-di.xml");
    
    		Account account = new Account("Smith", "John", 50, "Manager", "Senior");
    
    
    		// expected dependency injection (DI) 
    		// AccountService object into
    		// the teller object, but didn't happen
    		Teller teller = new Teller();
    
    		teller.debit(account, new Double(50.99));
    	}
    }
    simple-di.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:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    	<bean id="accountService" class="com.fundserv.simple.service.AccountService" scope="prototype"/>
    
    	<context:spring-configured/>
    
    </beans>

    Here is the runtime error (NullPointerException)

    run:
    [java] [2010-02-03 21:43:40,297][support.ClassPathXmlApplicationContext][INFO ] Refreshing org.springframework.context.support.ClassPathXmlAp plicationContext@1df38fd: startup date [Wed Feb 03 21:43:40 EST 2010]; root of context hierarchy
    [java] [2010-02-03 21:43:40,368][xml.XmlBeanDefinitionReader][INFO ] Loading XML bean definitions from class path resource [simple-di.xml]
    [java] [2010-02-03 21:43:40,560][support.DefaultListableBeanFactory][INFO ] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultL istableBeanFactory@56f631: defining beans [accountService,org.springframework.context.config. internalBeanConfigurerAspect]; root of factory hierarchy
    [java] Exception in thread "main" java.lang.NullPointerException
    [java] at com.fundserv.simple.busobj.Teller.debit(Teller.jav a:22)
    [java] at Main.main(Main.java:21)

    [java] Java Result: 1

    BUILD SUCCESSFUL
    Total time: 0 seconds

  • #2
    did you specify com.simple.busobj.Teller in your aop.xml file?

    Comment


    • #3
      Originally posted by bdangubic View Post
      did you specify com.simple.busobj.Teller in your aop.xml file?
      Why? Teller is just a pojo. It is not an advice at all.

      Comment


      • #4
        Originally posted by zollen View Post
        Why? Teller is just a pojo. It is not an advice at all.
        it's all in the documentation...

        http://static.springsource.org/sprin...tw-aop_dot_xml

        Comment


        • #5
          I have a different problem when using AnnotationConfigApplicationContext

          Above suggestions work as expected. However when I replace the following:

          ClassPathXmlApplicationContext("classpath:simple-di.xml");

          *with*

          AnnotationConfigApplicationContext(SimpleConfig.cl ass);

          Domain injection no longer works.

          Here are the codes:
          Account.java (same as above)
          AccountService.java (same as above)

          Main.java
          Code:
          public class Main
          {
                  public static void main (String [] args) throws Exception
                  {
                         ApplicationContext ctx = new AnnotationConfigApplicationContext(SimpleConfig.class);
          
                          Account account = new Account("Smith", "John", 50, "Manager", "Senior");
          
                          // expected dependency injection (DI) 
                          // AccountService object into
                          // the teller object, but didn't happen
                          Teller teller = new Teller();
          
                          teller.debit(account, new Double(50.99));
                   }
          }
          Code:
          SimpleConfig.java
          
          @Configuration
          @ImportResource({"classpath:simple-di.xml"})
          public class SimpleConfig 
          { }
          Teller.java
          Code:
          @Configurable(dependencyCheck=true)
          public class Teller
          {
                  @Autowired
                  private AccountService accountService;
          
                  public void debit(Account account, Double amount)
                  {
                          accountService.debit(account, amount);
                  }
          
                  public void setAccountService(AccountService service)
                  {
                          this.accountService = service;
                  }
          }
          simple-di.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:context="http://www.springframework.org/schema/context"
              xmlns:aop="http://www.springframework.org/schema/aop"
              xsi:schemaLocation="http://www.springframework.org/schema/beans
                  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          	http://www.springframework.org/schema/aop
                  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                  http://www.springframework.org/schema/context
                  http://www.springframework.org/schema/context/spring-context-3.0.xsd">
          
          	<bean id="accountService" class="com.simple.service.AccountService" scope="prototype">
          		<aop:scoped-proxy />
          	</bean>
          
          	<bean class="com.simple.busobj.Teller">
          		<property name="accountService" ref="accountService"/>
          	</bean>
          
          	<context:load-time-weaver />
          
          </beans>
          This is the successful output when using ClassPathXmlApplicationContext("classpath:simple-di.xml");
          run:
          [java] [2010-02-08 22:36:38,881][support.ClassPathXmlApplicationContext][INFO ] Refreshing org.springframework.context.support.ClassPathXmlAp plicationContext@27391d: startup date [Mon Feb 08 22:36:38 EST 2010]; root of context hierarchy
          [java] [2010-02-08 22:36:38,968][xml.XmlBeanDefinitionReader][INFO ] Loading XML bean definitions from class path resource [simple-di.xml]
          [java] [2010-02-08 22:36:39,220][weaving.DefaultContextLoadTimeWeaver][INFO ] Found Spring's JVM agent for instrumentation
          [java] [2010-02-08 22:36:39,659][support.DefaultListableBeanFactory][INFO ] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultL istableBeanFactory@1e2ca7: defining beans [scopedTarget.accountService,accountService,com.fun dserv.simple.busobj.Teller#0,org.springframework.c ontext.weaving.AspectJWeavingEnabler#0,org.springf ramework.context.config.internalBeanConfigurerAspe ct,loadTimeWeaver]; root of factory hierarchy
          [java] [2010-02-08 22:36:40,615][service.AccountService][INFO ] Debiting Account: [FirstName: [John] LastName: [Smith] Age: [50] Position: [Manager] Level: [Senior]] with Amount: [50.99]
          This is the failure when using AnnotationConfigApplicationContext(SimpleConfig.cl ass);
          run:
          [java] [2010-02-08 22:39:10,724][annotation.AnnotationConfigApplicationContext][INFO ] Refreshing org.springframework.context.annotation.AnnotationC onfigApplicationContext@126e85f: startup date [Mon Feb 08 22:39:10 EST 2010]; root of context hierarchy
          [java] [2010-02-08 22:39:10,835][xml.XmlBeanDefinitionReader][INFO ] Loading XML bean definitions from class path resource [simple-di.xml]
          [java] [2010-02-08 22:39:11,129][annotation.ConfigurationClassEnhancer][INFO ] Successfully enhanced com.fundserv.simple.config.SimpleConfig; enhanced class name is: com.fundserv.simple.config.SimpleConfig$$EnhancerB yCGLIB$$59478e5f
          [java] [2010-02-08 22:39:11,151][support.DefaultListableBeanFactory][INFO ] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultL istableBeanFactory@30d082: defining beans [org.springframework.context.annotation.internalCon figurationAnnotationProcessor,org.springframework. context.annotation.internalAutowiredAnnotationProc essor,org.springframework.context.annotation.inter nalRequiredAnnotationProcessor,org.springframework .context.annotation.internalCommonAnnotationProces sor,simpleConfig,scopedTarget.accountService,accou ntService,com.fundserv.simple.busobj.Teller#0,org. springframework.context.weaving.AspectJWeavingEnab ler#0,org.springframework.context.config.internalB eanConfigurerAspect,loadTimeWeaver]; root of factory hierarchy
          [java] [2010-02-08 22:39:11,310][weaving.DefaultContextLoadTimeWeaver][INFO ] Found Spring's JVM agent for instrumentation
          [java] Exception in thread "main" java.lang.NullPointerException
          [java] at com.fundserv.simple.busobj.Teller.debit(Teller.jav a:22)
          [java] at Main.main(Main.java:26)

          [java] Java Result: 1
          Last edited by zollen; Feb 8th, 2010, 10:43 PM.

          Comment


          • #6
            My initial conclusion:

            There is a bug in AnnotationConfigApplicationContext(SimpleConfig.cl ass), that could stop LTW from working properly.

            Comment


            • #7
              Try the latest snapshot build of Spring. The lifecycle of @Configuration class processing has been improved recently with SPR-6611. I cannot guarantee that this change will provide the fix, but would very much appreciate your report as to whether it does.

              Also feel free to enter a JIRA issue for this and please attach a minimal test case that reproduces the problem. I'll be happy to look into it.

              Comment


              • #8
                Of course, now you can simply use the just-released Spring 3.0.1.

                Comment


                • #9
                  Thanks. I will retest the issue.

                  Comment


                  • #10
                    It works!

                    Yep. I just re-test the Java Config class loaded with multiple spring beans XML files, and one of the bean XML file defines <context:load-time-weaver />. The latest 3.0.1-A release seem to have fixed the bug when <context:load-time-weaver /> tag is used in conjunction with Java Config class. My Domain objects dependency injection is working now.

                    Thanks!

                    Comment


                    • #11
                      excellent!

                      Comment

                      Working...
                      X