23

I'm facing "Circular Placeholder reference" exception while trying to run an executable jar file. Here's the detailed exception.


org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'postProcessProperties' defined in class path resource [applicationContext.xml]: Circular placeholder reference 'processor.core.poolsize' in property definitions
     [echo]     at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:287)
     [echo]     at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:75)
     [echo]     at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:663)
     [echo]     at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:638)
     [echo]     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:407)
     [echo]     at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
     [echo]     at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
     [echo]     at com.autodesk.postprocess.engine.PostProcessEngine.start(PostProcessEngine.java:39)
     [echo]     at com.autodesk.postprocess.engine.PostProcessEngine.main(PostProcessEngine.java:29)

This is a spring application which uses an external property file to read values at startup. Here's the spring definition. This has worked pretty well till now.


<bean id="propertyConfig"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_NEVER" />
        <property name="ignoreResourceNotFound" value="true" />
        <property name="locations">
            <list>
                <value>classpath:/postprocess.properties</value>
            </list>
        </property>
        <property name="properties">
            <props>
                <prop key="processor.core.poolsize">${processor.core.poolsize}</prop>
                <prop key="processor.max.poolsize">${processor.max.poolsize}</prop>
            </props>
        </property>
    </bean>

    <bean id="postProcessProperties"
        class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="properties">
            <props>
                <prop key="processor.core.poolsize">${processor.core.poolsize}</prop>
                <prop key="processor.max.poolsize">${processor.max.poolsize}</prop>
                <prop key="processor.polling.delay">${processor.polling.delay}</prop>
                <prop key="processor.polling.period">${processor.polling.period}</prop>
        </property>
    </bean>

I'm using shade plugin to generate the jar file. Here's a snippet


<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>1.7.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.test.postprocess.engine.PostProcessEngine</mainClass>
                                </transformer>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>META-INF/spring.handlers</resource>
                                </transformer>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>META-INF/spring.schemas</resource>
                                </transformer>
                            </transformers>
                            <filters>
                                <filter>
                                    <artifact>:</artifact>
                                    <excludes>
                                        <exclude>META-INF/.SF</exclude>
                                        <exclude>META-INF/.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

I'm not sure what's causing this issue, as I've used similar pattern before in other executable jar files.

Any pointer will be appreciated.

Thanks

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Shamik
  • 1,671
  • 11
  • 36
  • 64
  • I've got the same problem, would like to see more attention to this question. Did you solve this error? – dev_feed Mar 27 '14 at 11:58
  • In my case, I was actually missing the property in question. Problem was solved after adding it (as a dummy property, since I'm running locally). – Raphael Oct 13 '22 at 23:01

5 Answers5

28

Its probably late to answer this, but adding it for benefit of someone facing similar issue.

I was able to fix it by changing the key names. e.g.

 <prop key="processor.core.poolsize">${processor.core.poolsize}</prop>
 <prop key="processor.max.poolsize">${processor.max.poolsize}</prop>

Was changed to something like

<prop key="processor.core.poolsize">${core.poolsize}</prop>
<prop key="processor.max.poolsize">${max.poolsize}</prop>

property-placeholder key and the key of property value to be filtered cannot be same.

Pragmatic
  • 495
  • 1
  • 7
  • 11
15
Circular placeholder reference XXXX in property definitions

Above kind of exception will be thrown by the spring-framework when your property key name and value variable name are exactly the same.

Make sure your property should not look like key={$key}. Keeping different name for key and value will fix this issue.

Abhishek
  • 151
  • 1
  • 6
2

I was having the same issue when trying to run a spring integration test using SpringJUnit4ClassRunner. I was unsure of how to get my properties file loaded and after a few mis-steps, I found the @TestPropertySource annotation that allowed me to define the properties file(s) needed.

I had tried @PropertySource before that, and it does not work when you are running a spring integration test like this.

Hopefully this helps someone else.

Becky reamy
  • 96
  • 2
  • 11
0

It is probably not able to find the resource - postprocess.properties. Can you please remove this line -

<property name="ignoreResourceNotFound" value="true" />

Then if the resource is not found appropriate message should be displayed.

Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
0

In your java code, if you are using keys declared in some .properties or yaml file other than application.properties or application.yaml, you will get this exception when you try to run your Spring application without specifying the profile to use.

Solution: In my case, I'm using Spring Boot 2.4, here is one way to tell your app which profile(s) will be used:

Command Line:

java -jar -Dspring.profiles.active=DEV myapp.jar

If you're running your apps via an IDE such as IntelliJ:

Run -> Edit configurations

In your Spring Config, specify the profiles(s) that you want to be active (separated by commas):

enter image description here