Search
Write a publication
Pull to refresh

Жук в кофейной чашке

Недавно довелось столкнулся мне с очень неприятной недоработкой Sun-овской виртуальной машины. Сразу оговорюсь, что данная проблема затрагивает только Windows пользователей, так что юниксоидам данная статься врядли окажется полезной. Итак, запустив одним прекрасным днём NetBeans, я заметил, что служебные папки IDE (.netbeans и .netbeans-register) оказались у меня на рабочем столе. Такое поведение любимой среды меня расстроило и заставило задуматься:

Для начала необходимо было локализовать проблему, поэтому я начал с переустановки NetBeans. Естественно никакого результата это не дало. Папки упорно продолжали появляться не там, где им положено. Сужая круг поиска, смертью храбрых пал JDK. Решив, что проблема гораздо глубже, чем кажется на первый взгляд, я стал искать в Гугле не возникало ли у кого схожей проблемы. В результате нашлась такая вот интересная ссылка.

Если кому-то лень читать, то скажу просто: из данного описания следует, что виртуальная машина Java при запуске получает адрес домашней папки пользователя для свойства «user.home» несколько необычным образом. А именно: вместо того, чтобы взять значение системной переменной %USERPROFILE%, она обращается к ключу реестра [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Desktop], откуда, собственно, и выдирает значение «user.home». Описание данного бага датируется 2002-м годом, однако последние комментарии разгневанных пользователей оставлены в феврале 2009-го. Более, чем за шесть лет, инженеры Sun так и не удосужились устранить проблему. -1 им в карму за нерасторопность, однако что делать нам?

Сложность заключается в том, что для решения данной проблемы можно, например, создавать bat файл и в нём явно указывать домашнюю директорию параметром: -Duser.home=«C:\Documents and settings\User». Однако писать такой скрипт для каждого приложения — не самая лучшая идея, поэтому раз Sun не идет навстречу нам, то мы придем к Sun…

Для начала я решил проверить, а верно ли всё то, что описано в отчете. Для этого в BeanShell (никакой IDE на тот момент просто под рукой не было) был написан и выполнен такой код:



а Regmon был настроен на отлов обращений виртуальной Java-машины к параметру «Desktop». В логе обнаружилась такая запись:

173 2.15123796 java.exe:3972 OpenKey HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders SUCCESS Access: 0x20019
174 2.15131950 java.exe:3972 QueryValue HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Profile SUCCESS "C:\Documents and Settings\lonely-lockley\Рабочий стол"
175 2.15139484 java.exe:3972 CloseKey HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders SUCCESS


Значит, действительно, это всё тот же бородатый баг. Надо ли говорить, что переустановка JRE ничего не дала? Что ж, если виртуальная машина неверно интерпретирует информацию, получаемую из реестра, значит надо заставить её брать эту информацию в другом месте. Вооружившись IDA, я двинулся на поиски и в java.dll вот что нашел:



Теперь нужно лишь найти смещение в котором хранится данная строка.



Так как IDA работает не с файлом, а с его образом, то патчить библиотеку пришлось при помощи WinHex. Для простоты я решил заменить строку «Desktop» на «Profile», просто потому что в [Shell Folders] такого параметра нет. Итак:



Потом создал ключ реестра:



И снова запустил BeanShell:



Как видите, помогло. NetBeans перестали «хулиганить» на рабочем столе, а виртуальная машина теперь точно знает где мой «user.home».

Эпилог Кому-то данный способ скорее всего покажется излишне сложным, ведь теперь придется следить за апдейтами JRE, чтобы не потерять патченую java.dll, а ведь можно было бы просто перенести рабочий стол в другую папку или вообще переустановить Windows. Я отвечу: «Можно, но мне так удобнее». К тому же, есть случаи в которых данный способ может оказаться единственно верным. Например, когда Вы пользуетесь рабочим столом, расположенным на удалённом сервере. Надеюсь, что кому-нибудь эта статья сэкономит пару дней мучений.
_________
Текст подготовлен в ХабраРедакторе
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.