Quais são as razões para selar um .jar e como eu verificaria isso?

9

Eu criei um frasco selado, mas não vejo diferença em comparação com o uso de um não selado.

  • Quais testes posso executar para verificar se o frasco está lacrado?
  • Que razão poderíamos ter para preferir usar um lacrado em vez de não um?
  • Um lacrado criará algum problema para os usuários dos meus projetos?
Poder do Aquário
fonte
3
Eu reformulei o título e a pergunta principal no post (principalmente pequenos ajustes de redação neste momento). Deve estar um pouco melhor agora.
1
Você leu pacotes de vedação em um arquivo JAR ? Isso se aplica tanto a pacotes individuais quanto a frascos inteiros.

Respostas:

10

Você pode testar se um jar está selado, definindo uma classe para existir em um pacote usado no arquivo jar. Se o frasco estiver selado, todas as embalagens serão normalmente lacradas; caso contrário, você poderá selá-las por embalagem. A classe que você cria deve tentar acessar membros protegidos ou padrão de uma classe nesse pacote.

Por exemplo, se o jar tiver uma classe em com.example.Widgetque o pacote com.exampleestá selado e Widgettiver membros protegidos / padrão, crie uma classe com.example.Testque tente acessar esses membros. Isso deve falhar.

O motivo do selamento segue uma descrição de como testá-lo: você deseja que seu código seja independente e os usuários do jar devem usar apenas membros públicos. Não é necessário que os pacotes sejam exclusivos entre jars (e pastas bin no seu IDE) usados ​​por um programa. Você pode definir uma classe no mesmo pacote que em um jar e acessar membros protegidos / padrão que podem causar problemas. Freqüentemente, a visibilidade padrão é usada como um análogo à friendpalavra-chave do C ++, permitindo que outras classes no mesmo pacote executem ações que são seguras apenas porque os mesmos programadores trabalham em ambas as classes e entendem seus elementos internos. Talvez um método de visibilidade padrão renuncie a alguns limites de verificação no nome do desempenho, com o entendimento de que o código do cliente nunca o acessará. Por exemplo, oStringA classe em Java possui alguns desses tipos de métodos, pois o manuseio de String precisa ser rápido, porque uma grande quantidade de código depende disso. BigDecimalé construído sobre BigIntegere usa o acesso padrão para otimizar algumas operações que outros usuários da classe não devem usar.

TL; DR : as classes no mesmo pacote podem acessar membros não públicos entre si por desempenho ou simplicidade. Esse acesso pode não verificar invariantes e pré-condições. Pode-se colocar classes no mesmo pacote em vários locais no caminho de classe. A vedação de um pacote ou jar impede que o código do cliente acesse esses métodos, pois pode quebrar outras coisas.

Isso não causará problemas para os usuários do jar. O mecanismo de carregamento de classe que acessa recursos (por exemplo, arquivos de classe) em jars suporta totalmente jars e pacotes selados.

Leitura relacionada: Selando Pacotes em um Arquivo JAR


fonte
portanto, se eu quiser que o Widget seja totalmente extensível, não devo selar o frasco, pois os membros protegidos ficarão inacessíveis? ou pode criar outro frasco que não esteja selado para isso, certo? em outras palavras, como o 3D JMonkeyEngine, eles não selam seus frascos, eu acho (e eu devo cuidar para não selá-lo também durante a distribuição, mas verei meu próprio projeto não funcionando se estiver selado, eu acho, porque eu estendo e acessar membros protegidos).
Poder de Aquário
Além disso, eu queria impedir o acesso de membros protegidos de classes no mesmo projeto; nesse caso, acho que precisaria criar outro projeto pequeno e usar seu pote selado no projeto principal, certo? ou poderia haver outra maneira?
Poder de Aquário
Também li sobre uma SecurityException no caso de tentarmos "substituir uma classe" de um pacote selado.
Poder de Aquário
1
No artigo vinculado: "Os pacotes nos arquivos JAR podem ser opcionalmente selados, o que significa que todas as classes definidas nesse pacote devem ser arquivadas no mesmo arquivo JAR." Trata-se apenas de restringir a especificação de pacote de uma classe, que tem impacto nos membros padrão / protegidos, acessíveis por outras classes no mesmo pacote que eu descrevi na minha resposta. Isso é ortogonal à herança, o que significa que você pode estender as classes em jarros fechados e acessar membros protegidos dessa maneira.
Se você quiser que uma classe em um pacote lacrado não seja estendida, faça-o final. Se você deseja que ele seja estendido dentro do jar, mas não fora ... você precisa começar a olhar para as classes de visibilidade padrão, interfaces, métodos de fábrica, etc. que estão fora do escopo desta pergunta.
2

Para responder sua segunda pergunta, selamos nossos Jars como uma medida de segurança, pois isso evita uma forma de injeção de código onde classes adicionais são adicionadas à nossa base de código no tempo de execução.

Temos uma certa quantidade de reflexão em nosso código, onde os objetos são criados com base na entrada do usuário. O código que cria esses objetos permitirá apenas que instâncias de nomes de pacotes fixos sejam instanciadas.

Ao selar os frascos que contêm as classes que queremos que os usuários possam criar, não há como o usuário criar novas classes potencialmente perigosas e fazer com que nosso software as instale em tempo de execução. A menos que a classe esteja no pacote correto, nosso código não a carregará, e selar os Jars significa que apenas as classes às quais desejamos que os usuários tenham acesso são acessíveis.

Se nossos Jars não fossem selados, o usuário poderia adicionar novas classes que poderiam ser instanciadas. Isso seria um risco de segurança.

TL; DR: selando seus Jars, você pode impedir um tipo de injeção de código malicioso.

Mark Douglas
fonte
Então, basicamente, precisaríamos codificar (constante de seqüência de caracteres) o acesso às classes instanciadas recentemente para garantir que elas estejam no pacote correto? Gostaria de saber também se isso poderia interferir na criação de perfil jrat?
Poder de Aquário