5 ms·
Indeed, environment variables should be used to configure child processes, not to configure the current process, for non-shell programs, IMHO. Note that Java,
by diroussel 2y ago
Indeed, environment variables should be used to configure child processes, not to configure the current process, for non-shell programs, IMHO.
Note that Java, and the JVM, doesn't allow changing environment variables. It was the right choice, even if painful at times.
- jamesfinlayson 2y agoSure is painful (mostly when writing tests where the environment variables aren't abstracted in some way). But I think it was actually possible to hack around up until Java 17.
- xxs 2y agoif you really wish - you can change the bootstrap path and allow changing env() for whatever reason you want to (likely via copy on write). If you don't wish to do that feel free to spawn a child process with whatever env you desire, then redirect/join sys in/our/err (0/1/2) Those are trivial things in around 100 lines of code and have been available since System.getenv() got back (it used to be deprecated and non-functional prior Java 1.5 or 2004)
- jamesfinlayson 2y agoA lot of the Java I'm writing is in AWS Lambda so my options are a bit more limited.
- hinkley 2y agoI think there's a narrow window, at least in some programming languages, when environment variables can be set at the start of a process. But since it's global shared state, it needs to be write (0,1) and read many. No libraries should set them. No frameworks should set them, only application authors and it should be dead obvious to the entire team what the last responsible moment is to write an environment variable. I am fairly certain that somewhere inside the polyhedron that satisfies those constraints, is a large subset that could be statically analyzed and proven sound. But I'm less certain if Rust could express it cleanly.
- dietr1ch 2y agoWhich programming languages? When using C++ I wanted programs to have a function that was called before main() and set up things that got sealed afterwards, like parsing command-line-arguments, the environment variables, loading runtime libraries, and maybe look at the local directory, but I'm not sure if it'll be a useful and meaningful distinction unless you restructure way too many things. I remember that on the Fuchsia kernel programs needed to drop capabilities at some point, but the shift needed might be a hard sell given things already "work fine".
- saagarjha 2y agoEveryone thinks they are can be the first to do something, and that there is surely nothing that will happen before them. Unfortunately everyone save for one is mistaken. Sometimes that chosen one is not even consistent.
- wizzwizz4 2y agoIf everyone is responsible for maintaining the illusion that someone else is first, who's actually first is largely irrelevant.
- hinkley 2y agoThis is one of the problems with Singletons. Especially if they end up interacting or being composed. In Java you’d have the static initializers run before the main method starts. And in some languages that spreads to the imports which is usually where you get into these chicken and egg problems. One of the solutions here is make the entry point small, and make 100% of bootstrapping explicit. Which is to say: move everything into the main method. I’ve seen that work. On the last project it got a little big, and I went in to straighten out some bits and reduce it. But at the end anyone could read for themselves the initialization sequence, without needing any esoteric knowledge.
- GoblinSlayer 2y agogrpc reads some configuration from environment; environment has portability problems too, so it's useful to set it to cross platform shape.
- Calzifer 2y agoJava doesn't even allow to change the working directory also due to potential multi-threading problems. Another reason why Java isn't the greatest language to create CLI tools with.
- throwaway2037 2y agoIt is interesting that they do not allow ability to change env and working dir via security policy or a command line arg (--allow-setenv, etc.).
- xxs 2y agoThat would be so much wasted engineering effort. The actual solution is simple: read what you need from env, and pass it as parameters to the functions you want to. The values of what you have read can be changed... and if you really, really want start a child process with a modified env.
- skissane 2y ago> Java doesn't even allow to change the working directory also due to potential multi-threading problems. Linux and macOS both support per-thread working directory, although sadly through incompatible APIs. Also, AFAIK, the Linux API can't restore the link between the process CWD and thread CWD once broken – you can change your thread's CWD back to the process CWD, but that thread won't pick up any future changes to the process CWD. By contrast, macOS has an API call to restore that link.
- xxs 2y ago>Note that Java, and the JVM, doesn't allow changing environment variables. It was the right choice, even if painful at times. Not sure why would it be considered painful. Imo, use of setenv to modify your own variable, the definition of setenv is thread unsafe. So unless running a single threaded application it'd never make sense to call it. Java does support running child processes with a designated env space (ProcessBuilder.environment is a modifiable map, copied from the current process), so inability to modify its own doesn't matter. Personally I have never needed to change env variables. I consider them the same as the command line parameters.