Changement de comportement de création de nouvelle instance pour les interfaces non publiques

Java 8 a ajouté un changement de comportement pour le code qui utilise les méthodes Proxy.getProxyClass et Constructor.newInstance afin de créer une instance de proxy si l'appelant ne se trouve pas dans le même package d'exécution que l'interface proxy non publique. Dans Java 7, l'utilisation de ces méthodes crée la classe de proxy. Dans Java 8, elle provoque un échec et une exception IllegalAccessException est générée.

Etant donné que l'analyseur ne peut pas toujours déterminer les interfaces utilisées ou leur visibilité, cette règle marque tous les appels de Constructor.newInstance(InvocationHandler), sauf lorsque ceux-ci sont définis comme accessibles. Cette règle ne marque pas les appels de méthode Constructor.newInstance(InvocationHandler) qui sont précédés, dans la même méthode, d'appels aux méthodes suivantes :

Inspectez le code marqué afin de voir si la méthode getProxyClass est appelée à partir d'autres packages d'exécution et de vérifier si une des interfaces de proxy est non publique. Par exemple, une interface de niveau package n'ayant pas le mot clé public est non publique.

Pour créer une classe de proxy dans Java 8, utilisez une des techniques suivantes :

S'il existe un gestionnaire de sécurité, les deux solutions doivent disposer du droit ReflectPermission("newProxyInPackage.{package name}") afin d'éviter une exception SecurityException.

L'exemple suivant présente comment vous pouvez changer le code si la méthode proxyClass instancie une interface non publique :

Code d'origine :
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Objet < /span> instantiateClass(< span class= "JavaType"> Classe < ?> < /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;
}

Solution 1 :
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Objet < /span> instantiateClass(< span class= "JavaType"> Classe < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> Exception < /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;
}

Solution 2 :
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Objet < /span> instantiateClass(< span class= "JavaType"> Classe < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> Exception < /span> {

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

Pour plus d'informations, voir la documentation Java des classes suivantes :