Skip to content
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

Provide an alternative to @Value("\${foo}") for Kotlin projects #8061

Closed
sdeleuze opened this issue Jan 23, 2017 · 8 comments
Closed

Provide an alternative to @Value("\${foo}") for Kotlin projects #8061

sdeleuze opened this issue Jan 23, 2017 · 8 comments
Labels
status: declined A suggestion or change that we don't feel we should currently apply

Comments

@sdeleuze
Copy link
Contributor

As discussed in #5537 and this Stackoverflow question, Spring default property placeholder prefix is not a good fit with Kotlin because it is already used in the language for String interpolation and #{...} can't be used as a droppin replacement and has other meaning.

The current workaround I suggest to Kotlin users is to declare these customized PropertySourcesPlaceholderConfigurer that allow to support @Value("%{foo}") without breaking existing Java @Value("${foo}") or Kotlin @Value("\${foo}") annotations.

@Bean
fun kotlinPropertyConfigurer() = PropertySourcesPlaceholderConfigurer().apply {
    setPlaceholderPrefix("%{")
    setIgnoreUnresolvablePlaceholders(true)
}

@Bean
fun defaultPropertyConfigurer() = PropertySourcesPlaceholderConfigurer()

I suggest @Value("%{foo}") since that sounds a not so bad convention, but it could obviously be a different one.

It would be nice if that could be done by default (and documented) in Spring Boot 2.0, using for example @ConditionalOnClass(Unit.class) (kotlin.Unit is the Kotlin class equivalent for Void in Java).

Another way to tackle this issue could be to allow customizing such prefix with an application.properties property + configuring that by default for start.spring.ioKotlin projects, but I tend to think providing such default convention for Kotlin projects is more what I would expect from Spring Boot, but that's open to discussion ;-)

@sdeleuze sdeleuze changed the title Provide an alternative to @Value("\${foo}") for Kotlin projects Provide an alternative to @Value("\${foo}") for Kotlin projects Jan 23, 2017
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 23, 2017
@snicoll
Copy link
Member

snicoll commented Jan 23, 2017

We've moved almost full gears to @ConfigurationProperties and aren't really advising the use of @Value (I can see @dsyer objecting to that in a min). @Value is a Spring Framework feature and we don't do anything special in Spring Boot about it (AFAIK).

I'd be tempted to leave things as they are.

@dsyer
Copy link
Member

dsyer commented Jan 23, 2017

I don't think it matters if we advise using it or not. If it doesn't work in Kotlin we should try and support it, and the suggestion sounds pragmatic.

In Groovy you can just use '${foo}'. Is there no equivalent in Kotlin (a String literal with no replacements)?

@sdeleuze
Copy link
Contributor Author

In Kotlin you have to escape the $: @Value("\${foo}"), it's not the end of the world but it's ugly so Kotlin developers almost never write this in practice.

@dsyer
Copy link
Member

dsyer commented Jan 23, 2017

Ugliness is in the eye of the beholder, I suppose. It doesn't seem so bad to me, and it's a Spring annotation, so Spring dictates the contents, and if that means escaping, that's just the way it is.

I guess I agree with @snicoll after all (it's fine the way it is).

@sdeleuze
Copy link
Contributor Author

I understand, I guess we can just promote @ConfigurationProperties usage. Please just continue providing alternative to @Value like you did with @LocalServerPort in order to avoid situation when @Value is mandatory ;-)

@snicoll snicoll added status: declined A suggestion or change that we don't feel we should currently apply and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 23, 2017
@sdeleuze
Copy link
Contributor Author

sdeleuze commented Jan 23, 2017

I have updated the related Stack Overflow question accordingly. An eventual improvement could be to support @ConfigurationProperties on Kotlin data classes with immutable (val) properties provided via the constructor, but I need to experiment about that and that's not critical since I think you can just use regular Kotlin classes with mutable (var) properties currently.

@eacasanovaspedre
Copy link

For what it's worth, here is my opinion: I use injection through constructor whenever possible and I also prefer to have my properties immutable, so I use @Value most of the time with it's corresponding escaped $. It's ugly, but it's not the end of the world like @dsyer said and definitely better (for me) than having mutable properties all over the place. I've used @ConfigurationProperties for some special property loading and I like it, but I'll be willing to use it more when it supports val properties.

@philwebb
Copy link
Member

@eacasanovaspedre We're not really happy with the mutable nature of @ConfigurationProperties either. We've recently completed a big piece of work that will make it easier to support immutable configuration properties in the future and hopefully you'll soon be able to use Kotlin data classes as configuration properties (watch #8762 for updates).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

6 participants