如何解决FindBugs DP_DO_INSIDE_DO_PRIVILEGED

时间:2013-01-11 13:07:53

标签: java findbugs

在阅读和扫描旧代码时,我看到了以下几行代码:

public static void replaceNull(Object obj)
{
    if (obj == null)
    {
        return;
    }

    Field[] fields = obj.getClass().getDeclaredFields();
    if (fields != null)
    {
        for (Field field : fields)
        {
            field.setAccessible(true);
            Class<?> fieldType = field.getType();
            try
            {
                if (field.get(obj) == null)
                {
                    setDefaultValue(obj, field, fieldType);
                }
            } catch (IllegalArgumentException e)
            {
                logger. error("failed replacing null :"+ e.getMessage(),e);
            } catch (IllegalAccessException e)
            {
                logger. error("failed replacing null :"+ e.getMessage(),e);
            }

        }
    }
}

   private static void setDefaultValue(Object obj, Field field, Class<?> fieldType) throws IllegalAccessException
{
    if (fieldType == String.class)
    {
        field.set(obj, CommonConstants.BLANK);

    } else if (fieldType == Date.class)
    {
        field.set(obj, new Date());
    } else if (fieldType == Long.class)
    {
        field.setLong(obj, 0L);
    } else if (fieldType == Integer.class)
    {
        field.setInt(obj, 0);
    } else if (fieldType == BigDecimal.class)
    {
        field.set(obj, new BigDecimal("0.0"));
    }
}

从程序流程中,如果值为null,编写器似乎想要为对象的所有数据成员创建默认值。

使用FindBugs进行扫描时,findbugs在setAccessible(true)上报告了“DP_DO_INSIDE_DO_PRIVILEGED”以及此描述:

  

不好的做法 - 调用的方法只能在doPrivileged块中调用   插件:findbugs密钥:DP_DO_INSIDE_DO_PRIVILEGED   此代码调用需要安全权限检查的方法。如果此代码将被授予安全权限,但可能由没有安全权限的代码调用,则调用需要在doPrivileged块中进行。

我的问题为什么这么糟糕?我该如何解决呢?

2 个答案:

答案 0 :(得分:8)

来自field#setAccessible(boolean)的Javadoc:

  

首先,如果有安全管理器,则使用ReflectPermission(&#34; suppressAccessChecks&#34;)权限调用其checkPermission方法。

如果没有安装SecurityManager,程序将运行正常。但是,假设您的代码是作为共享库编写的,并且它恰好被某个已设置安全管理器的模块使用。在这种情况下,即使代码中的此操作和其他操作被视为可信代码,也可能会拒绝field.setAccessible(true)权限。这就是FindBugs提出这个警告的原因。

为了保证field.setAccessible(true)始终被授予权限而不管调用者代码的权限如何,您可以将语句包含在AccessController.doPrivileged内(您必须使field AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { field.setAccessible(true); return null; } }); 1}} final):

{{1}}

答案 1 :(得分:1)

添加上面接受的答案,使用Java 1.7+ lambda表达式,可以通过以下方式实现:

AccessController.doPrivileged((PrivilegedAction) () -> {
    field.setAccessible(true);
    return null;
});