Why I am able to re-create java.lang package and classes?

守給你的承諾、 提交于 2019-11-29 23:37:17

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.

Answer to SecurityException related question:

SecurityManger throws this RuntimeException while your classloader calling defineClass method and encountered specified class(your "custom class") name has "java.*" in it.

This is because you defined your class in "java.*" package and as per ClassLoader's documentation this is not allowed.

defineClass( )

..

The specified name cannot begin with "java.", since all classes in the "java.* packages can only be defined by the bootstrap class loader. If name is not null, it must be equal to the binary name of the class specified by the byte array "b", otherwise a NoClassDefFoundError will be thrown.

Throws: ..

SecurityException - If an attempt is made to add this class to a package that contains classes that were signed by a different set of certificates than this class, or if name begins with "java.".

For your testing, try creating java.test package and define one Custom class (names doesn't matter; like Object..). In this case as well you will get same SecurityException.

package java.test;

public class Test {

    public static void main(String[] args) {

        System.out.println("This is Test");
    }
}

This is not Bug.

Behaviour beacause of:

When the Java Virtual Machine (JVM) tries to load our class, it recognizes its package name as invalid and thus, a SecurityException is thrown. The SecurityException indicates that a security violation has occurred an thus, the application cannot be executed. public class SecurityException extends RuntimeException Thrown by the security manager to indicate a security violation.

please use different package name it not for only language package of java.it covers all package not gives permissions to override in build classes and packages of java.

By Changing this we can create or override same package and class:

a/j2ee.core.utilities/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiers.java b/j2ee.core.utilities/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiers.java

**if (packageName.startsWith(".") || packageName.endsWith(".")) {// NOI18N
          return false;
        }

   if(packageName.equals("java") || packageName.startsWith("java.")) {//NOI18N
          return false;
      }**

    String[] tokens = packageName.split("\\."); //NOI18N
       if (tokens.length == 0) {
          return Utilities.isJavaIdentifier(packageName);
 a/j2ee.core.utilities/test/unit/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiersTest.java    b/j2ee.core.utilities/test/unit/src/org/netbeans/modules/j2ee/core/api/support/java/JavaIdentifiersTest.java

      assertFalse(JavaIdentifiers.isValidPackageName(" "));
      assertFalse(JavaIdentifiers.isValidPackageName("public"));
      assertFalse(JavaIdentifiers.isValidPackageName("int"));
      assertFalse(JavaIdentifiers.isValidPackageName("java"));
      assertFalse(JavaIdentifiers.isValidPackageName("java.something"));

}

Your problem with java.lang.Boolean as your Boolean Class, and not the Object one is simple to explain.

The Object class is the root of every other classes you can find, use, or even create. Which means that if you could have the ability to override it, not a single class, method, or whatever you want to use would work, since every of them depends on that root class.
For the Boolean Class, it is not a boolean type, but a class for a boolean type. And since nothing depends on it, it is then possible to override it.
A better way to understand this problem, is to look at this link:
[http://docs.oracle.com/javase/7/docs/api/overview-tree.html]
You will notice that every kind of package, containing every kind of java classes, depends on the Object Class.

So the security exception you encountered is like a "life savior" for your program.
If I'm wrong about your question, other persons may find a more appropriate answer to it. :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!