Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

1.parent-ctx.xml

<?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:c="http://www.springframework.org/schema/c"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="Bean1InParent" class="java.lang.String">
        <constructor-arg>
            <value>Bean in Parent App Context</value>
        </constructor-arg>
    </bean>
</beans>
  • child-ctx.xml

     <beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:c="http://www.springframework.org/schema/c"
         xmlns:p="http://www.springframework.org/schema/p"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
         <bean class="com.app.appcontext.hierarchy.MyClass" id="myclass">
             <property name="value">
                 <ref parent="Bean1InParent" />
             </property>
         </bean>
     </beans>
    

    Followings are the classes in com.app.appcontext.hierarchy.MyClass package:

    public class MyClass {
        private String value;
        public String getValue() {
            return value;
        public void setValue(String value) {
            this.value = value;
    

    Main class is that works :

    import org.springframework.context.support.GenericXmlApplicationContext;
    public class AppCtxHierarchyMain {
        public static void main(String[] args) {
            GenericXmlApplicationContext parent = new GenericXmlApplicationContext();
            parent.load("classpath:parent-ctx.xml");
            parent.refresh();
            GenericXmlApplicationContext child = new GenericXmlApplicationContext();
            child.load("classpath:child-ctx.xml");
            child.setParent(parent);
            child.refresh();
            MyClass cls = child.getBean("myclass", MyClass.class);
            System.out.println(cls.getValue());
            child.close();
    

    Another Main Class code that doesn't work :

    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class AppCtxHierarchyMain {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("parent-ctx.xml");
            ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext("child-ctx.xml");
            child.setParent(parent);
            child.refresh();
            MyClass cls = child.getBean("myClass", MyClass.class);
            System.out.println(cls.getValue());
            child.close();
    

    I am curious about the code that is not working . What is the difference here ?

    P.S. : Spring version 3.2.9

    Here is the exception occured :

    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myclass' defined in class path resource [child-ctx.xml]: Cannot resolve reference to bean 'Bean1InParent' while setting bean property 'value'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'Bean1InParent' is defined
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:326)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1417)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1158)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
        at com.airtel.appcontext.hierarchy.AppCtxHierarchyMain.main(AppCtxHierarchyMain.java:9)
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'Bean1InParent' is defined
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:570)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1114)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:279)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:320)
                    Try to use another constructor ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent).
    – OleksiiMLD
                    Aug 8, 2020 at 8:56
                    @OleksiiMLD : Yes that i already tried and that worked as well , but is there anything specific that given code is not working
    – optional
                    Aug 8, 2020 at 9:19
                    Not working means you have an exception or bean is not found. The constructor ClassPathXmlApplicationContext will refresh the context automatically, the child bean definition should fail as the parent is not found
    – Cyril G.
                    Aug 8, 2020 at 11:05
                    ok the reason is the one I explained in my previous comment: Bean1InParent is missing because the child context is refresh before the parent is set.
    – Cyril G.
                    Aug 10, 2020 at 4:33
    

    The bean is not found as ClassPathXmlApplicationContext will refresh the child context before the parent context is set. Then the bean creation will failed as Bean1InParent is missing. You need to pass the parent context in the constructor of child context.

    public class AppCtxHierarchyMain {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("parent-ctx.xml");
            ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext("child-ctx.xml", parent );
            MyClass cls = child.getBean("myClass", MyClass.class);
            System.out.println(cls.getValue());
    

    EDIT:

    You can also use the constructor with the argument refresh to false when creating the child context

    ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext(new String[] {"child-ctx.xml"}, false);
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

  •