Geändertes Verhalten beim Erstellen einer neuen Instanz für nicht öffentliche Schnittstellen

In Java 8 wurde das Verhalten von Code geändert, der die Methoden Proxy.getProxyClass und Constructor.newInstance verwendet, um eine Proxy-Instanz zu erstellen, wenn sich der aufrufende Code nicht in demselben Laufzeitpaket wie die nicht öffentliche Proxy-Schnittstelle befindet. In Java 7 wird bei der Verwendung dieser Methoden die Proxy-Klasse erstellt. In Java 8 schlägt die Erstellung mit einer Ausnahme des Typs IllegalAccessException fehl.

Da die Analysefunktion die verwendeten Schnittstellen bzw. deren Sichtbarkeit nicht immer bestimmen kann, markiert diese Regel alle Aufrufe von Constructor.newInstance(InvocationHandler) mit Ausnahme der Fälle, in denen die Methode als zugänglich definiert ist. Die Regel markiert keine Aufrufe der Methode Constructor.newInstance(InvocationHandler), denen in derselben Methode Aufrufe der folgenden Methoden vorausgehen:

Überprüfen Sie den markierten Code, um festzustellen, ob die Methode getProxyClass in anderen Laufzeitpaketen aufgerufen wird und ob es Proxy-Schnittstellen gibt, die nicht öffentlich sind. Eine Schnittstelle auf Paketebene, die das Schlüsselwort public nicht enthält, ist nicht öffentlich.

Verwenden Sie zum Erstellen einer Proxy-Klasse in Java 8 eine der folgenden Techniken:

Wenn ein Sicherheitsmanager vorhanden ist, benötigen beide Lösungen die Berechtigung ReflectPermission("newProxyInPackage.{package name}"), um eine Ausnahme des Typs SecurityException zu vermeiden.

Das folgende Beispiel zeigt, wie Sie den Code ändern können, wenn die Methode proxyClass eine nicht öffentliche Schnittstelle instanziiert:

Ursprünglicher Code:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Objekt < /span> instantiateClass(< span class= "JavaType"> Klasse < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) löst < span class= "JavaType"> Ausnahmebedingung < /span> {

Object o=null;

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

Lösung 1:
public Object instantiateClass(Class<?> proxyClass, InvocationHandler handler) throws Exception {

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;
}

Lösung 2:
public Object instantiateClass(Class<?> proxyClass, InvocationHandler handler) throws Exception {

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

Weitere Informationen finden Sie in der Java-Dokumentation zu den folgenden Klassen: