CodeGym /Cursos /JAVA 25 SELF /Build de projetos multimódulo: Maven, Gradle, IDEA

Build de projetos multimódulo: Maven, Gradle, IDEA

JAVA 25 SELF
Nível 60 , Lição 4
Disponível

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.

1
Pesquisa/teste
Módulos e estrutura do projeto, nível 60, lição 4
Indisponível
Módulos e estrutura do projeto
Módulos e estrutura do projeto
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION