¿Cómo recuperar el valor modificado de una variable de entorno (que se modifica externamente) en un programa Java?

¿Es posible recuperar el valor modificado de una variable de entorno en un programa Java?

Intenté usar System.getenv(). Pero el nuevo valor no se refleja en el programa. El escenario es este:

  1. El programa recupera el valor de una variable de entorno.

  2. El valor de esta variable se cambia externamente, mientras el programa aún se está ejecutando. (Podría ser incluso un proceso manual, como por ejemplo, en Windows, el usuario cambia el valor de la pestaña Avanzado en Mi PC-> propiedades)

  3. El programa recupera de nuevo el valor de la variable de entorno.

La segunda vez que se recupera el valor, debería obtener el valor modificado. Descubrí que usando System.getenv() me dio el valor anterior solamente. ¿Hay algún método fiable para esto? (Este requisito es específico para Windows, pero también me encantaría escuchar soluciones generales)

preguntado el 03 de mayo de 12 a las 16:05

¿Qué tipo de sistema operativo estás usando? ¿Es Windows? -

Sí, este requisito es específico de Windows. -

4 Respuestas

Afaik, las variables de entorno visibles para un proceso se configuran en el momento de la creación del proceso.

Las modificaciones posteriores a las variables del sistema operativo no son visibles para los procesos que no sean quienes las modifican.

Sin embargo, dependiendo del sistema operativo, podría haber alguna forma de recuperarlos. Por ejemplo, en el sistema operativo Windows, se mantienen en el registro, por lo que puede leerlos.

Intenta leer la clave en HKCU\Environment para las variables de usuario actuales, y la clave

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment for system variables.

Vea esta pregunta sobre el registro de Windows para una clase útil para leer el registro.

contestado el 23 de mayo de 17 a las 13:05

Ok, nunca pensé en buscar en el registro, lo comprobaré. - vaisakh

Ningún proceso observa las variables de entorno del padre. Incluso los programas C no "observan" las variables de entorno porque necesitaría cambiarlas en ese proceso. Cuando un proceso se inicia, obtiene una copia del entorno de su padre. Entonces, si modifica la variable de entorno en el padre, no cambia la versión de los procesos secundarios. A menos que inicie un nuevo proceso del cual obtiene una copia del cambio. Y creo que, en última instancia, esa es la razón por la que Java no ve los cambios porque se comporta como lo haría cualquier proceso normal. ¡Hay una buena razón para este comportamiento! Si las variables env fueran modificables, estaría teniendo problemas de concurrencia a su alrededor y necesitaría definir cuándo un proceso "vería" esos cambios de otros procesos. Se trata de bloqueo, visibilidad y problemas desagradables de concurrencia que la mayoría de los sistemas operativos no querían resolver en los primeros días.

Si desea compartir datos entre dos procesos, debe usar IPC (comunicación entre procesos) para hacerlo. En C land había varias formas de hacer esto: tuberías, memoria compartida, sockets. Java simplificó IPC a sockets porque era un superconjunto de las capacidades de los otros dos y la transparencia entre los procesos locales y remotos. Puede usar tuberías para compartir datos con un proceso Java, pero sería a través de stdin.

En pocas palabras, inicie el socket en Java y envíele datos desde otro proceso.

contestado el 03 de mayo de 12 a las 16:05

Correcto, surgen problemas de concurrencia. Aquí, sin embargo, le pedimos específicamente al usuario que cambie el valor y regrese al programa. Para eso, IPC podría ser una exageración. Sin duda, tendré en cuenta esta opción como alternativa. - vaisakh

Eso significaría esencialmente reiniciar la aplicación. Solicite al usuario que apague el proceso y reinícielo. Viola verás el nuevo valor. Esto se podría hacer fácilmente a través de un proceso tipo perro guardián que puede reiniciar el proceso de Java. - chubbsondubs

Además de la respuesta de @Andrea Parodi (+1), realmente puedo recomendarle que lea el entorno ejecutando una línea de comando externa echo %MYENV_VAR% y leer la salida o leer el registro.

Por favor echa un vistazo a este artículo donde muestro cómo leer el registro de Windows sin bibliotecas externas.

contestado el 03 de mayo de 12 a las 16:05

El registro de lectura parece prometedor. Ahora que lo pienso, nuestro marco nos proporciona una API para acceder a los valores del registro. Mejor le echo un vistazo. ¡Gracias por la idea! (+1) - vaisakh

En Win 7, algo como esto obtendrá las variables env:

Process p = Runtime.getRuntime().exec("cmd.exe /c set");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while( (line = br.readLine()) != null ) {
   String var = br.readLine();
   . . . .

Sin embargo, sospecho que depende de su plataforma, por lo que la portabilidad de su código será un problema.

contestado el 03 de mayo de 12 a las 16:05

Esta bien set El comando también funcionará en Windows XP. Entonces eso no es un problema, pero tendré que analizar la salida para obtener el valor. Sin embargo, vale la pena intentarlo. - vaisakh

Si le parece demasiado trabajo y está buscando una var conocida en particular, intente usar cmd.exe /c echo %YOUR_VAR_NAME%. Pensé que querías detectar todos los cambios. - mazaneicha

Sí, es un valor conocido; solo una variable - vaisakh

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.