Почему `java.lang.SecurityException: запрещенное имя пакета: java` требуется?
Я создал класс "String" и поместил его в пакет "java" [на самом деле я хотел создать java.lang, чтобы посмотреть, какой класс загружен classLoader как
Как только класс загружается в JVM, тот же класс (повторяю, тот же класс) больше не будет загружаться
цитируется из рудни]. Но эта вещь позже, почему при запуске этого класса я получаю
java.lang.SecurityException: имя запрещенного пакета: java
По какой причине безопасности java не позволяет мне иметь класс в пакете java? Что можно сделать, если такой проверки не будет?
Ответы
Ответ 1
Пользовательскому коду никогда не разрешается помещать классы в один из стандартных пакетов Java. Таким образом, код пользователя не может получить доступ к каким-либо частным классам/методам/полям пакета в реализации Java. Некоторые из этих пакетов-частных объектов позволяют получить доступ к внутренним компонентам JVM. (В частности, я думаю о SharedSecrets
.)
Ответ 2
Во-первых, эти типы ограничений применяются для принудительной работы изолированной программной среды Java. То есть запуск ненадежного кода в надежной среде. Например, запуск апплета с какого-либо сайта (который вам не обязательно доверяет) на вашем компьютере (доверенной среде) в вашем браузере. Цель состоит в том, чтобы запретить ненадежный код получить доступ к частным частям пакета, которые могут помочь ему избежать песочницы.
Обычно эти ограничения применяются SecurityManager, поэтому их не должно происходить, когда вы запускаете собственное приложение в командной строке (если вы явно не указали использование SecurityManager). Когда вы управляете средой, вы можете просто перейти и отредактировать определение String.class внутри rt.jar вашей Java (и вы можете технически в любом случае не знать, что такое лицензирование). Как я уже сказал, ограничения обычно содержатся в SecurityManager, но это конкретное правило о пакетах java. * Находится в классе ClassLoader.
Чтобы ответить на ваш вопрос: я предполагаю, что java. * проверка есть из-за
а) исторические причины
б) где-то в ядре Java есть проверка имени класса, что-то вроде: Все классы, начинающиеся с java. * Получите специальное обращение.
Однако учтите, что даже если вам удалось создать класс с именем java.lang.String, он не был бы тем же классом, что и java.lang.String, определенным ядром Java. Это будет просто класс с таким же именем. Идентификатор класса - это больше, чем просто имя класса, хотя это может быть сложно понять, если вы действительно не играете с ClassLoaders.
Таким образом, класс, загруженный загрузчиком классов приложений в пакете java.lang, не будет иметь доступа к основному пакету java.lang-private.
Чтобы проиллюстрировать это, попробуйте создать класс javax.swing.JButton с основным методом и выполнить его. Вы получите java.lang.NoSuchMethodError: main
. Это потому, что java находит "настоящий" JButton перед вашим классом, а реальный JButton не имеет основного метода.
В автономном приложении Java вы можете обойти это ограничение, вызвав один из частных родных методов defineClassx напрямую с помощью отражения и setAccessible.
BTW: Ядро java.lang.String гарантированно будет загружено до того, как ваш код когда-либо будет выполнен, потому что он ссылается повсюду, вы не получите его первым с вашим кодом пользователя. JVM получает определенную степень, прежде чем даже попытаться загрузить ваш класс, не говоря уже о его выполнении.
Ответ 3
У вас нет имен пакетов "java. *". Это на самом деле жестко закодировано в ядре Java, поэтому вы даже не можете разрешать разрешение администратора безопасности работать с ним (см. ClassLoader:: preDefineClass (...))
Ответ 4
java
- это зарезервированное имя пакета. В этом пакете могут находиться только классы внутри JVM.
Если кто-то может написать в пакете Java, это может привести к тому, что библиотеки будут произвольно заменять основные классы Java своими собственными реализациями. Это может привести к тому, что многие думают, от взлома основных функций Java до выполнения вредоносного кода.
Ответ 5
Программа может обойти меры безопасности, если программа может переопределить основные классы JVM с троянскими версиями. Например, String используется практически везде.
Ответ 6
Из ClassLoader.defineClass(..)
javadoc:
... Указанное имя класса не может начинаться с "java." , так как все классы в пакетах "java." могут быть определены только загрузчиком класса bootstrap
и
Throws:... SecurityException. Если делается попытка добавить этот класс к пакету, который содержит классы, которые были подписаны другим набором сертификатов, чем этот класс, или если имя класса начинается с "java." .
Ответ 7
Возможно, во время рефакторинга/исправления/etc. вы добавили в название пакета слово "java", которое обычно представляет собой папку, содержащую пакеты.
Итак, вы можете закончить со структурой:
src- > Main- > Java- > java.com.yourpackage.name
Это может случиться и для теста:
src- > Main- > тест- > Java- > java.com.yourpackage.name
Проверьте его в своей среде IDE и удалите "java". часть