Behavior change in new instance creation for non-public interfaces

Java 8 introduces a behavior change for code that uses the Proxy.getProxyClass and the Constructor.newInstance methods to create a proxy instance if the caller is not in the same runtime package as the non-public proxy interface. In Java 7, using these methods creates the proxy class. In Java 8, it fails with an IllegalAccessException.

Because the analyzer cannot always determine the interfaces that are used or their visibility, this rule flags all invocations of Constructor.newInstance(InvocationHandler) except when they are defined as accessible. The rule does not flag invocations of the Constructor.newInstance(InvocationHandler) method that are preceded in the same method with calls to the following methods:

Inspect the flagged code to see if the getProxyClass method is called from other runtime packages and if any of the proxy interfaces are non-public. For example, a package-level interface that does not have the public keyword is non-public.

To create a proxy class in Java 8, use one of the following techniques:

If a security manager is present, both solutions need the ReflectPermission("newProxyInPackage.{package name}") permission to avoid a SecurityException.

The following example shows how you can change the code if the proxyClass method instantiates a non-public interface:

Original code:
public Object instantiateClass(Class<?> proxyClass, InvocationHandler handler) throws Exception {

Object o=null;

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

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

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

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

For additional information, see the Java documentation for the following classes: