1. Build de projetos modulares: princípios básicos
Compilador e caminho de módulos (module-path)
Antes dos módulos, todo o aplicativo era compilado e executado usando o chamado classpath — apenas uma lista de diretórios e arquivos JAR onde o Java procurava as classes. No sistema modular surgiu um novo participante — module-path. Agora o compilador e a JVM precisam saber não apenas onde estão as classes, mas também a quais módulos pertencem, de quais dependem e quais pacotes são exportados.
Ponto-chave:
- Para projetos modulares, use --module-path em vez de -classpath.
- O compilador e a JVM precisam enxergar todos os módulos de que seu aplicativo precisa (e suas dependências).
Exemplo: compilação manual de módulos
Suponha que você tenha dois módulos: core e app, onde app depende de core.
Estrutura de diretórios:
project-root/
core/
src/
main/
java/
module-info.java
com/example/core/...
app/
src/
main/
java/
module-info.java
com/example/app/...
Compilação manual (demonstração):
# Primeiro, compile core
javac -d out/core core/src/main/java/module-info.java core/src/main/java/com/example/core/*.java
# Depois, compile app informando o module-path para core
javac --module-path out/core -d out/app app/src/main/java/module-info.java app/src/main/java/com/example/app/*.java
Execução:
java --module-path out/core:out/app -m app/com.example.app.Main
Em projetos reais não é necessário fazer isso manualmente — use Maven/Gradle ou a IDE.
2. Maven: build de projetos multimódulo
Estrutura de um projeto multimódulo no Maven
O Maven há muito tempo oferece suporte a uma estrutura com vários módulos (submodules). Agora, com o sistema modular do Java, esses “módulos” do Maven muitas vezes coincidem com os módulos do Java, mas nem sempre: um módulo do Maven é apenas um subprojeto, enquanto um módulo do Java é o que está descrito em module-info.java. Normalmente, um módulo do Maven = um módulo do Java.
Estrutura típica:
myproject/
pom.xml # Parent POM
core/
pom.xml # Módulo core
src/main/java/
module-info.java
com/example/core/...
app/
pom.xml # Módulo app
src/main/java/
module-info.java
com/example/app/...
Exemplo de POM pai (myproject/pom.xml):
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>core</module>
<module>app</module>
</modules>
</project>
Exemplo de POM para o módulo core (core/pom.xml):
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>core</artifactId>
<dependencies>
<!-- Aqui podem entrar dependências, por exemplo, para outros módulos ou bibliotecas de terceiros -->
</dependencies>
</project>
Exemplo de POM para o módulo app (app/pom.xml):
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>app</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Importante:
- Se em app for necessário core, no module-info.java do módulo app deve haver requires core;
- O Maven montará as dependências automaticamente, se <dependency> e <module> estiverem declarados corretamente.
Como o Maven trata o module-info.java
- O Maven compila automaticamente o module-info.java junto com as demais classes.
- Se você tiver dependências modulares, o Maven irá adicioná-las ao module-path na compilação e na execução.
- Se você usar plugins antigos ou Java abaixo da versão 9 — o sistema de módulos não funcionará.
Executar um aplicativo modular via Maven
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<release>21</release> <!-- ou a sua versão do Java -->
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<mainClass>com.example.app.Main</mainClass>
<commandlineArgs></commandlineArgs>
</configuration>
</plugin>
</plugins>
</build>
mvn clean install
mvn -pl app exec:java
Erros comuns ao trabalhar com Maven e módulos
Erro: “module not found”. Você não informou corretamente o module-path ou não declarou a <dependency> para o artefato necessário.
Duplicação de nomes de módulos. O projeto não deve ter dois módulos com o mesmo nome (por exemplo, dois module core).
Falta de export/requires. Se você esquecer de exportar um pacote (exports) ou de declarar a dependência (requires), ocorrerá um erro de compilação.
Mistura de classpath e module-path. Não use plugins/configurações legados que não suportam módulos: isso leva a erros imprevisíveis.
3. Gradle: build de projetos multimódulo
Estrutura do projeto no Gradle
myproject/
settings.gradle
build.gradle
core/
build.gradle
src/main/java/module-info.java
src/main/java/com/example/core/...
app/
build.gradle
src/main/java/module-info.java
src/main/java/com/example/app/...
settings.gradle
rootProject.name = 'myproject'
include 'core', 'app'
build.gradle (raiz)
subprojects {
apply plugin: 'java'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21) // ou a sua versão do Java
}
}
repositories {
mavenCentral()
}
}
build.gradle para core
plugins {
id 'java'
}
group = 'com.example'
version = '1.0-SNAPSHOT'
build.gradle para app
plugins {
id 'java'
id 'application'
}
group = 'com.example'
version = '1.0-SNAPSHOT'
dependencies {
implementation project(':core')
}
application {
mainModule = 'app' // Nome do seu módulo Java
mainClass = 'com.example.app.Main'
}
Build e execução
./gradlew build
./gradlew :app:run
O Gradle detecta automaticamente o module-path se encontrar module-info.java. Se algo não funcionar — verifique se você está usando uma versão recente do Gradle e dos plugins.
4. IntelliJ IDEA: criação e configuração de um projeto modular
Criação de um projeto modular
- File → New → Project → Java → marque “Create module-info.java”.
- Para um projeto multimódulo: File → New → Module — adicione novos módulos ao projeto.
- Se usar Maven/Gradle — basta importar o projeto via pom.xml ou build.gradle.
Estrutura na IDEA
- Na Project View, cada módulo é exibido como um ramo separado.
- Em cada módulo há o seu próprio module-info.java, seus fontes.
- A IDEA indica quais módulos exportam/exigem quais pacotes (exports/requires).
- Se você esquecer de exportar um pacote ou declarar uma dependência — a IDEA destacará o erro.
Verificação do module-path, execução da classe main
- Em Run/Debug Configurations, informe:
- Main class (por exemplo, com.example.app.Main)
- Module (por exemplo, app)
- A IDEA cuidará automaticamente do module-path.
- Se for executar via Maven/Gradle — use as configurações correspondentes (por exemplo, app [run]).
Importação de módulos e bibliotecas de terceiros
- Para trabalhar com bibliotecas externas (por exemplo, requires java.sql; ou JARs de terceiros) — adicione a dependência via Maven/Gradle.
- Se a biblioteca não for modular (não tem module-info.java), ela será adicionada automaticamente ao “unnamed module” (isso é normal para a maioria das bibliotecas).
5. Prática: criando um projeto multimódulo simples
Passo 1. Criar a estrutura do projeto
myproject/
core/
src/main/java/module-info.java
src/main/java/com/example/core/HelloService.java
app/
src/main/java/module-info.java
src/main/java/com/example/app/Main.java
HelloService.java (core):
package com.example.core;
public class HelloService {
public String getHello() {
return "Olá do módulo core!";
}
}
module-info.java (core):
module core {
exports com.example.core;
}
Main.java (app):
package com.example.app;
import com.example.core.HelloService;
public class Main {
public static void main(String[] args) {
HelloService service = new HelloService();
System.out.println(service.getHello());
}
}
module-info.java (app):
module app {
requires core;
}
Passo 2. Build e execução com Maven
Na raiz do projeto, crie o POM pai (pom.xml) e dois subprojetos (core/pom.xml, app/pom.xml) como acima. No app/pom.xml, adicione a dependência de core.
mvn clean install
mvn -pl app exec:java
Passo 3. Build e execução com Gradle
Crie o settings.gradle, o build.gradle da raiz e um para cada módulo. No app/build.gradle, declare a dependência de core e o mainClass.
./gradlew build
./gradlew :app:run
Passo 4. Importação e execução no IntelliJ IDEA
- Abra a raiz do projeto via File → Open.
- A IDEA reconhecerá a estrutura Maven/Gradle e criará os módulos.
- Em cada módulo você pode abrir module-info.java; a IDEA mostrará as relações entre os módulos.
- Execute Main.java pelo menu de contexto (“Run Main.main()”) — a IDEA definirá automaticamente o module-path.
6. Erros comuns ao construir projetos modulares
Erro nº 1: module-path incorreto. Se, na execução ou compilação, aparecer uma mensagem como “module not found” ou “package is not visible”, provavelmente você não informou corretamente o module-path ou esqueceu de adicionar a dependência no pom.xml/build.gradle.
Erro nº 2: duplicação de nomes de módulos. O projeto não deve ter dois módulos com o mesmo nome (por exemplo, dois module core). Isso leva a erro de compilação.
Erro nº 3: pacote não exportado. Se a classe estiver em um pacote que não é exportado via exports no module-info.java, ela ficará indisponível para outros módulos, mesmo sendo public. Surgirá um erro de compilação ao tentar usar essa classe.
Erro nº 4: requires não declarado. Se um módulo usa classes de outro módulo, mas não declarou requires no module-info.java, o compilador emitirá um erro.
Erro nº 5: incompatibilidade com bibliotecas externas. A falta de correspondência entre módulos e bibliotecas sem module-info.java (elas vão para o “unnamed module”) geralmente não atrapalha, mas em algumas configurações pode ser necessário ajuste adicional.
Erro nº 6: execução a partir do módulo errado. Na configuração de execução da IDEA ou do Maven/Gradle foi indicado o main class ou o módulo incorreto — o aplicativo não inicia. Verifique Main, mainModule/module e o profile usado.
GO TO FULL VERSION