Mudança de comportamento em nova criação de instância para interfaces não públicas

O Java 8 introduz uma mudança de comportamento para código que usa os métodos Proxy.getProxyClass e Constructor.newInstance para criar uma instância de proxy se o responsável pela chamada não estiver no mesmo pacote de tempo de execução que a interface proxy não pública. No Java 7, o uso desses métodos cria a classe de proxy. No Java 8, ele falha com um IllegalAccessException.

Porque o analisador não pode sempre determinar as interfaces que são usadas ou a sua visibilidade, esta regra sinaliza todas as chamadas de Constructor.newInstance(InvocationHandler), exceto quando elas são definidas como acessíveis. A regra não sinaliza chamadas do método Constructor.newInstance(InvocationHandler) que são precedidas no mesmo método com chamadas para os métodos a seguir:

Inspecione o código sinalizado para ver se o método getProxyClass é chamado a partir de outros pacotes de tempo de execução e se alguma das interfaces de proxy são não publicas. Por exemplo, uma interface de nível do pacote que não possui a palavra-chave public é não pública.

Para criar uma classe de proxy no Java 8, use uma das técnicas a seguir:

Se um gerenciador de segurança estiver presente, ambas as soluções precisarão da permissão ReflectPermission("newProxyInPackage.{nome do pacote}") para evitar um SecurityException.

O exemplo a seguir mostra como é possível alterar o código se o método proxyClass instanciar uma interface não 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> manipulador) lança < span class= "JavaType"> Exceção < /span> {

Object o=null;

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

Solução 1:
< span class="Code"> < span class= "JavaKeyword"> público < /span> < span class="JavaType"> Objeto < /span> instantiateClass(< span class= "JavaType"> Classe < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) lança < span class= "JavaType"> Exceção < /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;
}

Solução 2:
< span class="Code"> < span class= "JavaKeyword"> público < /span> < span class="JavaType"> Objeto < /span> instantiateClass(< span class= "JavaType"> Classe < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) lança < span class= "JavaType"> Exceção < /span> {

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

Para obter informações adicionais, veja a documentação Java para as classes a seguir: