代码之家  ›  专栏  ›  技术社区  ›  Rakesh Juyal

为什么JavaLang.SurfyExtExc:禁止的包名:Java'是必需的?

  •  21
  • Rakesh Juyal  · 技术社区  · 16 年前

    我创建了一个类“string”,并将它放入包“Java”中[实际上我想创建]。 贾瓦朗 查看类加载器加载的类为

    一旦一个类被加载到一个JVM中, 同一个班(我重复一遍,同一个班) 将不再加载

    引自奥利里。但那件事以后,为什么我要上这门课
    java.lang.securityException:禁止的包名称: 爪哇

    出于安全原因,Java不允许我在 爪哇 包裹?如果没有这样的支票怎么办?

    8 回复  |  直到 7 年前
        1
  •  23
  •   C. K. Young    16 年前

    用户代码是 从未 允许将类放入标准Java包中的一个。这样,用户代码就无法访问Java实现中的任何包私有类/方法/字段。其中一些包私有对象允许访问JVM内部。(我在想 SharedSecrets 特别是)

        2
  •  16
  •   Sami Koivu    16 年前

    首先,这些类型的限制已经到位来强制执行Java沙箱。也就是说,在受信任的环境中运行不受信任的代码。例如,在浏览器中的计算机(受信任的环境)上从某个站点(不一定信任)运行小程序。其目的是禁止不受信任的代码访问可帮助其逃离沙盒的包私有内容。

    通常,这些限制是由SecurityManager强制执行的,因此当您在命令行上运行自己的应用程序时(除非您明确指定使用SecurityManager),它们不应该发生。当你控制环境时,你可以去编辑你的Java的RT.jar中的Strug.Car定义(你可以从技术上说,不知道许可是什么)。正如我所说的,限制通常在SuffigyMeal管理中,但是关于Java.*包的这个特定规则在类加载器类中。

    要回答你的问题:我猜想Java.*检查是因为 a)历史原因 B)Java核心中的某个地方检查类的名称,比如:从Java开始的所有类。*得到特殊的处理。

    但是,考虑到即使您成功创建了一个名为java. Lang.Stand的类,它也不会是Java核心定义的JavaLang.Stand的类。它只是一个同名的类。类标识不仅仅是类的名称,即使这很难理解,除非您真正使用类加载器。

    因此,由包java.lang中的应用程序类加载器加载的类将无法访问核心java.lang包私有内容。

    为了说明这一点,尝试用一个主方法创建一个名为javax.swing.jbutton的类,并执行它。你会得到一个 java.lang.NoSuchMethodError: main . 这是因为Java在你的类之前找到了“真正的”JBut纽,而真正的JButton没有一个主要的方法。

    在Java独立应用程序中,您可以通过使用反射和可访问的直接调用私有本机定义的方法之一来绕过这个限制。

    顺便说一句:核心java.lang.string保证在代码执行之前被加载,因为它在任何地方都被引用,所以您不会首先使用您的用户代码。JVM在尝试加载类之前就已经设置好了,更不用说执行它了。

        3
  •  8
  •   Coder Guy    14 年前

    您不能拥有“java. *”包名。这实际上是在Java内核中硬编码的,因此您甚至不能授予安全管理器权限来处理它(参见CultLooul::PrimeDeCuxLASS(…))。

        4
  •  7
  •   Vivien Barousse    16 年前

    java 是保留的包名称。只有JVM中的类才能驻留在这个包中。

    如果任何人可以在Java包中写入,这可能导致库通过它们自己的实现任意地替换核心Java类。这可能会导致很多想法,从破坏核心Java特性到执行恶意代码。

        5
  •  2
  •   Bert F    16 年前

    如果程序可以用特洛伊木马版本覆盖JVM核心类,那么程序可以绕过安全措施。例如,字符串实际上无处不在。

        6
  •  1
  •   idelvall    10 年前

    代码>类加载器。 < Buff行情>

    …指定的类名不能以“Java”开头。,因为“Java.*包中的所有类只能由Bootstrap类加载器< /P>定义”。 < /块引用>

    < Buff行情> <投掷:…安全性异常-如果尝试将这个类添加到一个包中,该包包含由该类不同的证书集签名的类,或者类名以“Java”开头。

    < /块引用> javadoc:

    …指定的类名不能以“Java”开头。,因为“java. *包中的所有类只能由Bootstrap类加载器定义。

    投掷:…安全性异常-如果尝试将这个类添加到一个包中,该包包含由该类不同的证书集签名的类,或者类名以“Java”开头。.

        7
  •  0
  •   szczepan.kurnyta    12 年前

    可能在重构/补丁应用程序等期间,您已经添加到包名称Word“Java”,它通常是包含包的文件夹。

    所以你可以以结构结尾: SRC & GT;Meave& Gt;Java≫Java.C.YouP包装

    也可能发生在测试中: SRC & GT;主& gt;测试& gt;java>java.com。

    在IDE中验证它并删除“Java”部分。

        8
  •  0
  •   Sadeq Dousti    7 年前

    摘录 java.lang.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)
    {
        ...
    
        // 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('.')));
        }
    
        ...
    }
    

    请注意 类加载器 是一个抽象类,意思是子类(比如, SecureClassLoader )将实际实现它。然而, 预先定义的字符 方法是 private ,因此它不能被子类重写。

    预先定义的字符 是由 defineClass 方法,即 protected final . 这意味着 定义类 子类可以访问并且可以调用它,但是它们不能更改它的实现。