ITmob-Ly
发布于 2022-08-29 / 252 阅读
0

Java Exception - java.lang.SecurityException: Prohibited package name: java.*

Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.demo
        at java.base/java.lang.ClassLoader.preDefineClass(ClassLoader.java:898)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1014)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:468)
        at java.base/sun.launcher.LauncherHelper.loadMainClass(LauncherHelper.java:780)
        at java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:675)

因为 JVM 禁止包以 java 开头,修改包名即可。

java.lang.ClassLoader 类对类名做了检查,如果以 java.* 的格式作为包名的话,则会抛出异常:SecurityException("Prohibited package name: " + name.substring(0, name.lastIndexOf('.')))

源码:ClassLoader类的preDefineClass方法

/* 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)
{
    if (!checkName(name))
        throw new NoClassDefFoundError("IllegalName: " + name);

    // 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.")
            && this != getBuiltinPlatformClassLoader()) {
        throw new SecurityException
            ("Prohibited package name: " +
             name.substring(0, name.lastIndexOf('.')));
    }
    if (pd == null) {
        pd = defaultDomain;
    }

    if (name != null) {
        checkCerts(name, pd.getCodeSource());
    }

    return pd;
}