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

Viewed 57598

I created a class "String" and placed that in package "java" [ actually i wanted to create java.lang to see which class is loaded by classLoader as

Once a class is loaded into a JVM, the same class (I repeat, the same class) will not be loaded again

quoted from oreilly ] . But that thing later, why on running this class i am getting
java.lang.SecurityException: Prohibited package name: java

For which security reason java is not allowing me to have a class in java package? What one could do if there will not be no such check?

8 Answers

An excerpt from java.lang.ClassLoader's preDefineClass method:

/* Determine protection domain, and check that:
    - not define java.* class,
    - signer of this class matches signers for the rest of the classes in
      package.
*/
private ProtectionDomain preDefineClass(String name,
                                        ProtectionDomain pd)
{
    ...

    // Note:  Checking logic in java.lang.invoke.MemberName.checkForTypeAlias
    // relies on the fact that spoofing is impossible if a class has a name
    // of the form "java.*"
    if ((name != null) && name.startsWith("java.")) {
        throw new SecurityException
            ("Prohibited package name: " +
             name.substring(0, name.lastIndexOf('.')));
    }

    ...
}

Please note that java.lang.ClassLoader is an abstract class, meaning that a subclass (say, SecureClassLoader) will actually implement it. However, the preDefineClass method is private, so it cannot be overridden by a subclass.

preDefineClass is called by the defineClass method, which is protected final. This means defineClass is accessible to subclasses and they can call it, but they won't be able to change its implementation.

Related