为什么`java.lang.SecurityException:禁止包名:java`是必需的?

我创建了一个类“String”并将其放在包“java”中[实际上我想创建java.lang来查看classLoader加载的类是

一旦一个类被加载到一个JVM中,同一个类(我重复,同一个类)将不会再被加载

引自oreilly]。 但那件事后来,为什么我要跑这个课
java.lang.SecurityException:禁止的包名称: java

为什么java不允许我在java包中有类呢? 如果不存在这种检查,可以做什么?


用户代码绝不允许将类放入其中一个标准Java包中。 这样,用户代码就无法访问Java实现中的任何包 - 专用类/方法/字段。 其中一些包专用对象允许访问JVM内部。 (特别是我在考虑SharedSecrets 。)


首先,这些类型的限制已经到位来执行Java沙箱。 也就是说,在受信任的环境中运行不受信任的代码。 例如,从您的浏览器的计算机(受信任的环境)运行某个站点(您不一定信任)的applet。 目的是禁止不受信任的代码访问包可以帮助它逃离沙盒的私人包。

通常情况下,这些限制是由SecurityManager强制实施的,因此当您在命令行上运行自己的应用程序时(除非明确指定使用SecurityManager),它们不应该发生。 当你控制环境时,你可以去编辑你的Java的rt.jar中的String.class定义(并且从技术上说,无论如何,你不知道什么是许可说的)。 正如我所说的,限制通常在SecurityManager中,但是关于java。*包的特定规则在ClassLoader类中。

回答你的问题:我的猜测是,java。* check是因为a)历史原因b)在Java核心的某个地方有一个类的名称检查,如:所有以java开头的类。* get特别待遇。

但是,考虑到即使您设法创建了一个名为java.lang.String的类,它也不会与Java内核定义的java.lang.String类相同。 这只是一个名字完全相同的课程。 类的身份不仅仅是类的名字,尽管除非你真的使用类加载器,否则这可能会很难理解。

因此,由包java.lang中的应用程序类加载器加载的类将无法访问核心java.lang包私有内容。

为了说明这一点,尝试用main方法创建一个名为javax.swing.JButton的类并执行它。 你会得到一个java.lang.NoSuchMethodError: main 。 这是因为java在你的课程之前找到了“真正的”JButton,而真正的JButton没有一个主要的方法。

在Java独立应用程序中,您可以通过使用reflection和setAccessible直接调用其中一个私有本地defineClassx方法来解决此限制。

顺便说一句:核心java.lang.String保证在你的代码执行之前被加载,因为它被引用到任何地方,你不会首先使用你的用户代码。 在甚至试图加载你的类之前,JVM就已经设置了一定程度,更不用说执行它了。


您不能拥有“java。*”软件包名称。 这实际上是在Java核心中进行硬编码的,所以你甚至不能授予安全管理员权限来解决它(参见ClassLoader :: preDefineClass(...))

链接地址: http://www.djcxy.com/p/84175.html

上一篇: why `java.lang.SecurityException: Prohibited package name: java` is required?

下一篇: What strategy do you use for package naming in Java projects and why?