Программа использует устаревшее (не текущее) значение переменной env - PullRequest
1 голос
/ 09 марта 2012

У меня есть программа на C ++, которая внутренне использует java (через мою библиотеку C ++, которая оборачивает WebLogic jsmc.dll, которая внутренне использует jvm.dll).

Когда я устанавливаю CLASSPATH перед запуском моей программы, всеБиблиотеки JAR найдены и программа работает правильно.Когда я не устанавливаю CLASSPATH перед запуском моей программы, файлы JAR не найдены, что, конечно, ожидается.

Теперь, когда я устанавливаю CLASSPATH передпри запуске моей программы, но clear эта переменная среды CLASSPATH внутри кода программы до загрузки моей dll, использующей java, происходит странная вещь: все JAR-файлы все еще найдены, и программа работает так, как будтовсе было хорошоЯ проверил несколькими способами, что CLASSPATH действительно удаляется из переменных env (например, с помощью ProcessExplorer или путем печати его значения).

ВОПРОС:

Можете ли вы объяснить мне такое поведение?Я не задаюсь вопросом, почему java игнорирует установленную мной CLASSPATH, но как возможно , что java видит старое значение CLASSPATH, а не текущее?Я подчеркиваю, что java не может каким-то образом хранить старое значение CLASSPATH, потому что java не был загружен в то время, когда было доступно старое значение.

Как я могу сделать java с учетом изменений впеременные процесса env?

ДЕТАЛИ:

Приведенная выше проблема - это просто упрощение, которое я сделал, чтобы исследовать мою реальную проблему.Я пытаюсь установить CLASSPATH изнутри программы и не устанавливать его внешне.Но в java используется внешне установленный CLASSPATH, а не тот, который я установил в программе.

Я читаю и устанавливаю значения переменных env с помощью Windows API (GetEnvironmentVariableA, SetEnvironmentVariableA).Я убедился, что переменные среды процесса программы действительно меняются после их установки таким образом.Я даже напечатал значение CLASSPATH из библиотеки DLL, которая использует Java, перед вызовом любого метода Java.Я проверил с помощью ProcessMonitor, что jvm.dll действительно загружен после , CLASSPATH удален.Я также попытался исключить возможность чтения CLASSPATH из родительского процесса.Теперь я уверен, что во время загрузки jvm.dll CLASSPATH уже удален из среды процесса.

Я пробовал и программу тестирования Visual C ++ 2010, и C-компилятор HP LoadRunner(mmdrv.exe) скрипт vuser, с тем же результатом.LoadRunner - главная причина, по которой мне нужно решить эту проблему.

Ответы [ 2 ]

1 голос
/ 14 марта 2012

Проблема была вызвана тем, что среда выполнения C каким-то образом кэширует переменные среды.Пока я пытался изменить CLASSPATH с помощью системной функции SetEnvironmentVariableA (), jmsc.dll считывал CLASSPATH из кэша времени выполнения C.Среда выполнения C пытается синхронизировать свой кэш с реальными значениями в среде процесса, но, очевидно, не очень успешно.Мне было необходимо заменить системный вызов SetEnvironmentVariableA () на вызов _putenv () из среды выполнения C, чтобы изменить CLASSPATH.

Но возникла другая проблема.В моем коде использовались различные версии C-runtime, каждая из которых имела свой собственный кэш среды.Мой код VC был связан с msvcr100.dll, в то время как jmsc.dll (который создает экземпляр Java VM) использует msvcrt.dll.Решением было также связать мой код с msvcrt.dll, чтобы мой код устанавливал CLASSPATH с помощью _putenv () из той же C-среды выполнения, которую читает jmsc.dll.* за важный намек и Питер Цетински за ценную информацию.

0 голосов
/ 09 марта 2012

Вы не должны полагаться на переменную среды CLASSPATH при вызове нового процесса JVM из C ++.Интерфейс JNI предоставляет механизм для указания пути к классу JVM при запуске.

См. http://java.sun.com/docs/books/jni/html/invoke.html#28719

...