Estou familiarizado com o Java Platform Module System.
O javadoc Module#addOpens
esboça um caso de uso que não consigo traduzir para o mundo real:
Este método pode ser usado para casos em que um módulo consumidor usa um opens qualificado para abrir um pacote para um módulo API, mas onde o acesso reflexivo aos membros de classes no módulo consumidor é delegado ao código em outro módulo. O código no módulo API pode usar este método para abrir o pacote no módulo consumidor para o outro módulo .
Confesso que sou muito estúpido para dar o salto desta descrição para o mundo real. Posso ver que isso tem a ver com expandir o acesso reflexivo profundo de alguma forma, mas não tenho certeza de qual é essa forma, particularmente dada a descrição do método em si:
Se este módulo [o " módulo consumidor "? talvez?] abriu um pacote para pelo menos o módulo chamador [o " módulo API "? talvez?], então atualize este módulo para abrir o pacote para o módulo fornecido [o " outro módulo "? talvez?].
Tenho uma vaga e quase certamente errada sensação de que isso está relacionado a, digamos, meu módulo (o "módulo do consumidor"?) abrindo um pacote para algo como Servlet (o "módulo da API"?), sem saber em tempo de execução que a implementação do Servlet em jogo é, na verdade, (digamos) Tomcat, então, se meu código desejar, ele (eu acho?) pode chamar esse método e, assim, de alguma forma, permitir que o Tomcat (o "outro" módulo?) faça coisas reflexivas sem saber que é, de fato, o Tomcat (e não, digamos, o Jetty) fazendo essas coisas reflexivas, e sem precisar ter um extra, opens com.foo.bar to Tomcat
bem module-info
como opens com.foo.bar to Servlet
.
(Também não tenho certeza de onde a "delegação" deveria estar acontecendo; o Servlet não pode "delegar" nada ao Tomcat neste cenário.)
Mas, dadas Lookup
as restrições de sensibilidade do site de chamada, não tenho certeza de como isso deve funcionar, ou onde e quando no meu código neste cenário eu devo fazer esse tipo de chamada, ou por que, se eu já adicionei uma opens
declaração, agora também devo fazer algo programático. Eu entendo o objetivo motivador da integridade e que a permissão deve ser concedida para acesso reflexivo e que isso deve , de alguma forma, tornar as coisas mais fáceis, mas não consigo chegar lá concretamente.
Em resumo: existe realmente um caso de uso concreto para esse recurso? Se sim, qual é? Como ele funciona?
O código de ligação xml Jakarta usa esse método em
jakarta.xml.bind.ModuleUtil.delegateAddOpensToImplModule
O código fonte está aqui
No código Javadoc do JDK também
TagletManager
éjdk.javadoc.internal.doclets.formats.html.taglet
usado isso.Majoritariamente:
Aplicação de patches
Se você quiser 'editar' um módulo 'no local' por meio de patch (chamar seus métodos privados ou modificá-lo de alguma outra forma em tempo de execução, em vez de bifurcá-lo a partir da fonte, editar essa fonte e liberar uma bifurcação modificada), você pode acessar os componentes internos do que está corrigindo/estendendo usando
--add-opens
.Legado
É um termo com conotações negativas, mas não é o que se pretende aqui: Muitas coisas são possíveis apenas com reflexão e o OpenJDK tem quebrado coisas a torto e a direito ao tornar isso impossível. Às vezes, uma substituição adequada está disponível. Mas às vezes, não há.
--add-opens
pode restaurar a funcionalidade sem exigir que um autor de biblioteca tire um coelho da cartola.Geralmente você faz essas coisas na linha de comando, mas quando um sistema existente é configurado com os
--add-opens
switches apropriados sempre que é iniciado, e depois refatora um pouco seu aplicativo e o módulo real que acaba hospedando o código que precisa dos direitos de 'abertura' é algum submódulo, então você pode usar oaddOpens
método onModule
para 'estender o guarda-chuva' dos direitos de abertura adicionais do seu módulo para seu submódulo. Dessa forma, por exemplo, seus scripts de inicialização ou seus cronjobs ou outros (o lugar onde ojava --add-opens
comando real é escrito que inicia seu aplicativo) não precisa ser modificado.