Além de compreender os acessos entre os módulos e seus respectivos pacotes. Acredito que o ponto crucial disso está no Módulo System # Relaxed-strong-encapsulation e eu selecionaria as partes relevantes para tentar responder à pergunta.
O que define um acesso reflexivo ilegal e quais circunstâncias acionam o aviso?
Para ajudar na migração para Java-9, o encapsulamento forte dos módulos pode ser relaxado.
Uma implementação pode fornecer acesso estático , ou seja, por bytecode compilado.
Pode fornecer um meio de invocar seu sistema de tempo de execução com um ou mais pacotes de um ou mais de seus módulos abertos para código em todos os módulos não nomeados , ou seja, para código no classpath. Se o sistema de tempo de execução for invocado dessa forma, e ao fazer isso, algumas invocações das APIs de reflexão serão bem-sucedidas onde, de outra forma, teriam falhado.
Nesses casos, você acabou fazendo um acesso reflexivo que é "ilegal", já que em um mundo modular puro você não deveria fazer tais acessos.
Como tudo se encaixa e o que dispara o aviso em qual cenário?
Esse relaxamento do encapsulamento é controlado no tempo de execução por uma nova opção do ativador --illegal-access
que, por padrão, no Java9 é igual permit
. O permit
modo garante
A primeira operação de acesso reflexivo a qualquer um desses pacotes faz com que um aviso seja emitido, mas nenhum aviso é emitido após esse ponto. Este único aviso descreve como habilitar outros avisos. Este aviso não pode ser suprimido.
Os modos são configuráveis com valores debug
(mensagem, bem como rastreamento de pilha para cada acesso), warn
(mensagem para cada acesso) e deny
(desativa essas operações).
Poucas coisas para depurar e corrigir nos aplicativos seriam: -
- Execute-o com
--illegal-access=deny
para conhecer e evitar a abertura de pacotes de um módulo para outro sem uma declaração de módulo incluindo tal diretiva ( opens
) ou o uso explícito de --add-opens
VM arg.
- As referências estáticas do código compilado para APIs internas do JDK podem ser identificadas usando a
jdeps
ferramenta com a --jdk-internals
opção
A mensagem de aviso emitida quando uma operação de acesso reflexivo ilegal é detectada tem o seguinte formato:
WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM
Onde:
$PERPETRATOR
é o nome totalmente qualificado do tipo que contém o código que invocou a operação reflexiva em questão mais o código-fonte (ou seja, caminho do arquivo JAR), se disponível, e
$VICTIM
é uma string que descreve o membro que está sendo acessado, incluindo o nome totalmente qualificado do tipo envolvente
Perguntas para esse exemplo de aviso: = JDK9: Ocorreu uma operação de acesso reflexivo ilegal. org.python.core.PySystemState
Por último e uma observação importante, ao tentar garantir que você não enfrente tais avisos e esteja seguro no futuro, tudo que você precisa fazer é garantir que seus módulos não estejam fazendo aqueles acessos reflexivos ilegais. :)