What is an Environment Variable?
Environment variables (sometimes called "env vars") are variables you store outside your program that can affect how it runs. You can later use that value to change how programs, applications, and services behave. Applications treat environmental variables like constants (a value that does not change during the program's execution) rather than mutable variables (a value that can change). They are best used with things you would typically consider hard coding but would rather keep the value out of your code, either because it will change between environments. You want to keep your code portable and easier to manage because you want to avoid leaking sensitive information such as your API key and password in less secure environments like development or testing.
Use Cases
Here are a few use cases for environmental variables:
Defining program arguments
Specifying domain names
Storing API keys
Setting path variables
Let’s dive into each!
Defining Program Arguments
How It Works: Developers use environment variables like
ENV_MODE
to indicate the current execution context of the application, such as development, testing, staging, or production.Benefits: This allows the application to adapt its behavior based on the mode. For instance, in development mode, the application might enable verbose logging and debugging tools, whereas in production, these features are disabled for efficiency and security.
Implementation Example: In Java, you might check
System.getenv("ENV_MODE")
to configure database connections or error handling differently for each mode.
Specifying Domain Names
How It Works: Environment variables like
SERVICE_URL
can store domain names or URLs that the application might need to access.Benefits: This is particularly useful for applications that interact with different endpoints or services in different environments. By changing the environment variable, you can redirect your application to use a different domain without altering the code.
Implementation Example: In a Java-based web application integrating Vonage services, the endpoint URL for Vonage's API can be defined using an environment variable, like
VONAGE_API_URL
. This allows developers to switch between a local development environment and a production server by simply changing the value of the environment variable. The application retrieves this URL withSystem.getenv("VONAGE_API_URL")
.
Storing API Keys
How It Works: Sensitive information such as API keys can be stored in environment variables, for instance,
API_KEY
.Benefits: This practice keeps sensitive data out of the source code, enhancing security. It also makes it easy to update keys without needing to touch the codebase, and different keys can be used in different environments.
Implementation Example: In a Java application using Vonage services, the Vonage API key can be stored in an environment variable, such as
VONAGE_API_KEY
. To access this key, the application would useSystem.getenv("VONAGE_API_KEY")
. This approach ensures the API key is not embedded in the source code or exposed in version control, enhancing security while providing access to Vonage's telecommunication services.
Setting Path Variables
How It Works: Environment variables like LOG_PATH or CONFIG_DIR can be used to specify the application's directory paths for logging, configuration files, or other purposes.
Benefits: This allows for flexible file management, as paths can be changed per environment without code changes. It’s beneficial for applications on multiple platforms (like Windows and Unix), where directory structures can vary significantly.
Implementation Example: In a Java application, reading a configuration path from an environment variable allows it to quickly adapt to different file system layouts across development and production servers or operating systems.
In all these cases, environment variables provide a layer of abstraction that separates configuration details from the application logic. This separation not only enhances security and maintainability but also increases the adaptability of the software to different environments and conditions.
Getting Environmental Variables
Accessing environment variables in Java is straightforward and can be done using the System class provided by the standard Java library. Here's a simple guide on how to do it:
Get a Single Environment Variable: Use the System.getenv(String name) method to retrieve the value of a specific environment variable. For example, to access an environment variable named
API_KEY
, you would use:
String apiKey = System.getenv("API_KEY");
Check for Null Values: It's a good practice to check if the environment variable is null (i.e., not set) to avoid potential NullPointerExceptions. For example:
String apiKey = Optional.ofNullable(System.getenv("API_KEY")).orElse(otherValue);
where otherValue
is the fallback. You can throw an exception instead if the environemnt variable is missing like so:
Optional.ofNullable(System.getenv("API_KEY")).orElseThrow(() -> new IllegalStateException("API_KEY env var is not defined"));
Get All Environment Variables: To get a
Map<String, String>
of all environment variables, useSystem.getenv()
. This is useful if you want to iterate over all available environment variables. For example:
Map<string, string=""> envVars = System.getenv();
for (String envName : envVars.keySet()) {
System.out.format("%s=%s%n", envName, envVars.get(envName));`
}
</string,>
Alternatively, this can be written in one line:
System.getenv().forEach((k, v) -> System.out.println(k+"="+v));
Setting Environmental Variables
Setting environment variables directly within a Java application is not straightforward because environment variables are typically set at the operating system level and are read-only without an argument. However, there are a few ways you can work around this limitation, depending on your use case:
Set Environment Variables Before Running Java Application
The most common approach is to set environment variables in your operating system before starting your Java application. This can be done in the command line or through scripts.
For example, in a Unix environment, you can set an environment variable in the terminal like this:
In Windows Command Prompt, it would be:
set MY_VAR=some value
Set for Sub-Processes
If you need to set environment variables for subprocesses started from your Java application (and not for the Java process itself), you can use the ProcessBuilder class:
ProcessBuilder processBuilder = new ProcessBuilder();
Map<string, string=""> env = processBuilder.environment();
env.put("MY_VAR", "some value");
Process process = processBuilder.start();
</string,>
Set Environment Variables in IDE
If you are using an Integrated Development Environment (IDE) like IntelliJ IDEA or Eclipse, you can set environment variables in the configuration settings of your application.
Set Environment Variables in Build Tools
When using build tools like Maven or Gradle, you can configure environment variables in the build scripts or configuration files.
Loading Configurations From a File
Since java.util.Properties
implements the Map interface, you can load any file which maps key-value pairs like so, irrespective of its file extension:
var props = new Properties();
var envFile = Paths.get("/path/to/MyEnvConfig.env");
try (var inputStream = Files.newInputStream(envFile)) {
props.load(inputStream);
}
String apiKey = props.get("VONAGE_API_KEY");
String apiSecret = props.get("VONAGE_API_SECRET");
Share Your Best Practices
Getting and setting environment variables is an essential part of creating production software. If you’ve reached the end of this article, you’re now familiar with what environment variables are, use cases, how to get and set environment variables, and using .env files in Java. Feel free to join our community Slack and follow us on X, formerly known as Twitter. Do you have other best practices using environmental variables? Please share them and tag me - I'd love to hear about them!