Comments (8)
Thanks for the details. This is helpful. Will have a look
from dotenv-kotlin.
Yeah Base64 definitely gets the job done. Did not occur to me at the moment so ended up putting something like __NEWLINE__
in the .env
file and then replacing it when reading the values in the Java code.
Thanks for taking the time to go over the Java behavior! I do agree with you that it should stay the same as what System.getenv
does.
Maybe we could add something to the README
there is a reference to the issue in the future. Coming in, I thought the newlines would just work and took me well over an hour to realize that was the issue I had, given the use case I had.
from dotenv-kotlin.
@david-arteaga thanks for the ticket
I created a quick simple test to try and recreate your issue
Here is my .env
file
MULTI_LINE=hello\nworld
Here is a quick Java test (included only the relevant bits)
...
private val envVars = mapOf(
"MULTI_LINE" to "hello\\nworld"
)
...
@test
fun multiLine() {
val dotenv = Dotenv.configure()
.ignoreIfMalformed()
.load()
assertEquals(dotenv["MULTI_LINE"]!!, envVars["MULTI_LINE"]!!)
}
The above test passes.
Can you provide the .env
file you are using and what you expect to see in Java
Thanks
from dotenv-kotlin.
Ok so I played around with some examples and I think I got to the issue.
This is my .env
file:
MULTILINE=1\n2
This is the code I am running
public static void main(String[] args) {
String multilineString = "1\n2";
Dotenv d = Dotenv.load();
String multilineFromDotEnv = d.get("MULTILINE");
System.out.println("Characters from multiline");
printChars(multilineString);
System.out.println("\n\nCharacters from dotenv");
printChars(multilineFromDotEnv);
System.out.println("\n\nPrinted string with multiline");
System.out.println(multilineString);
System.out.println("Printed string from dotenv");
System.out.println(multilineFromDotEnv);
System.out.println("\n\nAre they equal? : " + multilineString.equals(multilineFromDotEnv));
}
private static void printChars(String all) {
all.chars().forEach(System.out::println);
}
This is the output I get:
Characters from multiline
49
10
50
Characters from dotenv
49
92
110
50
Printed string with multiline
1
2
Printed string from dotenv
1\n2
Are they equal? : false
So as you can see in the character list from dotenv, the characters get interpreted literally, as a \
+ n
character.
I would expect for there to be a way to actually have a real multiline string from dotenv.
I ran into this problem trying to use a .pem
certificate in the .env
file, and the library I was using rightfully complained saying the certificate was incorrect.
I can imagine there are many other use cases for this, but this is the one I found.
I want the string that is loaded from dotenv to actually have the newline character in the string, not to have the \
+ n
characters.
Is there any way to do this with the library?
What I did in the end was just to put an arbitrary string where there should be newlines in the .env
file and then replace them in java code.
from dotenv-kotlin.
I ran a few more tests. Ultimately, Java's System.getenv(...)
and java-dotenv's dotenv.get(...)
behave the same way for multi-line EVs. Given that this is the case, the current behavior should remain. I don't think dotenv should diverge from Java's behavior.
Here is the test. It's essentially an extension of yours
package tests;
import io.github.cdimascio.dotenv.Dotenv;
import java.util.ArrayList;
import java.util.List;
public class Test
{
public static void main(String[] args) {
String multilineString = "1\n2";
Dotenv d = Dotenv.configure().ignoreIfMalformed().load();
String multilineFromDotEnv = d.get("MULTILINE");
String multilineFromSytemEnv = System.getenv("MULTILINE");
System.out.println("Characters from");
System.out.println(" - multiline: " + collectChars(multilineString));
System.out.println(" - dotenv : " + collectChars(multilineFromDotEnv));
System.out.println(" - System : " + collectChars(multilineFromSytemEnv));
System.out.println();
System.out.println("String from");
System.out.println(" - multiline: " + multilineString);
System.out.println(" - dotenv : " + multilineFromDotEnv);
System.out.println(" - System : " + multilineFromSytemEnv);
System.out.println();
System.out.println("Does System.getenv(...) equal dotenv.get(...): " + multilineFromSytemEnv.equals(multilineFromDotEnv));
System.out.println("Does System.getenv equal multiline String? : " + multilineString.equals(multilineFromSytemEnv));
System.out.println("Does dotenv.get equal multiline String? : " + multilineString.equals(multilineFromSytemEnv));
}
private static List<Integer> collectChars(String all) {
return all.chars().collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
}
}
from dotenv-kotlin.
All in all, this still begs the question, how do you solve your original issue.
Here's a suggestion. Base 64 encode the multi-line value in the EV, and decode it after its read in.
Here is an example, you'll notice that the bae64 encoding will preserve the newlines and both Java system and dotenv produce the same and desired result
# EVs
MULTILINE=1\n2
# base 64 encoded version of string above
B64_MULTI_LINE=MQoy
package tests;
import io.github.cdimascio.dotenv.Dotenv;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
public class Test
{
public static void main(String[] args) {
String multilineString = "1\n2";
runWith("MULTILINE", "1\n2");
System.out.println("=================");
String encodedString = Base64.getEncoder().encodeToString(multilineString.getBytes());
runWith("B64_MULTI_LINE", encodedString);
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
System.out.println(new String(decodedBytes));
}
public static void runWith(String ev, String multilineString) {
Dotenv d = Dotenv.configure().ignoreIfMalformed().load();
String multilineFromDotEnv = d.get(ev);
String multilineFromSytemEnv = System.getenv(ev);
System.out.println("Characters from");
System.out.println(" - multiline: " + collectChars(multilineString));
System.out.println(" - dotenv : " + collectChars(multilineFromDotEnv));
System.out.println(" - System : " + collectChars(multilineFromSytemEnv));
System.out.println();
System.out.println("String from");
System.out.println(" - multiline: " + multilineString);
System.out.println(" - dotenv : " + multilineFromDotEnv);
System.out.println(" - System : " + multilineFromSytemEnv);
System.out.println();
System.out.println("Does System.getenv(...) equal dotenv.get(...): " + multilineFromSytemEnv.equals(multilineFromDotEnv));
System.out.println("Does System.getenv equal multiline String? : " + multilineString.equals(multilineFromSytemEnv));
System.out.println("Does dotenv.get equal multiline String? : " + multilineString.equals(multilineFromSytemEnv));
String encodedString = Base64.getEncoder().encodeToString(multilineString.getBytes());
}
private static List<Integer> collectChars(String all) {
return all.chars().collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
}
}
Hope this helps
from dotenv-kotlin.
Done. I’ve added a note in the FAQ section.
from dotenv-kotlin.
Just for reference the FAQ section is here
from dotenv-kotlin.
Related Issues (20)
- Dotenv entries() result is not overridden by environment variables HOT 3
- Not working correctly when I execute a jar after gradle build HOT 2
- Option to only load .env file env vars HOT 6
- using env vars from host, it requires .env file HOT 1
- Directory configuration not working correctly HOT 3
- question - incorporating into build.gradle HOT 5
- 5.1.3 library version does not resolve correctly .env file location in jar file. HOT 3
- How is it different from Spring properties? HOT 5
- Make dotenv env variables available in System.getProperty() too HOT 6
- .env file and Travis HOT 5
- Getting an error when running a jar that uses dotenv HOT 1
- kotlin libs are required HOT 3
- Update version in readme
- Crashes on Android version 7 and older HOT 2
- package version 6.3.0 is not published anywhere other than github packages HOT 1
- Android Could not find /asset/env on the classpath HOT 1
- Errors when attempting to start it from a jar.
- Latest build on maven HOT 1
- Feature missing in docs.. DECLARED_IN_ENV filter
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dotenv-kotlin.