Cambio de comportamiento en la creación de nuevas instancias para interfaces no públicas

Java 8 introduce un cambio de comportamiento para el código que utiliza los métodos Proxy.getProxyClass y Constructor.newInstance para crear una instancia de proxy si el llamador no está en el mismo paquete de ejecución que la interfaz proxy no pública. En Java 7, la utilización de estos métodos hace que se cree la clase de proxy. En Java 8, se produce un error y se emite una excepción IllegalAccessException.

Puesto que el analizador no siempre puede determinar las interfaces que se utilizan o sus visibilidad, esta regla señala todas las invocaciones de Constructor.newInstance(InvocationHandler) excepto cuando están definidas como accesibles. La regla no señala las invocaciones del método Constructor.newInstance(InvocationHandler) que están precedidas en el mismo método con llamadas a los métodos siguientes:

Revise el código de distintivo para ver si se llama al método getProxyClass desde otros paquetes de tiempo de ejecución y si cualquiera de las interfaces de proxy no es públicas. Por ejemplo, una interfaz a nivel de paquete que no contiene la palabra clave public no es pública.

Para crear una clase de proxy en Java 8, utilice uno de los métodos siguientes:

Si existe un gestor de seguridad, en ambos casos es necesario el permiso ReflectPermission("newProxyInPackage.{nombre de paquete}") para evitar una excepción SecurityException.

El ejemplo siguiente muestra cómo puede cambiar el código si el método proxyClass crea una interfaz no pública:

Código original:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Object < /span> instantiateClass(< span class= "JavaType"> Class < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> Exception < /span> {

Object o=null;

o = proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
return o;
}

Solución 1:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Objeto < /span> instantiateClass(< span class= "JavaType"> Clase < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> Excepción < /span> {

Object o=null;

o = proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
Constructor c = proxyClass.getConstructor(InvocationHandler.class);
c.setAccessible(true);
o = c.newInstance(handler);
return o;
}

Solución 2:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Objeto < /span> instantiateClass(< span class= "JavaType"> Clase < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> Excepción < /span> {

Object o=null;
o = Proxy.newProxyInstance(proxyClass.getClassLoader(), proxyClass.getInterfaces(), handler);
return o;
}

Para obtener información adicional, consulte la documentación de Java para las clases siguientes: