Você resolveu usar Java 9 no seu projeto e criou um módulo:
module br.com.alexandreaquiles.projeto { }
Por padrão, todo módulo “puxa” o java.base
, que disponibiliza pacotes como java.lang
, java.math
, java.util
e java.io
.
Vamos dizer que seu código usa o JDBC. Pra poder ter acesso a interfaces como Connection
e PreparedStatement
, você precisa dizer que usa o módulo java.sql
:
module br.com.alexandreaquiles.projeto { requires java.sql; }
JARs não modularizados
Agora, digamos que o seu projeto usa a biblioteca commonmark, responsável por renderizar arquivos Markdown.
Os desenvolvedores dessa biblioteca não criaram um module-info.java
. Ou seja, o JAR do commonmark
não está modularizado.
O que preciso colocar no requires
pra usar classes dessa biblioteca no meu código?
Você precisa “puxar” o módulo org.commonmark
:
module br.com.alexandreaquiles.projeto { requires java.sql; requires org.commonmark; }
Automatic-Module-Name
Mas da onde vem esse nome?
Para todo JAR não modularizado, é criado um módulo automaticamente, que exporta todos os pacotes.
O nome desse módulo automático pode ser definido pelos desenvolvedores da biblioteca na propriedade Automatic-Module-Name
do arquivo META-INF/MANIFEST.MF
lá dentro do JAR.
É uma estratégia de compatibilidade em que o nome do módulo automático é informado explicitamente.
O conteúdo do META-INF/MANIFEST.MF
de dentro do commonmark-0.11.0.jar
é o seguinte:
Manifest-Version: 1.0 Automatic-Module-Name: org.commonmark Built-By: bamboo-agent Created-By: Apache Maven 3.3.9 Build-Jdk: 1.8.0_144
Por isso, pra puxar o módulo automático do commonmark
para nosso módulo, usamos o nome org.commonmark
.
jar –describe-module
Mas e quando os desenvolvedores da biblioteca não colocaram a propriedade Automatic-Module-Name
no MANIFEST.MF
?
É o caso da biblioteca jsoup, que serve pra manipular HTML em Java à la jQuery.
O nome do módulo automático do jsoup
é simplesmente jsoup
. Por isso, no nosso módulo, devemos fazer:
module br.com.alexandreaquiles.projeto { requires java.sql; requires org.commonmark; requires jsoup; }
Agora, e esse nome de módulo, da onde vem?
Vem do nome do próprio JAR! No caso do jsoup
, é jsoup-1.11.2.jar
.
Perceba que o número de versão do JAR foi extirpado. A regra completa está na documentação do método ModuleFinder.of().
É difícil de adivinhar. Porém, o comando jar
agora tem a opção --describe-module
, que deve ser usada em conjunto com --file
:
jar --file jsoup-1.11.2.jar --describe-module
O nome do módulo automático será exibido antes do @
:
No module descriptor found. Derived automatic module. jsoup@1.11.2 automatic requires java.base mandated contains org.jsoup contains org.jsoup.helper contains org.jsoup.internal contains org.jsoup.nodes contains org.jsoup.parser contains org.jsoup.safety contains org.jsoup.select
Os contains
mostram os pacotes exportados.
Podemos executar também para o commonmark
:
jar --file commonmark-0.11.0.jar --describe-module
Perceba que o Automatic-Module-Name
é respeitado:
No module descriptor found. Derived automatic module. org.commonmark@0.11.0 automatic requires java.base mandated contains org.commonmark contains org.commonmark.internal contains org.commonmark.internal.inline contains org.commonmark.internal.renderer contains org.commonmark.internal.renderer.text contains org.commonmark.internal.util contains org.commonmark.node contains org.commonmark.parser contains org.commonmark.parser.block contains org.commonmark.parser.delimiter contains org.commonmark.renderer contains org.commonmark.renderer.html contains org.commonmark.renderer.text
Um bug no Eclipse
Num projetinho de teste, tentei usar a API do Hibernate com o Eclipse Oxygen.2 (4.7.2) e deu pau! Com o Maven e no IntelliJ funcionou bonitinho.
O hibernate-jpa-2.1-api-1.0.0.Final.jar
não tinha um Automatic-Module-Name
e a saída do jar --describe-module
era hibernate.jpa
. Porém, o Eclipse não reconhecia esse nome de módulo!
Abri um bug, que já foi corrigido. Era um erro na detecção de nomes de módulos do JDT.
A versão com a correção é a Eclipse 4.8 Milestone 5, ainda não lançada.
1 Comentário