permanentes - ¿Es posible establecer una variable de entorno en tiempo de ejecución desde Java?
variables de entorno java linux (5)
En respuesta a su pregunta actualizada:
- ¿Podemos modificar el entorno del proceso actual?
Sí , si usa JNI para llamar asetenv()
o algo. Sin embargo, probablemente no necesites hacer esto, y puede que no funcione en todas las situaciones. - ¿Podemos modificar el entorno del proceso principal?
No - ¿Podemos modificar el entorno del proceso hijo?
Sí , usandoProcessBuilder
.
¿Es posible establecer una variable de entorno en tiempo de ejecución desde una aplicación Java? En Java 1.5 clase java.lang.System existe el método getenv (), solo necesitaría un método setenv () ...
¿Es posible modificar las variables de entorno en el proceso de Java? no en el proceso de niño
¿Es posible lograrlo a través de JNI? ¿Y cómo funcionaría eso?
Gracias.
EDITAR: Ok, déjame ponerlo de esta manera. ¿Podemos hacer lo siguiente con Java? Por favor conteste.
- ¿Podemos modificar el entorno del proceso actual?
- ¿Podemos modificar el entorno del proceso principal?
- ¿Podemos modificar el entorno del proceso hijo?
Hemal Pandya ha respondido que "se puede modificar el entorno de los procesos actuales y secundarios, pero no del proceso principal que generó este proceso". Estás de acuerdo con esto ?
No lo creo, al menos no solo en Java, pero ¿por qué necesitas hacer esto? En Java, es preferible usar propiedades a través de System.getProperties()
, que puede modificar.
Si realmente es así, estoy seguro de que podría ajustar la función C setenv
en una llamada JNI; de hecho, no me sorprendería que alguien ya lo haya hecho. Aunque no conozco los detalles del código.
Puede modificar el entorno de los procesos actuales e secundarios, pero no del proceso principal que generó este proceso.
Puede obtener un control sobre el mapa subyacente al que ProcessEnvironment se aferra, y luego colocar cosas nuevas y eliminar todo lo que desee.
Esto funciona en java 1.8.0_144. No puedo garantizar que funcione en ninguna otra versión de Java, pero probablemente sea similar si realmente necesita cambiar el entorno en tiempo de ejecución.
private static Map<String,String> getModifiableEnvironment() throws Exception{
Class pe = Class.forName("java.lang.ProcessEnvironment");
Method getenv = pe.getDeclaredMethod("getenv");
getenv.setAccessible(true);
Object unmodifiableEnvironment = getenv.invoke(null);
Class map = Class.forName("java.util.Collections$UnmodifiableMap");
Field m = map.getDeclaredField("m");
m.setAccessible(true);
return (Map) m.get(unmodifiableEnvironment);
}
Después de obtener la referencia al mapa, simplemente agregue lo que desee y ahora puede recuperarlo utilizando la antigua llamada System.getenv ("").
Intenté esto está trabajando en MAC que no funciona en Windows en ambos os java versión 1.8_161
Si mi intuición es correcta y realmente desea modificar el entorno en beneficio de un subproceso generado (bifurcado) ( Runtime.getRuntime().exec()
), utilice ProcessBuilder lugar de exec()
. Puede crear un entorno personalizado a través del método environment() su instancia de ProcessBuilder
.
Si esto no es lo que está tratando de lograr, desestime amablemente esta respuesta.
ACTUALIZAR
La respuesta a sus tres preguntas actualizadas y específicas es la siguiente:
- ¿Podemos modificar el entorno del proceso actual?
- No es facil Depende si desea cambiar el entorno del proceso, para cambiar los valores devueltos por
System.getenv()
en la misma JVM o ambas. - Como Greg Hewgill señaló, para cambiar el entorno del proceso actual puede llamar a
setenv
o su equivalente específico de la plataforma a través de JNI. También puede emplear el método extremadamente intrincado del punto 2 a continuación, que funciona para cualquier proceso (siempre que tenga los permisos). Sin embargo, tenga en cuenta que en la mayoría de las JVM este cambio podría no reflejarse en los valores devueltos porSystem.getenv()
, ya que el entorno se almacena en caché casi siempre en el inicio de la máquina virtual enjava.util.Map
(o equivalente). - Para cambiar la copia en caché del entorno de la JVM, cuando se usa una caché (consulte el código fuente en
System.java
en cualquier distribución JVM que vaya a utilizar para implementar), puede intentar piratear la implementación (a través del orden de carga de clase, reflection , o instrumentation ). En el caso de la JVM v1.6 de SUN, por ejemplo, la caché de entorno está gestionada por la claseProcessEnvironment
noProcessEnvironment
(que puede parchear).
- No es facil Depende si desea cambiar el entorno del proceso, para cambiar los valores devueltos por
- ¿Podemos modificar el entorno del proceso principal?
- Extremadamente difícil y altamente no portátil . Si de manera absoluta e imperativa tiene que hacerlo, existen hacks muy específicos que puede emplear:
- Windows: dinámicamente Agregar / Editar variables de entorno del proceso remoto
- * nix: ¿Hay alguna manera de cambiar las variables de entorno de otro proceso? - Este es un asesino de rendimiento, ya que cualquier proceso instrumentado por
gdb
se suspenderá por un período de tiempo distinto de cero.
- Extremadamente difícil y altamente no portátil . Si de manera absoluta e imperativa tiene que hacerlo, existen hacks muy específicos que puede emplear:
- ¿Podemos modificar el entorno del proceso hijo?
- Sí , a través de
ProcessBuilder
al generar el proceso. - Si el proceso ya se generó cuando se requiere la alteración del entorno, se necesita el método 2 anterior (o algún método igualmente intrincado, como la inyección de código en el momento de generación, controlado ulteriormente mediante, por ejemplo, socket por el proceso principal).
- Sí , a través de
Tenga en cuenta que todos los métodos anteriores, excepto el que involucra ProcessBuilder
, son frágiles, propensos a errores, no portátiles en varios grados y propensos a condiciones de carrera en entornos de subprocesos múltiples.