| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Как сказать JVM об изменившемся свойстве |
| Автор: lazycat 6.7.2010, 10:44 |
| Доброго времени суток всем! Знает ли кто-нибудь, можно ли во время выполнения программы сказать JVM, что одно из свойств изменилось. Например, я в программе установил новое значение свойства java.system.class.loader. Однако JVM работает с тем системным загрузчиком, который был определен при ее запуске. Так вот, есть ли возможность сказать JVM, что она должна с этого момента использовать другой загрузчик? Заранее благодарен всем откликнувшимся |
| Автор: Skipy 6.7.2010, 11:26 |
| Поменять СИСТЕМНЫЙ ЗАГРУЗЧИК, разумеется, нельзя. Иначе кто угодно подложит свои классы, поменяет загрузчик - и до свиданья, безопасность. Вам это зачем? |
| Автор: Skipy 6.7.2010, 18:06 | ||||
Видите ли, в чем дело... Не все приложения запускаются из командной строки. Загружаете Вы страницу в браузере, а там - скрытый апплет. Который подменяет системный загрузчик, имеющий максимальные права, и начинает бесчинствовать в системе. А Вы этого всего не видите. Нравится? Кроме того. Что делать с классами, которые УЖЕ загрузились? Строки используете? Наверняка. Что при одинаковом содержимом строки, загруженные разными загрузчиками, неравны - в курсе? Да и любые другие правильно написаные классы. Вы так и не ответили - Вам зачем НА ЛЕТУ подменять загрузчик? Тем более - системный? |
| Автор: lazycat 6.7.2010, 21:39 | ||||||
Совершенно неубедительный пример. Бесчинствовать апплету не дает "песочница", в которой (не знаю, но фантазирую) может быть предусмотрен и такой пункт, как подмена загрузчика. В общем, Вы не хуже меня (а вероятно и лучше) знаете, как ограничиваются права апплета.
Опять же пример неубедительный. Строки, загруженные разными загрузчиками будут равны, если сравнивать через equals(). Если сравнивать через ==, то в общем случае строки, загруженные одним загрузчиком тоже будут не равны.
Не собираюсь делать из этого тайну, но не представляю, как рассказать в рамках поста. Мы с сотрудником, переписываясь по чату, наверное пару мегабайт текста написали, чтобы понять, что нам надо. Постараюсь кратко, но, наверное, совершенно непонятно: в момент загрузки класса о загрузчике, который впоследствии станет системным, еще ничего не известно. Сведения о нем появляются в процессе работы программы. Одним словом, не от хорошей жизни прибегаем к разным извращениям. |
| Автор: LSD 7.7.2010, 10:59 | ||||
Вы действительно не понимаете как с помощью системного загрузчика можно получить полный доступ к системе?
Не будут, читайте про загрузку классов. По теме вопроса: system properties это просто "информация к размышлению". Каждый класс сам решает как часто ему проверять system properties. Какие-то класы могут это делать какждый раз при создании объекта/вызове метода, какие-то один раз при загрузке. |
| Автор: Skipy 7.7.2010, 13:04 | ||||||
Именно. Лучше знаю. Они ограничиваются менеджером безопасности, который успешно подменяется собственным загрузчиком. До свиданья, песочница.
Метод String.equals(...) начинается так:
Сравнение anObject instanceof String вернет false, если anObject загружен одном загрузчиком, а String - другим. До сравнения содержимого дело не дойдет. P.S. Вы так и не ответили, зачем Вам подменять СИСТЕМНЫЙ загрузчик. Почему не организовать свой собственный для своих классов? |
| Автор: lazycat 8.7.2010, 21:51 | ||||||||
| Skippy, LSD, во-первых, спасибо за участие в дискуссии. Теперь по вопросам.
Не такой уж я и дремучий Я не утверждаю, что приложение может подменять загрузчик, но аргумент "это привело бы к проблемам безопасности при работе с апплетами" кажется мне совершенно надуманным. Добавлено через 1 минуту и 57 секунд
Еще раз спасибо, очень интересно. Прямо сейчас попробую. Добавлено через 7 минут и 54 секунды
Вкратце так: есть одно приложение со своими библиотеками, оно грузит другое приложение тоже со своими библиотеками. Код приложений переписывать нельзя. Системный загрузчик указывается через свойство перед запуском первого приложения - это тоже обязательное условие. Надо сделать так, чтобы это другое приложение ничего не знало и не могло узнать о библиотеках первого приложения. Такая задача только на первый взгляд кажется простой. Уже неделю работаем вдвоем и ничего сделать не можем. |
| Автор: lazycat 8.7.2010, 23:09 | ||
Кстати, вдумайтесь в эту фразу. Да и я ответ написал не лучше. Как можно загрузить строки разными загрузчиками? |
| Автор: jk1 9.7.2010, 09:00 | ||
| lazycat, Подменить загрузку классов из rt.jar (в том силе и строк java.lang.String) вы не сможете. Дело в том, что любой Class Loader придется наследовать от java.lang.ClassLoader, в котором намертво зашиты вот такие проверки
версия кода загрузки без проверок объявлена private native и вызову извне не подлежит. Таким образом, любой пользовательский Class Loader будет проходить проверку: не пытается ли он загружать системные классы. |
| Автор: LSD 9.7.2010, 17:16 | ||||
1. JVM всегда нужен доступ к файловой системе, для подгрузки классов, ресурсов, шрифтов и т.п. Поэтому системные классы даже в апплете имеет доступ к файловой системе (и не только). 2. Мы можем взять какой нибудь класс подменить его на свой и вполне безобидый в оригинале метод будет заражать систему вирусом.
Ну так и на кой вам подменять системный ClassLoader? Все сервера приложений сталкиваются с такой задачей и решают ее создавая обычного ClassLoader для каждого приложения. Строки нельзя, потому что классы из пакетов java и javax может грузить только системный ClassLoader, а вот для других классов сколько угодно - http://forum.vingrad.ru/index.php?showtopic=24799&view=findpost&p=694112. |
| Автор: lazycat 13.7.2010, 18:35 |
| For LSD Прошу прощения, пару дней не мог участвовать в дискуссии. Если Вам не надоела тема, можем продолжить обсуждение. |
| Автор: LSD 14.7.2010, 18:22 |
Легко |
| Автор: lazycat 14.7.2010, 19:52 | ||
Если хотите, попробуйте решить такую задачу. Есть приложение, назовем его "первое". В нем есть какой-то класс somepackage.A. Есть еще одно приложение, назовем его "второе". В нем тоже есть класс somepackage.A. Для чистоты эксперимента: оба класса A содержат одинаковые наборы методов с одинаковым сигнатурами, но методы разные. В процессе работы первое приложение загружает второе. При этом оно не знает о наличии во втором приложении класса somepackage.A. Попробуйте добиться, чтобы после загрузки второе приложение, создавая экземпляр класса А получало свой класс A, а не одноименный класс первого приложения. Чтобы сэкономить Ваше время, скажу, что отдельный загрузчик для второго приложения задачу не решает, потому что стандартный алгоритм работы загрузчика выглядит так: сначала проверяется, загружен ли уже такой класс, затем загрузчик запрашивает класс у своего родителя, а уже потом пытается загрузить класс сам. Добавлено через 3 минуты и 13 секунд Вдогонку: В принципе я уже понял, что манипулировать системным загрузчиком - тупиковый путь и решил задачу, переписав метод loadClass(String) загрузчика. |
| Автор: LSD 28.7.2010, 17:55 |
| К вопросу о быстроте ответов На практике такая задача решается следующим образом: есть некое микроядро, которое загружается системным загрузчиком. Потом оно читает конфигурацию и грузит необходимые модули. Каждый модуль грузится своим загрузчиком для которого родительским будет системный загрузчик и поэтому они видят только свои классы, системные классы и классы ядра. |