PropertyPlaceholderConfigurer using ${...}

I have a Spring application that is deployed in several environments each having a set of property files that have environment-specific things like database credentials, caching settings etc.
In my spring context there is a PropertyPlaceholderConfigurer:


    <!-- Configuration of environment-specific properties -->
    <bean >
        <property name="locations">
            <list>
                <value>${config.dir}/database.properties</value>
                <value>${config.dir}/mail.properties</value>
                <value>${config.dir}/remoting.properties</value>
            </list>
        </property>
    </bean>




config.dir is passed to the application via command-line parameter: -Dconfig.dir=file:/some/path

It works just fine, including integration tests that use Spring JUnit runner.
However, IintelliJ shows me that config.dir variable is not resolved, as well as all properties are not found (and they are shown as unused when the properties file is opened).

How can I set config.dir variable so that IntelliJ can pick up the properties file?
7 comments

Have a look at http://youtrack.jetbrains.com/issue/IDEA-92348 - it is a feature request that was added in IDEA 12 to handle the exact case you describe. It has a link to a screencast showing how to do this. In a nutshell, you can add a properties file to the Application Context defined in the Spring Facet.

0

I have the same case:

    <bean id="propertyConfigurer"
          >
        <property name="locations">
            <list>
                <value>file:///${XPMHOME}/px-common/common.properties</value>
                <value>file:///C:/work/xpm_home/px-common/env.properties</value>
            </list>
        </property>
    </bean>


but to use the suggestion on that link, now I have to add those properties files to every spring context, in every module of my project.  Could be over 30+ of those, plus, there is no way to extend that to the whole team.  We all have to do it.  Not fun.

My question is why doesn't intellij look at the users profile for values like XPMHOME, and replace it, and then, why can intellij simply pull from a file based location (also not available).  E.g.

    <profiles>
        <profile>
            <id>local-process</id>
            <properties>
                <XPMHOME>C:/work/xpm_home</XPMHOME>
               ...
            </properties>
        </profile>
...
    </profiles>
0

This looks like http://youtrack.jetbrains.com/issue/IDEA-101476 (using Maven).

there is now way to extend that to the whole team.

What exactly do you mean? Spring configuration incl. defined .properties file(s) is stored in .iml files which can (and should) be shared across team.

0

Thank you Yann,

It does appear to be exactly the same.  I tend to agree with Constantine Vasilyev on this matter though.  I like the idea that I can have my own personal maven settings.xml with contents like:
<profiles>
        <profile>
            <id>local-process</id>
            <properties>
                <XPMHOME>C:/work/xpm_home</XPMHOME>
...
            </properties>
        </profile>

</profiles>

and then refer to that from within the spring config files as follows:
    <context:property-placeholder location="file:///${XPMHOME}/px-common/env.properties"/>


or


    <bean id="propertyConfigurer"
        >
        <property name="locations">
            <list>
                <value>file:///${XPMHOME}/px-common/common.properties</value>
                <value>file:///${XPMHOME}/px-common/env.properties</value>
            </list>
        </property>
    </bean>


and then have the spring values get populated when referred to as follows:

    <bean id="mongo" >
        <constructor-arg index="0" type="java.lang.String">
            <value>${mongodb.host}</value>
        </constructor-arg>
        <constructor-arg index="1">
            <value>${mongodb.port}</value>
        </constructor-arg>
    </bean>


from within those files.  That leverages how folks generally use maven, and it allows very quick and seemless setup.  This new idea from IDEA that asks me to select the .properties file for every spring file (facet) is cumbersome. I have over 54 spring files, and I'm not eager to go set it up for all of them like that.  If someone did do that and share it with the rest of the team, that would still be kind of troublesome because we open our projects from different module levels, most of us, depending on what we are working on.  That makes the .iml files not very extensible to the rest of the team.  Rather than share the .iml files, we use the maven configurations and personal settings.xml as our 'source of truth'.  I think also, that there is some fear that if the .iml became misconfigured, then it has to be reconfigured once again.  I.e. it get re-imported from maven, so we like that as the single source of truth.

Is there a way to re-enable the functionality that Constantine and I liked so much?
0

This functionality only worked by accident, see my comment http://youtrack.jetbrains.com/issue/IDEA-101476#comment=27-461732

Never did IntelliJ IDEA's Spring support parse/understand the relationship between Maven profiles and PropertyPlaceholder keys resolving.


So how does your team share project-specific settings for IntelliJ IDEA? Not at all? How do you setup for Spring facets (XML, Code Config) or any other IDE specific framework configuration?

0

Thanks for your reply Yann,

I didn't gather it was an accident from your comment.  Even after my second reading, that isn't clear at all to me that it worked by accident.

Even if IDEA didn't pull it from maven profiles, it would be nice to pull it from somewhere like that.  One place that could be referenced, rather than configured for all 54 projects.

My team doesn't actually share project-specific Intellij IDEA settings.  Maybe that's bad, and maybe there are elements of productivity that could be achieved, that we are leaving on the table.

The way that we set up for Spring Facets, or Scala Facets is that intellij prompts that it has found new spring facets, and we accept them.  That's basically it.

I have over 54 spring files.  Can you see why I wouldn't want to select the feeder .properties files for all of those spring files?  Can you see how it would make sense to have the ability to use the local settings.xml file in this case?  intellij has this ability to open the users maven settings.xml file, so it definitely knows about it.  Seems like a natural extension of the users settings.

0

Brent, thanks for sharing your feedback. I fully agree that providing an out-of-the-box solution for this use case with Maven makes perfectly sense. Please watch/vote the issue to keep up to date.

I would definitely advise to evaluate sharing .iml and IDE configuration files - sharing inspection settings, formatting rules etc makes so much sense in a team. Using the provided auto-configuration for Spring or other frameworks as you do now might work quite well in some projects (so everyone can do it locally during initial setup of project), but from my experience this can be a huge pain in bigger projects or when large refactorings happen later. Also more complicated setups (e.g. using parent contexts in Spring facet) can only be configured manually, so sharing configuration is essential here.

0

Please sign in to leave a comment.