在调用 java.awt.image.RenderedImage class 的 getWidth() 方法时获取 java.security.AccessControlException

Getting java.security.AccessControlException on on calling getWidth() method of java.awt.image.RenderedImage class

通过调用 java.awt.image.RenderedImage 的 getWidth() 方法获得 java.security.AccessControlException class。

导致问题的代码

new Dimension(this.image.getWidth(), this.image.getHeight())

在上面的代码中 this.image 是类型 java.awt.image.RenderedImage class

完整堆栈跟踪

java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.com.sun.media.jai.util")
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPackageAccess(Unknown Source)
    at sun.plugin2.applet.SecurityManagerHelper.checkPackageAccessHelper(Unknown Source)
    at sun.plugin2.applet.AWTAppletSecurityManager.checkPackageAccess(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at javax.media.jai.ScaleOpImage.layoutHelper(ScaleOpImage.java:228)
    at javax.media.jai.ScaleOpImage.(ScaleOpImage.java:437)
    at com.sun.media.jai.opimage.ScaleNearestBinaryOpImage.(ScaleNearestBinaryOpImage.java:77)
    at com.sun.media.jai.opimage.ScaleCRIF.create(ScaleCRIF.java:123)
    ... 33 more

注意:

我已将以下行添加到我的 java.policy 文件中

 permission java.lang.RuntimePermission "accessClassInPackage.*";
 permission java.lang.RuntimePermission "accessClassInPackage.com.sun.media.jai.opimage";

还是不行。有人遇到过这个问题吗?我是运行jre 1.8版的小程序0_45

更新:

如果我们将以下条目添加到 java.policy 文件

,则相同的代码将适用于 Java 7
permission java.util.PropertyPermission com.sun.media.imageio.disableCodecLib", "read";

成功了。以下是我所做的修复的详细信息

1] 添加 permission:all-permissions 到 MANIFEST.MF:实际上我的 applet jar 的清单中已经有这个条目。但是我的 jar 依赖于没有此条目的 jai-core、jai-imageio 和 jai-codec jar。因此,我使用 maven shade 插件生成了一个 uber jar,这样我的 applet jar 及其所有依赖项将打包在一个 jar 中,并引用其清单,清单中将包含条目 permission:all-permissions

2] 完成第 1 步后,我得到 java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.com.sun.media.jai.util")

这个异常可以通过两种方式解决

a] 通过将条目 permission java.lang.RuntimePermission "accessClassInPackage.com.sun.media.jai.util"; 添加到可以在位置 C:\Program Files\Java\jre1.8.0_45\lib\security

中找到的 java.policy 文件

这种方法不是很酷,因为它需要在每个客户端系统中修改 java.policy 文件。所以我使用了方法 b

中描述的替代方法来实现 PrivilegedAction

b] 通过实施 PrivilegedAction,您必须实施它的 运行() 方法。 运行() 方法中的所有代码都将在启用权限的情况下执行,因此您不会获得任何 AccessControlException。您确定抛出 AccessControlException 的代码并将该代码放入覆盖的 运行() 方法中,以便该代码具有必要的权限。

例如,在我的例子中,以下代码抛出 AccessControlException

graphics2d.drawRenderedImage(image, new AffineTransform());

为了修复它,我在我的 class 中创建了一个私有 class 并实现了如下所示的 PrivilegedAction

 private final class DrawRenderedImage implements PrivilegedAction
{
    private Graphics2D graphics2D = null;

    public DrawRenderedImage(Graphics2D graphics)
    {
        graphics2D = graphics;
        // TODO Auto-generated constructor stub
    }

    public Object run()
    {

            graphics2D.drawRenderedImage(image, new AffineTransform());


        return new Boolean(true);
    }
}

如您所见,我已将导致问题的代码放入 运行 方法中。现在 运行 方法可以像下面这样调用

AccessController.doPrivileged(new DrawRenderedImage(graphics2d));

此处 AccessController class 将调用 PrivilegedAction 实例的 运行 方法。

通过这样做,您不必像方法 a

中提到的那样将权限放入 java.policy 文件中