37

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.

enter image description here

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 ?

4

4 回答 4

36
于 2015-08-25T22:58:08.693 回答
4

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");
    }
}
于 2015-08-23T11:34:57.410 回答
4

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"));

}

于 2015-08-30T05:19:39.683 回答
1

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. :)

于 2015-08-29T12:46:43.820 回答