paulschwarz/spring-dotenv

discuss about the dotenv addToEnvironment phase

clevertension opened this issue · 10 comments

if i add the configuration

log.path=${env.LOG_PATH}

it will throw the error
Exception in thread "main" java.lang.IllegalStateException: Logback configuration error detected: ERROR in ch.qos.logback.core.joran.spi.Interpreter@6:68 - RuntimeException in Action for tag [springProperty] java.lang.IllegalArgumentException: Could not resolve placeholder 'env.LOG_PATH' in value "${env.LOG_PATH}" at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:169) at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:80) at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60) at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:118) at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:313) at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:288) at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246) at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345) at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) at com.dragon.flow.manager.main.FlowManagerApplication.main(FlowManagerApplication.java:34)

we can dig the code to find the reason
image

the log prepare is occured at prepareEnvironment(), while dotenv addToEnvironment is occured at prepareContext() which is later than log preparation, so it can't find the LOG_PATH in environment

so my suggestion is we should prepare the dotenv at SpringApplicationRunListener instead of DotenvApplicationInitializer

I'll read an digest this. But for now, out of curiosity, what would be the implication if you configured spring-dotenv to have a prefix of "" and therefore you placeholder would be ${LOG_PATH}? I suspect this won't help and you would get the same error.

Are you able to prepare a PR, even if it's just a POC?

Thanks so much for the POC. It's really helpful.

I replicated your error.

I then followed your instructions in https://github.com/clevertension/dotenv-demo/blob/master/README.MD which is supposed to remove the error, but in fact I get the same error. So I can't replicated your "work around".

Any hints before I investigate further?

can you paste the error log here?

My bad. It is running fine.

So is this the solution you are looking for?
https://github.com/clevertension/dotenv-demo/blob/master/src/main/java/com/example/dotenvdemo/config/DotenvApplicationRunListener.java#L22-L24

If yes, then it put a dependency on Spring Boot. This may or may not be a bad thing because, until now, spring-dotenv doesn't depend on Spring Boot. Only Spring (but of course, works with Spring Boot).

Thoughts?

Actually, i test spring-dotenv with pure spring + jetty, try this POC
https://github.com/clevertension/dotenv-with-spring-demo

the env file didn't read into system environment, i think the META-INF/spring.factories file is used only be spring boot, so your project may only worked in spring boot project not spring

I made the same observation and have discovered a solution. You are right that the spring.factories is only used by Spring Boot. However, in a pure Spring project, the library can still be used but DotenvPropertySource needs to be registered programmatically. If there is another way, I'd be interested to hear.

Once the latest version is published it will include an example with pure Spring. I have managed to incorporate your main idea successfully. Busy working on it.

update I've just seen your sample project. I will analyse it and take some time to test the library against it.

you can try this POC
https://github.com/clevertension/dotenv-with-spring-demo

i comment some notes in README

Please review #18

I haven't had time to update the readme yet, but this will be released as 3.0.0 because it breaks the api. I made that decision because I realise it doesn't make sense to ask the user to prefix dotenv vars with env.

So instead of ${env.EXAMPLE} just use ${EXAMPLE}.

Also, .env configuration has moved from application.yml to .env.properties.

This will be made clear in the readme soon.

good, it is ok now