New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support escaping placeholder prefix in property placeholders [SPR-4953] #9628
Comments
Timo Thomas commented Apache Jakarta Commons-Lang has a similar technology known as "StrSubstitutor" (org.apache.commons.lang.text.StrSubstitutor). There, the default escape character is "$", but it is configurable (independently from the prefix and suffix). I'm using StrSubstitutor on expressions in bean properties, and if there is no escaping, the only (ugly) option left for me is to change one of the prefixes. IMHO not having an escape character nowadays should be considered as a production-critical feature (what if changing the prefix is not an option? The workarounds necessary then are even more ugly) - if not as a bug. |
Eric Haszlakiewicz commented It seems that you can work around this by defining a property that has a value of '$'. e.g. and in the xml config to get a value of e.g. ' It's not pretty, but at least it works. |
Jim Utter commented The workaround does not work when the replacement needs the braces passed through. properties: wiring: or even "${var}foo}" or finally "${var}" still results in an error like: Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'id' defined in class path resource [applicationContext.xml]: Could not resolve placeholder 'foo' For me, I'd like to define concatenated strings like " |
Joshua Caplan commented The following blog post details a workaround that is available starting from Spring 3.0.x (or whenever SpEL was introduced): http://jazzjuice.blogspot.com/2011/06/escaping-property-placeholders-in.html I still agree that native escaping would be useful, though. |
Aleksandr Dubinsky commented Indeed, However, it is too long (5 characters!). It is poorly documented. It exists by sheer accident. It is really shocking that an escape sequence does not exist. Btw, the alternative of defining a different placeholder sequence is a really, really bad idea. That feature should NOT even be there. Allowing users to arbitrarily re-define the basic syntax of a language leads to confusion. |
Michel Nolard commented
Interesting fact: there is a lot advices on the net to use your trick -- often without referencing your post properly, but this does not remove the need for this issue to be solved anyway ! |
Jan Zidek commented In YAML configuration files,
then it is not ignored, but when the parameter is set by |
Bulk closing outdated, unresolved issues. Please, reopen if still relevant. |
I really would welcome a "fix" for this. In my app I externalized config into When I have I worked around this issue by putting @Value("${my.app.var}")
private String var;
public String getVar() {
return fixed(var);
}
private String fixed(String in) {
return in.replace('@', '$');
} |
Interestingly enough, core support for ignoring nested properties appears to have been in place since Spring Framework 3.2 via the However, Here's a JUnit Jupiter based test case for experimentation: package example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
@SpringJUnitConfig
// Using the following SpEL hack allows the test to pass.
// @TestPropertySource(properties = "my.app.var = #{'$'}{var}")
@TestPropertySource(properties = "my.app.var = ${var}")
class IgnoredPlaceholderTests {
@Value("${my.app.var}")
String value;
@Test
void test() {
assertThat(value).isEqualTo("${var}");
}
@Configuration
static class Config {
@Bean
static PropertySourcesPlaceholderConfigurer pspc() {
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
pspc.setIgnoreUnresolvablePlaceholders(true);
return pspc;
}
}
} @jhoeller, what do you think about either introducing support for escaping placeholders or providing a mechanism for configuring the |
it's amazing the issue lasts for more than ten years. When I use sharding-jdbc which configuration also need '${xxx}', I faced this problem. |
Will it be fixed at all? |
Any progress? Any comment? :) |
The team currently plans to look into escaping support in the 6.0.x timeline. |
In the interim, you may find it useful to ignore unresolvable placeholders when using That fix will be available in |
Chris Lee opened SPR-4953 and commented
There is presently no way to inject a placeholder expression (
${...}
) that won't be picked up byPropertyPlaceholderConfigurer
. Ideally we should be able to inject a string that contains${...}
for later use in its target bean without involvement fromPropertyPlaceholderConfigurer
.Perhaps a simple escape mechanism using the conventional backslash, such as
"The current value is \\${...}"
would suffice.Affects: 2.5.4, 2.5.5
11 votes, 5 watchers
The text was updated successfully, but these errors were encountered: