Guia detalhado sobre Java Modules
Tags: java
Published: 2024-07-06 00:58:36

Com a chegada do Java 9, a plataforma Java ganhou um novo sistema de módulos, que foi uma das maiores mudanças desde a introdução das Generics no Java 5. O sistema de módulos, também conhecido como **_Projeto Jigsaw_**, permite dividir a aplicação em módulos distintos com dependências explícitas. Isso melhora a organização, segurança e manutenibilidade do código.

## Introdução aos módulos
Um módulo em Java é uma unidade de agregação de pacotes. Ele encapsula pacotes e recursos e especifica quais deles são acessíveis a outros módulos e quais não são. O sistema de módulos tem como objetivo principal oferecer maior controle sobre a visibilidade de classes e pacotes e ajudar a construir aplicações mais robustas e seguras.

## Definindo um módulo
Para definir um módulo, você precisa criar um arquivo **module-info.java** na raiz do diretório do módulo. Esse arquivo contém as declarações que definem o nome do módulo e as suas dependências.

Exemplo de um **module-info.java** básico:
```
module com.example.myapp {
    requires java.sql;
    exports com.example.myapp.api;
}
```

Neste exemplo:

- **'module com.example.myapp'** define o nome do módulo
- **'requires java.sql'** declara que este módulo depende do módulo **'java.sql'**.
- **exports com.example.myapp.api** permite que outros módulos acessem os pacotes dentro módulo **'com.example.myapp.api'**

### Estrutura do projeto com módulo
Suponha que temos dois módulos **'com.example.myapp'** e **'com.example.util'**.

A estrutura do projeto seria algo assim:
```
my-modular-project/
├── com.example.myapp/
│   ├── module-info.java
│   └── com/example/myapp/
│       ├── Main.java
│       └── api/
│           └── MyService.java
└── com.example.util/
    ├── module-info.java
    └── com/example/util/
        └── Utility.java

```
### Exemplo de implementação
Vamos implementar um exemplo simples onde um módulo com.example.myapp utiliza um serviço fornecido pelo módulo com.example.util.

**com.example.util/module-info.java**
```
module com.example.util {
    exports com.example.util;
}
```
**com.example.util/com/example/util/Utility.java**
```
package com.example.util;
public class Utility {
    public static String getGreeting() {
        return "Hello from Utility!";
    }
}
```
**com.example.myapp/module-info.java**
```
module com.example.myapp {
    requires com.example.util;
}
```
**com.example.myapp/com/example/myapp/Main.java**
```
package com.example.myapp;

import com.example.util.Utility;

public class Main {
    public static void main(String[] args) {
        System.out.println(Utility.getGreeting());
    }
}
```
### Compilação e execução dos módulos
Para compilar e executar módulos, você pode usar o comando **'javac'** e **'java'** com a opção **'--module-path'** para especificar onde os módulos estão localizados.
**Compilação**
```
javac -d out --module-source-path src $(find src -name "*.java")
```
**Execução**
```
java --module-path out -m com.example.myapp/com.example.myapp.Main
```
### Recursos adicionais
#### Diretrizes de acesso
Você pode usar a diretiva 'opens' para permitir acesso reflexivo a pacotes, por exemplo, para bibliotecas e frameworks como Spring e Hibernate:
```
module com.example.myapp {
    requires com.example.util;
    opens com.example.myapp.internal to some.framework;
}
```
#### Serviços e provedores
Java Modules também suportam um mecanismo de serviços para facilitar a implementação de padrões de design como Inversão de Controle (IoC).

**Definição de serviço:**
```
module com.example.util {
    exports com.example.util;
    provides com.example.util.MyService with com.example.util.MyServiceImpl;
}
```

**Uso do serviço:**
```
module com.example.myapp {
    requires com.example.util;
    uses com.example.util.MyService;
}
```
No código do cliente, você pode obter um instância do serviço usando o **'ServiceLoader'**:
```
ServiceLoader<MyService> serviceLoader = ServiceLoader.load(MyService.class);
MyService service = serviceLoader.findFirst().orElseThrow();
```
## Conclusão
O sistema de módulos em Java oferece uma maneira poderosa e flexível de organizar o código, controlar dependências e melhorar a segurança das aplicações. Ele é especialmente útil para grandes projetos que podem se beneficiar de uma estrutura modularizada. Ao entender e aplicar os conceitos de módulos, você pode construir aplicações Java mais robustas e manuteníveis.