Ответ 1
Если моя интуиция правильная, и вы действительно хотите изменить среду в интересах порожденного (раздвоенного) подпроцесса (Runtime.getRuntime().exec()
), используйте ProcessBuilder вместо exec()
. Вы можете создать настраиваемую среду с помощью ProcessBuilder
экземпляра environment().
Если это не то, чего вы пытаетесь достичь, тогда любезно проигнорируйте этот ответ.
UPDATE
Ответ на три обновленных конкретных вопроса следующий:
- Можем ли мы изменить среду текущего процесса?
- Не легко. Зависит от того, хотите ли вы изменить среду процесса, изменить значения (значения), возвращаемые
System.getenv()
в одной JVM, или и то, и другое. - Как отметил Грег Хьюглилл, чтобы изменить текущую среду процесса, вы можете вызвать
setenv
или ее эквивалент для платформы через JNI. Вы также можете использовать чрезвычайно запутанный метод из пункта 2 ниже, который работает для любого процесса (при условии, что у вас есть разрешения.) Однако имейте в виду, что в большинстве JVM это изменение никогда не может быть отражено в значениях, возвращаемыхSystem.getenv()
, поскольку среда чаще всего кэшируется при запуске виртуальной машины вjava.util.Map
(или эквиваленте.) - Чтобы изменить кешированную копию среды JVM, когда используется кеш (см. исходный код в
System.java
в том, какой дистрибутив JVM вы будете использовать для развертывания), вы можете попробовать взломать реализацию (через порядок загрузки классов, reflection, или instrumentation. ) В случае SUN v1.6 JVM, например, кэш среды управляется недокументированным классомProcessEnvironment
(который вы можете исправлять).
- Не легко. Зависит от того, хотите ли вы изменить среду процесса, изменить значения (значения), возвращаемые
- Можем ли мы изменить среду родительского процесса?
- Чрезвычайно сложный и высоконепортативный. Если вам абсолютно и необходимо, есть очень специфические хаки, которые вы можете использовать:
- Windows: Динамически добавлять/редактировать переменные среды удаленного процесса
- * nix: Есть ли способ изменить другие переменные среды процессов? - это убийца производительности, так как любой процесс, управляемый
gdb
, будет приостановлен для ненулевого количества времени.
- Чрезвычайно сложный и высоконепортативный. Если вам абсолютно и необходимо, есть очень специфические хаки, которые вы можете использовать:
- Можем ли мы изменить среду дочернего процесса?
- Да, через
ProcessBuilder
при рождении процесса. - Если процесс уже был порожден, когда требуется изменение окружения, вам нужен метод 2 выше (или какой-то одинаково запутанный метод, такой как инъекция кода в момент времени появления, скрытый контроль через, например, сокет родительским процессом.)
- Да, через
Обратите внимание, что все вышеописанные методы, за исключением одного, включающего ProcessBuilder
, являются хрупкими, подверженными ошибкам, не переносятся в разной степени и подвержены условиям гонки в многопоточных средах.