Announcement Announcement Module
Collapse
No announcement yet.
Problem Initialising Map Collection Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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.

    Comment


    • #3
      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?

      Comment


      • #4
        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...

        Comment


        • #5

          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.

          Comment


          • #6
            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.

            Comment


            • #7
              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...

              Comment


              • #8
                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?

                Comment


                • #9
                  ..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.

                  Comment


                  • #10
                    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?

                    Comment


                    • #11
                      Hi Marten,

                      Upon further reading, I realised that you were talking about Automatic DI. I have adapted my program to do as such. Yes, the code looks cleaner, because I no longer have to do getInstance(), it's automatically populated. Out of curiosity, what are the performance sacrifies with Automatic D.I as opposed to do it the convential way using Java? Would you still recommend this approach for an application that has millions of hits per second?

                      Comment


                      • #12
                        Well you are using IoC (Inversion of Control) however you are doing a dependency lookup and not dependency injection.

                        There is only a performance hit on startup as your beans are only initialized once (in general services and daos should be singletons). Also which form of DI (annotations, java, xml) you use doesn't really matter and mainly boils down to personal preference. (I still like XML for the general configuration and annotations in the web layer).

                        Comment


                        • #13
                          Thanks for your information, I appreciate it. However, according to the knowledge that I have IoC & DI work together: IoC is object decoupling concept and DI is the binding mechasim of objects. According to Wiki definition http://en.wikipedia.org/wiki/Inversion_of_control :

                          ...Inversion of Control (IoC) is an object-oriented programming practice where the object coupling is bound at run time by an assembler object and is typically not known at compile time ... the binding process is achieved through dependency injection...

                          Comment


                          • #14
                            Dependency Injection is a means to achieve IoC... IoC isn't only achieved through DI there are several different types of IoC which are all mentioned on the wiki page you link to. The key is that the object needing the dependencies doesn't now which (concrete type) dependency it needs (stub, mock, database or whatever implementation).

                            Comment


                            • #15
                              Thanks Marten!

                              Comment

                              Working...
                              X