我创建了一个类"String"并将其放在包"java"中[实际上我想创建java.lang以查看classLoader加载哪个类
将类加载到JVM后,将不会再次加载同一个类(我重复,同一个类)
引自oreilly].但是之后的事情,为什么在运行这个类我得到
java.lang.SecurityException:禁止的包名:java
为什么安全性原因java不允许我在java包中有一个类?如果没有这样的检查,怎么办?
Chr*_*ung 25
永远不允许用户代码将类放入标准Java包之一.这样,用户代码就无法访问Java实现中的任何包私有类/方法/字段.其中一些包私有对象允许访问JVM内部.(我正在考虑SharedSecrets.)
Sam*_*ivu 16
首先,这些类型的限制适用于强制Java沙箱.也就是说,在受信任的环境中运行不受信任的代码.例如,在您的浏览器中的计算机(可信环境)上运行某个站点(您不一定信任)的applet.目的是禁止不受信任的代码访问包私有的东西,这可以帮助它逃离沙箱.
通常,这些限制由SecurityManager强制执行,因此当您在命令行上运行自己的应用程序时,不应该发生这些限制(除非您明确指定使用SecurityManager).当你控制环境时,你可以去编辑Java的rt.jar中的String.class定义(从技术上讲,你可以不确定许可证说的是什么).正如我所说,限制通常在SecurityManager中,但是关于java.*包的这个特殊规则是在ClassLoader类中.
回答你的问题:我的猜测是java.*检查是因为a)历史原因b)在Java核心的某个地方检查类的名称,例如:所有以java开头的类.*get特别待遇.
但是,请考虑即使您设法创建了一个名为java.lang.String的类,它也不会与Java核心定义的java.lang.String类相同.它只是一个具有完全相同名称的类.类标识不仅仅是类的名称,即使你真的很难理解,除非你真的使用ClassLoader.
因此,由java.lang包中的应用程序类加载器加载的类将无法访问核心java.lang包私有内容.
为了说明这一点,尝试使用main方法创建一个名为javax.swing.JButton的类并执行它.你会得到一个java.lang.NoSuchMethodError: main.那是因为java在你的类之前找到了"真正的"JButton,而真正的JButton没有main方法.
在Java独立应用程序中,您可以通过使用reflection和setAccessible直接调用其中一个私有本机defineClassx方法来绕过此限制.
顺便说一句:核心java.lang.String保证在代码执行之前加载,因为它在任何地方都被引用,你不会先用你的用户代码到达那里.在尝试加载类之前,JVM设置到一定程度,更不用说执行它了.
你不能拥有"java.*"包名.这实际上是在Java核心中进行了硬编码,因此您甚至无法授予安全管理员权限来解决它(参见ClassLoader :: preDefineClass(...))
java是保留的包名称.只有JVM中的类可以驻留在此包中.
如果任何人都可以在Java包中编写,那么可能会导致库通过自己的实现任意替换核心Java类.从破解核心Java功能到执行恶意代码,这可能会产生很多想法.
| 归档时间: |
|
| 查看次数: |
44555 次 |
| 最近记录: |