Изменение логики создания нового экземпляра для интерфейсов без спецификатора public

В Java 8 изменена логика для кода, который использует методы Proxy.getProxyClass и Constructor.newInstance для создания экземпляра посредника, если инициатор и интерфейс посредника, объявленный без спецификатора public, находятся в разных пакетах среды выполнения. В Java 7 применение этих методов приводило к созданию класса посредника. В Java 8 возникает исключительная ситуация IllegalAccessException.

Поскольку анализатор не всегда может определить используемые интерфейсы и их область видимости, данное правило помечает все вызовы метода Constructor.newInstance(InvocationHandler), за исключением случаев, когда они определены как доступные. Правило не помечает вызовы метода Constructor.newInstance(InvocationHandler), перед которыми в коде объемлющего метода есть вызовы следующих методов:

Проверьте, есть ли в помеченном коде вызовы метода getProxyClass из других пакетов среды выполнения и есть ли интерфейсы посредников без спецификатора public. Например, интерфейс уровня пакета без спецификатора public.

Для создания класса посредника в Java 8 используйте один из следующих приемов:

Если есть администратор защиты, оба решения требуют прав доступа ReflectPermission("newProxyInPackage.{имя-пакета}"). В противном случае возникнет исключительная ситуация SecurityException.

В следующем примере показано, как изменить код, если метод proxyClass создает экземпляр интерфейса, который объявлен без спецификатора public:

Исходный код:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Объект < /span> instantiateClass(< span class= "JavaType"> Class < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> Исключительная ситуация < /span> {

Object o=null;

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

Решение 1:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Объект < /span> instantiateClass(< span class= "JavaType"> Class < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> Исключительная ситуация < /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;
}

Решение 2:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Объект < /span> instantiateClass(< span class= "JavaType"> Class < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> Исключительная ситуация < /span> {

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

Дополнительную информацию можно найти в документации Java для следующих классов: