Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: Problem Initialising Map Collection

  1. #1
    Join Date
    Apr 2012
    Posts
    15

    Default Problem Initialising Map Collection

    Hi,

    I have a working Spring Application (MVC) and I want to initialise a Map property, but I am getting BeanCreationException. For example:

    Code:
    Error creating bean with name 'myprops2' defined in ServletContext resource [/WEB-INF/servlet-context.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ilt.myport.MySpecial]: Constructor threw exception; nested exception is java.lang.NullPointerException
    My servlet-content.xml file includes the following entry:

    Code:
    <beans:bean id="myprops2" class="com.ilt.myport.MySpecial">
      <beans:property name="myprops2">
         <beans:map>
            <beans:entry key="myFieldType" value="Special X Key" />
            <beans:entry key="myFieldActive" value="true" />
        </beans:map>
      </beans:property>
    </beans:bean>
    My class' snippet is:

    Code:
    // declaration
    private Map<String,String> myprops2;
    
    // setter for bean instantiation
    public void setMyprops2(Map<String, String> myprops2) {
       this.myprops2 = myprops2;
    }
    And of course, my classes are on the classpath as the MVC configuration works fine.

    Also, I would like to know if it is possible to initialise static collections, that is, intead of the above declaration, if I had:

    Code:
    private static Map<String,String> myprops2;
    
    public static void setMyprops(Map<String, String> myprops) {
       MySpecial.myprops = myprops;
    }
    ...would that be fine with the same bean configuration? If not, what is the work around?

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Also, I would like to know if it is possible to initialise static collections, that is, intead of the above declaration, if I had:
    No that isn't a property as specified by the Java Beans Specification.

    Also judging from you code I guess you are trying to access the myprops2 from your constructor, which isn't possible there needs to be an instance before you can call a method that goes for plain java and as such also for spring.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Apr 2012
    Posts
    15

    Default

    Thanks for your reply.

    I have tried to access the normal (non-static) myprops2 collection after an instance has been created, but upon inspecting myprops2, it is null. Is there any other configuration that I may have forgotten or an extra piece of code required or annotation required to make this initialisation happen? Please note that MySpecial class is a singleton class and do I get the following Spring log messages, which apparently indicates that it's picked up myprops in the xml file and ready for autowiring:

    Code:
    INFO : org.springframework.web.context.support.GenericWebApplicationContext - Refreshing Flow ApplicationContext [adminmenu]: startup date [Mon Aug 13 16:59:57 BST 2012]; parent: WebApplicationContext for namespace 'myport-servlet'
    
    INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    
    INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1ad4feb: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@156e5ed
    Any ideas what the problem is?

  4. #4
    Join Date
    Aug 2012
    Posts
    3

    Default

    How are you accessing your instance? Probably the instance you are using and the instanciated by Spring are not the same one.

    About your static matters... you shouldn't user static values if you have Spring singleton patterns...

  5. #5
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default


    I have tried to access the normal (non-static) myprops2 collection after an instance has been created, but upon inspecting myprops2, it is null. Is there any other configuration that I may have forgotten or an extra piece of code required or annotation required to make this initialisation happen? Please note that MySpecial class is a singleton class and do I get the following Spring log messages, which apparently indicates that it's picked up myprops in the xml file and ready for autowiring:
    As mentioned before you cannot access the collectionin the constructor that is basic java and has nothing to do with spring or whatever framework you use. It simply will not work... The instance is only available AFTER the execution of the constructor. If you really need it that hard, don't use setter injection but use constructor injection.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  6. #6
    Join Date
    Apr 2012
    Posts
    15

    Default

    Thanks Marten and Gotilio, both of your answers has helped me solve this problem. I have 2 more related questions:

    1. I have a 3rd party database access software (non-Hibernate) that needs initialising by injecting properties. As I am using Spring, I didn't want to use the standard Java File I/O nor the 3rd parties properties file loader Helper class, so as to take advantage of the Springer Dependency Injection. I have designed it as such that this 3rd party DAO instance is a singleton and static, so that all the other objects can access the data layer for necessary database operations. What do you guys recommend: either I use the standard Java I/O or 3rd party Helper class or just drop static altogether as Spring class are by default singletons?

    2. I have used the traditional way to access the Spring instance, that is:

    Code:
    ApplicationContext ctx = new ClassPathXmlApplicationContext("servlet-context.xml");
    instance = (MySpecial) ctx.getBean("myprops2");
    ...is there a way to avoid using new ClassPathXmlApplicationContext above as Spring MVC framework is already aware of the servlet-context.xml upon starting my application? Would using Annotations be more efficient and if so, how to configure it?

    Many thanks.

  7. #7
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    1. Please don't use a static singleton this will give you more trouble then its worth... Use spring to configure your objects and inject the dao. So basically neither of your suggestions.

    2. see 1, use dependency injection...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  8. #8
    Join Date
    Apr 2012
    Posts
    15

    Default

    Thanks. Regarding Q2: you wrote:

    see 1, use dependency injection...
    I thought that by doing:

    Code:
    ApplicationContext ctx = new ClassPathXmlApplicationContext("servlet-context.xml");
    instance = (MySpecial) ctx.getBean("myprops2");
    ...I was using dependency injection - please explain further? My question rephrased: how can I avoid a duplicating the reading of servlet-context.xml (which is read by the MVC / WebFlow framework upon starting my application)? Or is there no other way, but to do it as above?

    Also, as a side point, is calling ctx.getBean(...) for access to the the singleton Spring bean (by many objects) as efficient as wrapping this Spring bean to a normal (non-Static) singleton? I ask this, because I am not sure how efficient or what performance penalties there are by invoking getBean(...) many times (together with passing around the ApplicationContext object) as opposed to calling just calling getInstance() method on the non-Static wrapped singleton?

  9. #9
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    ..I was using dependency injection - please explain further?
    No you aren't... If you start to mess around with static singletons and constructing your own instances of the ApplicationContext (which loads another instanceof the bean each time you do that) so you aren't using dependency injection. You are only injecting the dependencies into the dao you should also use dependency injection for the other objects that need the dao (you shouldn't use a static singleton (anti-pattern) for that).

    You shouldn't do either a getBean call nor a getInstance on oa static singleton you really should be doing dependency injection... You either do it correct or you shouldn't do it at all (IMHO that is). You should let the framework do the heavy lifting for you (ie inject all the dependencies an object needs) instead of trying to create a sort-of framework around it.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  10. #10
    Join Date
    Apr 2012
    Posts
    15

    Default

    Okay, I see. According to the Spring book I am using, it uses ctx.getBean(...) to do DI. So, what aspects of my code and xml file do I need to change or add for it to work that way that you suggest?

Tags for this Thread

Posting Permissions

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