为什么我能够重新创建java.lang包和类? [英] Why I am able to re-create java.lang package and classes?

查看:185
本文介绍了为什么我能够重新创建java.lang包和类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩包结构。令我惊讶的是,我可以通过创建具有该名称的包和类名来绕过默认类。



例如:



我创建了一个名为 java.lang 的包,而Class是 Boolean 。当我导入 java.lang.Boolean 时,它不是JDK的 Boolean 版本。这是我的。它只显示了每个对象java都有的 Objects 的方法。



为什么会这样?为什么我被允许创建包 java.lang ?程序运行正常。





另一个障碍是如果我创建一个 Class ,名称 Object 并尝试运行程序然后异常



< pre class =lang-none prettyprint-override> java.lang.SecurityException:禁止的包名:java.lang.ClassLoader.preDefineClass(未知来源)的java.lang

at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)

为什么会出现这种情况?这是一个错误还是正常行为?

解决方案

java.lang classes是运行时限制,而不是编译时间。



JVM实际上专门提供了一种覆盖 java.lang中的类的机制/ code>。您可以使用 -Xbootclasspath 命令行标志


-Xbootclasspath:bootclasspath

指定以分号分隔的目录,JAR文件和ZIP存档列表,以搜索引导类文件。这些用于代替Java平台JDK中包含的引导类文件。



为了覆盖rt.jar中的类而使用此选项的应用程序不应该部署是因为这样做会违反Java Runtime Environment二进制代码许可证。



-Xbootclasspath / a:path

指定以分号分隔的目录,JAR文件和ZIP存档路径,以附加到默认引导程序类路径。



-Xbootclasspath / p:path

指定要在默认值前添加的以分号分隔的目录,JAR文件和ZIP存档路径引导类路径。



不要部署使用此选项的应用程序覆盖rt.jar中的类,因为此违反了Java Runtime Environment二进制代码许可证。


然而,正如我已经用粗体标记强调的那样,这样做违反了 Java SE的Oracle二进制代码许可协议JavaFX技术


D. JAVA技术限制。 您不得创建,修改或更改被许可方的行为,或授权其创建,修改或更改以任何方式标识为java,javax的类,接口或子包的行为,javafx,sun,oracle或Oracle在任何命名约定中指定的类似约定。您不得重新发布附表1中列出的软件。


除上述内容外,您可以添加您想要的任何课程你想要的任何套餐;它在JLS§13.3中有具体讨论:


13.3。包的演变



新的顶级类或接口类型可以添加到包而不破坏与预先存在的二进制文件的兼容性,前提是新类型不重用先前为不相关类型指定的名称。



如果新类型重用先前为不相关类型指定的名称,则可能会导致冲突,这两种类型的二进制文件无法由同一个类加载器加载。



顶层类和非公共接口类型的更改,不是超类或超接口,分别是公共类型,仅影响声明它们的包中的类型。这些类型可能会被删除或以其他方式更改,即使此处另有描述不兼容,只要该包的受影响二进制文件一起更新。



I am just playing with package structure. And to my surprise I can bypass the default classes by creating my package and class name with that name.

For ex:

I created a package called java.lang and Class is Boolean. When I import java.lang.Boolean it's not the JDK's version of Boolean. It's mine. It's just showing the methods of Objects which every object java have.

Why so ? Why I am allowed to create the package java.lang? And the program runs fine.

Another baffle is if I create a Class with name Object and try to runs the program then an exception

java.lang.SecurityException: Prohibited package name: java.lang
    at java.lang.ClassLoader.preDefineClass(Unknown Source)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)

Why is this behaviour ? is this a bug or normal behaviour ?

解决方案

The restriction on java.lang classes is a runtime restriction, not a compile time one.

The JVM actually specifically provides a mechanism for overriding classes in java.lang. You can do it using the -Xbootclasspath command line flag:

-Xbootclasspath:bootclasspath
Specifies a semicolon-separated list of directories, JAR files, and ZIP archives to search for boot class files. These are used in place of the boot class files included in the Java platform JDK.

Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed because doing so would contravene the Java Runtime Environment binary code license.

-Xbootclasspath/a:path
Specifies a semicolon-separated path of directories, JAR files, and ZIP archives to append to the default bootstrap class path.

-Xbootclasspath/p:path
Specifies a semicolon-separated path of directories, JAR files, and ZIP archives to add in front of the default bootstrap class path.

Do not deploy applications that use this option to override a class in rt.jar because this violates the Java Runtime Environment binary code license.

However, as I've already emphasized with bold marks, doing so is a violation of the Oracle Binary Code License Agreement for Java SE and JavaFX Technologies:

D. JAVA TECHNOLOGY RESTRICTIONS. You may not create, modify, or change the behavior of, or authorize your licensees to create, modify, or change the behavior of, classes, interfaces, or subpackages that are in any way identified as "java", "javax", "javafx", "sun", "oracle" or similar convention as specified by Oracle in any naming convention designation. You shall not redistribute the Software listed on Schedule 1.

Apart from the above, you may add whatever class you want to whatever packages you want; it's specifically discussed in the the JLS §13.3:

13.3. Evolution of Packages

A new top level class or interface type may be added to a package without breaking compatibility with pre-existing binaries, provided the new type does not reuse a name previously given to an unrelated type.

If a new type reuses a name previously given to an unrelated type, then a conflict may result, since binaries for both types could not be loaded by the same class loader.

Changes in top level class and interface types that are not public and that are not a superclass or superinterface, respectively, of a public type, affect only types within the package in which they are declared. Such types may be deleted or otherwise changed, even if incompatibilities are otherwise described here, provided that the affected binaries of that package are updated together.

这篇关于为什么我能够重新创建java.lang包和类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆