Gestión de variables de entorno en Java

En este tutorial, administraremos las variables de entorno usando Java con ejemplos de cómo obtener nombres y claves de variables de entorno, así como configurarlos y ejecutar procesos.

Introducción

Las variables son ubicaciones de memoria con nombre. Sus valores se guardan en la memoria, que normalmente no podemos recordar ya que no son amigables para los humanos y cambian. Sin embargo, si nombramos la ubicación de la memoria, como a, es mucho más fácil de recordar.

Las variables de entorno se parecen mucho a las variables de programación habituales, excepto que se establecen en algún lugar fuera del programa. Eso puede ser utilizado por el sistema operativo, JVM, un microservicio que usa nuestro programa, etc.

Más precisamente, son pares clave/valor, donde la clave es lo que se puede considerar como el nombre de la variable de entorno y el valor es, bueno, el valor. Sus valores son siempre cadenas.

Cuando las personas se refieren a las variables de entorno, generalmente se refieren a las establecidas por el sistema operativo. Es probable que haya tenido que lidiar con PATH y JAVA_HOME en el pasado; esas son variables de entorno.

Las variables de entorno varían según los sistemas operativos y, a veces, puede ser difícil crear programas portátiles que se basen en ellas, pero nada hace que sea inherentemente difícil trabajar con ellas.

Las variables de entorno del sistema operativo tienen su analogía en el mundo JVM - Propiedades. Están más allá del alcance de este artículo, pero vale la pena mencionarlos ya que son un concepto bastante similar a una escala más pequeña.

Consulta de variables de entorno

Su sistema operativo almacena sus variables de entorno como pares clave/valor. Puede usar System.getenv() para recuperar esos valores. Si lo usa sin un argumento, obtendrá un objeto Map como valor de retorno:

1
2
3
4
5
Map<String, String> env = System.getenv();

for(String envName : env.keySet()){
    System.out.println(String.format("%s : %s", envName, env.get(envName)));
}

Aquí hay una vista truncada de los resultados:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
PROCESSOR_ARCHITECTURE : AMD64
MIC_LD_LIBRARY_PATH : C:\Program Files (x86)\Common Files\Intel\Shared Libraries\compiler\lib\mic
PSModulePath : C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\
SystemDrive : C:
AWE_DIR : D:\Awesomium\1.6.6\
FPS_BROWSER_USER_PROFILE_STRING : Default
PATHEXT : .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
DriverData : C:\Windows\System32\Drivers\DriverData
HerokuPath : E:\Heroku
ProgramData : C:\ProgramData
ProgramW6432 : C:\Program Files

También puede pasarle una Cadena correspondiente al nombre de la variable (clave) y devolverá el valor de la variable respectiva como una Cadena:

1
System.out.println(System.getenv("NUMBER_OF_PROCESSORS"));
1
8

ProcessBuilder y entorno

Java tiene una clase Proceso para tratar con los procesos del sistema operativo. Para simplificar la creación de un proceso, hay una clase Generador de procesos y simplemente puede "agregar" comandos a su instancia para ejecutar.

Cada proceso puede tener su propio entorno. Su programa tendrá su entorno establecido por el sistema operativo, pero los programas que inicie como procesos pueden tener un entorno "hecho a mano" modificado.

Para editar un entorno, debe obtener su referencia de su objeto ProcessBuilder mediante el captador environment(). Al igual que con la lectura de variables de entorno de Sistema, obtendrá un Mapa y luego podrá modificarlo con las operaciones habituales de Mapa.

Después de crear un entorno, crearemos un comando. Esto depende del sistema operativo. Aquí tenemos una comprobación rudimentaria que modifica adecuadamente el comando:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Setting up the environment...
ProcessBuilder processBuilder = new ProcessBuilder();
Map<String, String> env = processBuilder.environment();
env.put("PING_WEBSITE", "wikihtp.com");

if (System.getProperty("os.name").startsWith("Windows")) {
    processBuilder.command("cmd.exe", "/c", "ping -n 3 %PING_WEBSITE%")
} else {
    processBuilder.command("/bin/bash", "-c", "ping $PING_WEBSITE$");
}

try {
    // Starting the process...
    Process process = processBuilder.start();

    // Reading the output of the process
    try (BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()))) {

        String line;

        while ((line = reader.readLine()) != null) {
             System.out.println(line);
        }
    }

    // Catch the exit code of our process
    int ret = process.waitFor();

    System.out.printf("Program exited with code: %d", ret);

} catch (IOException | InterruptedException e) {
    // Handle exception...
    e.printStackTrace();
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Pinging wikihtp.com [172.67.218.223] with 32 bytes of data:
Reply from 172.67.218.223: bytes=32 time=12ms TTL=57
Reply from 172.67.218.223: bytes=32 time=12ms TTL=57
Reply from 172.67.218.223: bytes=32 time=15ms TTL=57

Ping statistics for 172.67.218.223:
    Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 12ms, Maximum = 15ms, Average = 13ms
Program exited with code: 0
Process finished with exit code 0

Hemos creado una nueva variable de entorno llamada PING_WEBSITE con un valor fijo. Puede modificar este programa para establecer el valor de PING_WEBSITE en la entrada del usuario, un argumento de línea de comandos o leer el valor de un archivo.

If you'd like to read on Cómo analizar y asignar argumentos de línea de comandos en Java or Cómo obtener entrada de Uset en Java, we've got you covered!

Conclusión

Hemos introducido el concepto de variables de entorno, explicado para qué se utilizan y conceptos análogos, así como su naturaleza dependiente del sistema.

Luego, imprimimos las variables de entorno usando el método System.getEnv() de Java, así como también creamos procesos usando ProcessBuilder y ejecutamos comandos que se basan en variables de entorno.

Licensed under CC BY-NC-SA 4.0