DEV Community

Cover image for A Metamorfose da Plataforma Java: Uma Análise Exaustiva da Evolução Arquitetural, Funcional e Operacional do JDK 8 ao JDK 11
Kauê Matos
Kauê Matos

Posted on

A Metamorfose da Plataforma Java: Uma Análise Exaustiva da Evolução Arquitetural, Funcional e Operacional do JDK 8 ao JDK 11

Introdução: O Contexto da Mudança de Paradigma

A história do desenvolvimento de software corporativo está intrinsecamente ligada à evolução da linguagem Java. Por mais de duas décadas, o Java manteve uma posição de hegemonia, sustentada por sua promessa de "Write Once, Run Anywhere" e por um ecossistema robusto de bibliotecas e frameworks. No entanto, o período compreendido entre 2014 e 2018 representou o momento mais crítico e transformador da plataforma. A transição do Java 8 para o Java 11 não foi apenas uma atualização sequencial de versão; tratou-se de uma refundação arquitetural completa da Java Virtual Machine (JVM) e das bibliotecas de classe fundamentais.

O Java 8, lançado em março de 2014, é amplamente considerado o ápice da "Era Clássica" do Java. Ele introduziu a programação funcional através de expressões Lambda e da API de Streams, modernizando a sintaxe e permitindo que o Java competisse com linguagens mais expressivas. Contudo, sob o capô, o Java 8 ainda carregava o peso de vinte anos de decisões arquiteturais legadas: um tempo de execução monolítico, um classpath propenso a erros (o famigerado "JAR Hell") e uma gestão de memória que lutava para escalar em ambientes de contêineres modernos.1

Este relatório técnico oferece uma dissecção detalhada da jornada do Java 8 ao Java 11. Analisaremos não apenas as funcionalidades de superfície visíveis aos desenvolvedores, mas as mudanças tectônicas na infraestrutura do JDK 9 (Modularidade), as otimizações de ergonomia e performance do JDK 10 (Inferência de Tipos e G1GC) e a consolidação e estandardização do JDK 11 (LTS). O objetivo é fornecer uma compreensão profunda das motivações, implementações e impactos dessas mudanças, equipando arquitetos e engenheiros com o conhecimento necessário para navegar no ecossistema Java moderno.

Capítulo 1: O Legado e as Limitações do Java 8

Para compreender a magnitude das inovações introduzidas nas versões 9, 10 e 11, é imperativo estabelecer uma linha de base clara sobre o estado da arte no Java 8. Esta versão, embora revolucionária em termos de sintaxe, expôs as fissuras estruturais da plataforma quando confrontada com as novas realidades da computação em nuvem e microsserviços.

1.1 A Arquitetura Monolítica do JDK 8

No Java 8, o Java Runtime Environment (JRE) era distribuído como um grande bloco monolítico. O arquivo rt.jar (Runtime JAR) continha todas as classes da biblioteca padrão, totalizando mais de 60 megabytes de código compilado que precisava ser carregado ou indexado pela JVM, independentemente de a aplicação utilizar ou não essas classes.

  • Impacto no Desempenho: Para uma aplicação simples "Hello World" ou um microsserviço enxuto, a JVM ainda precisava carregar a bagagem de bibliotecas legadas como CORBA, Swing e AWT, resultando em tempos de inicialização lentos e um footprint de memória excessivo.
  • O Problema do Classpath: O mecanismo de carregamento de classes no Java 8 era linear e plano. O classpath era simplesmente uma lista de JARs. Se duas bibliotecas diferentes dependessem de versões diferentes de uma terceira biblioteca (ex: Logging), o Java carregaria a primeira que encontrasse, levando a comportamentos imprevisíveis e erros em tempo de execução (NoSuchMethodError, ClassNotFoundException).3

1.2 O Modelo de Memória e Coleta de Lixo

Embora o Java 8 tenha removido a PermGen (Permanent Generation) em favor do Metaspace (memória nativa), a gestão de heap ainda apresentava desafios.

  • Padrão de GC: O coletor padrão no Java 8 era o Parallel GC, focado em throughput (vazão), mas propenso a longas pausas de "Stop-the-World" em heaps grandes.
  • G1GC Imaturo: O Garbage-First Garbage Collector (G1GC) estava disponível e suportado, mas não era o padrão e sofria de limitações severas em situações de falha de evacuação, onde recorria a um Full GC single-threaded, paralisando a aplicação por segundos ou até minutos em casos extremos.1

1.3 A Estagnação das APIs de Rede e Concorrência

A API HttpURLConnection, datada das primeiras versões do Java, era a única opção nativa para comunicação HTTP. Era uma API bloqueante, difícil de usar, sem suporte a HTTP/2 (que estava emergindo) e verbosa. Desenvolvedores eram forçados a usar bibliotecas de terceiros como Apache HttpClient ou OkHttp, aumentando a complexidade das dependências.5

Capítulo 2: Java 9 — A Revolução Modular (Project Jigsaw)

O lançamento do Java 9 em setembro de 2017 foi, sem hipérbole, a maior mudança na estrutura do Java desde a versão 1.0. O foco central não foi a produtividade do desenvolvedor em termos de sintaxe, mas sim a reengenharia da plataforma através do Java Platform Module System (JPMS), desenvolvido sob o codinome Project Jigsaw.

2.1 Desconstruindo o Monolito: O Sistema de Módulos

O JPMS resolveu o problema do monolito dividindo o JDK em módulos discretos e interconectados. O rt.jar foi eliminado. Em seu lugar, o JDK foi particionado em cerca de 90 módulos, como java.base (o módulo fundamental), java.sql, java.logging, etc..1

2.1.1 Encapsulamento Forte e Configuração Confiável

O sistema de módulos introduziu dois conceitos fundamentais que alteraram a física do desenvolvimento Java:

  1. Configuração Confiável: No Java 9, as dependências devem ser declaradas explicitamente. Se um módulo requer outro módulo que não está presente na inicialização, a JVM se recusa a iniciar. Isso elimina a incerteza do classpath, garantindo que se a aplicação subir, todas as suas dependências estão satisfeitas.8
  2. Encapsulamento Forte: Antes do Java 9, o modificador public significava "público para todos". No Java 9, public significa "público apenas para quem o meu módulo permite". Um módulo deve exportar explicitamente seus pacotes para que sejam visíveis. Isso permitiu que os mantenedores do JDK ocultassem APIs internas perigosas (como sun.misc.Unsafe) que não deveriam ser usadas por desenvolvedores de aplicações, melhorando a segurança e a manutenibilidade a longo prazo.9

2.1.2 O Descritor de Módulo: module-info.java

A peça central de um módulo é o arquivo module-info.java, que reside na raiz do código fonte. Este arquivo usa novas palavras-chave reservadas para definir o contrato do módulo. A análise das diretivas revela a profundidade do controle que o JPMS oferece:

Diretiva Descrição e Impacto Arquitetural
requires Declara uma dependência estrita. O módulo atual não compilará ou rodará sem o módulo alvo.
requires transitive Estabelece "leitura implícita". Se o Módulo A requer transitivamente o Módulo B, e o Módulo C requer A, então C tem acesso a B automaticamente. Isso é crucial para bibliotecas agregadoras.11
exports Define quais pacotes do módulo contêm tipos públicos acessíveis a outros módulos. Pacotes não exportados são fortemente encapsulados.
exports... to Exportação qualificada. Permite exportar um pacote apenas para módulos específicos (ex: uma API interna compartilhada apenas entre módulos do mesmo framework), refinando a superfície de ataque.13
opens Permite acesso via reflexão (reflection) aos tipos do pacote, inclusive membros privados. Essencial para frameworks como Spring e Hibernate que usam injeção de dependência profunda.12
uses / provides Mecanismo de serviços. Permite o desacoplamento completo entre a interface de um serviço e sua implementação, formalizando o ServiceLoader dentro do sistema de módulos.12

2.2 JShell: Democratizando a Experimentação (REPL)

O Java 9 introduziu o JShell, uma ferramenta de Read-Eval-Print Loop. Historicamente, o Java exigia muita cerimônia (criar classe, método main, compilar) para testar a menor das lógicas. O JShell permite a execução interativa de trechos de código Java.

  • Utilidade Prática: Arquitetos podem usar o JShell para prototipar APIs complexas de Streams ou Data/Hora instantaneamente. Educadores podem ensinar conceitos sem o overhead da estrutura de classes.
  • Recursos: Suporta autocompletar, definição de métodos e classes temporárias, e persistência de sessões.7

2.3 Melhorias nas Coleções e Streams

O Java 9 modernizou a criação de coleções com a introdução de Factory Methods estáticos nas interfaces List, Set e Map.

  • Imutabilidade: Métodos como List.of("a", "b") ou Map.of("k1", "v1") criam instâncias imutáveis. Diferente do antigo Collections.unmodifiableList, que era apenas uma "view" (vista) sobre uma lista mutável, as coleções do Java 9 são estruturalmente imutáveis e otimizadas para consumo de memória.
  • Segurança de Nulos: Tentativas de adicionar null a essas coleções resultam em NullPointerException, reforçando boas práticas de programação defensiva.16

2.4 Compact Strings: Otimização Silenciosa

Uma das melhorias de desempenho mais significativas e transparentes do Java 9 foi a implementação de Compact Strings. A JVM analisou dumps de memória massivos e concluiu que a vasta maioria das Strings em aplicações Java continha apenas caracteres Latin-1 (1 byte), mas eram armazenadas como arrays de char (UTF-16, 2 bytes), desperdiçando 50% de espaço.

  • A Mudança: A classe String mudou internamente de char para byte mais um byte de codificação (coder). Se a String for puramente Latin-1, ela ocupa 1 byte por caractere. Se contiver caracteres multibyte, ela infla para UTF-16. Isso resultou em reduções de footprint de heap da ordem de 10-15% em grandes aplicações corporativas sem nenhuma alteração de código.19

2.5 A API de Flow (Reactive Streams)

O Java 9 incluiu a classe java.util.concurrent.Flow, que fornece as interfaces padrão para o manifesto Reactive Streams (Publisher, Subscriber, Subscription, Processor). Embora o JDK não forneça uma implementação completa robusta (como Project Reactor ou RxJava), a inclusão das interfaces no núcleo da linguagem permitiu a interoperabilidade entre diferentes bibliotecas reativas, servindo como uma "lingua franca" para o assincronismo.

Capítulo 3: Java 10 — Refinamento, Inferência e Performance

Lançado apenas seis meses após o Java 9, em março de 2018, o Java 10 foi a primeira prova do novo modelo de lançamentos rápidos da Oracle. Embora o ciclo fosse curto, as funcionalidades entregues foram de alto impacto, focando na ergonomia do desenvolvedor e na latência do GC.

3.1 A Chegada da Inferência de Tipos: var (JEP 286)

O recurso mais visível do Java 10 foi a introdução da palavra-chave var, permitindo a inferência de tipos para variáveis locais. Isso alinhou o Java com linguagens como C#, Scala e Kotlin, reduzindo a verbosidade sem sacrificar a segurança da tipagem estática forte.

  • Mecanismo: O compilador analisa o lado direito da atribuição (o inicializador) para determinar o tipo da variável no momento da compilação. O bytecode gerado é idêntico ao da declaração explícita.
    • Exemplo: var map = new HashMap<String, List<Integer>>(); substitui a repetição tediosa do tipo.
  • Limitações Críticas:
    • Não pode ser usado para campos de classe (atributos), parâmetros de métodos ou tipos de retorno. Isso preserva o contrato da API pública das classes explícito.
    • Não pode ser inicializado com null (pois não há tipo para inferir).
    • Não funciona com "Poly Expressions" (como lambdas sem contexto de destino claro).20
  • Impacto na Legibilidade: O uso criterioso de var melhora a legibilidade ao remover o "ruído" de tipos genéricos longos, permitindo que o leitor foque no nome da variável, que carrega o significado semântico do dado.23

3.2 Otimização Paralela do G1GC (JEP 307)

O G1GC, projetado para ser um coletor de baixa latência, tinha um "calcanhar de Aquiles" nas versões 8 e 9: o Full GC. Se a aplicação alocasse memória mais rápido do que o G1 conseguisse limpar (Concurrent Mode Failure), o G1 recorria a uma coleta completa de emergência. No Java 8 e 9, essa coleta era single-threaded.

  • O Cenário de Desastre: Em um servidor com 64 núcleos e 128GB de RAM, um Full GC usava apenas 1 núcleo, deixando 63 ociosos enquanto a aplicação ficava paralisada por minutos.
  • A Solução do Java 10: O Parallel Full GC paralelizou esse processo. O G1 agora utiliza o mesmo número de threads de trabalho paralelas para o Full GC que usa para as coletas jovens. Isso transformou pausas de minutos em segundos, tornando o G1GC viável para cargas de trabalho críticas e de alta alocação, consolidando sua posição como o coletor padrão da plataforma.4

3.3 Application Class-Data Sharing (AppCDS)

O Java 10 expandiu o recurso de compartilhamento de dados de classe (CDS). Antes restrito ao bootloader, o AppCDS permite que classes de aplicação sejam arquivadas em um arquivo mapeado em memória compartilhado entre múltiplas JVMs.

  • Benefício para Microserviços: Em um ambiente de nuvem onde múltiplos contêineres rodam a mesma aplicação Java no mesmo host físico, o AppCDS permite que a estrutura de classes seja carregada uma única vez na memória e compartilhada, reduzindo drasticamente o tempo de inicialização (Cold Start) e o consumo de memória RAM.25

3.4 Melhorias na Integração com Contêineres

O Java 10 aprimorou a capacidade da JVM de reconhecer que está rodando dentro de um contêiner Docker (cgroups). Antes disso, a JVM consultava o SO para saber a memória disponível e via a memória total do host, não o limite do contêiner, causando OutOfMemoryError frequentes. O Java 10 introduziu flags e comportamentos automáticos para respeitar os limites de CPU e memória do contêiner, calculando o tamanho da Heap de forma proporcional ao limite imposto pelo Docker.26

Capítulo 4: Java 11 — A Consolidação LTS e a Modernização da API

O Java 11, lançado em setembro de 2018, marcou o destino final da migração para a maioria das empresas. Como uma versão de Long Term Support (LTS), ele acumulou as inovações disruptivas do 9 e 10 e adicionou recursos finais de polimento, segurança e estandardização.

4.1 O Novo Cliente HTTP (JEP 321)

A API java.net.http.HttpClient, incubada no Java 9, foi promovida a padrão no Java 11, substituindo a obsoleta HttpURLConnection.

  • Assincronismo e Reatividade: O novo cliente é totalmente assíncrono e não bloqueante. Ele utiliza CompletableFuture e a API de Flow (Reactive Streams) para processar requisições e respostas.
  • HTTP/2 e WebSocket: Suporte nativo a multiplexação HTTP/2 (várias requisições na mesma conexão TCP) e comunicação bidirecional via WebSocket.
  • Código Fluente: A API utiliza o padrão Builder, tornando a construção de requisições legível e concisa. Isso eliminou a necessidade de dependências pesadas como Apache HttpClient para a maioria dos casos de uso.5

4.2 Execução de Código Fonte Direta (JEP 330)

O Java 11 simplificou a execução de programas simples. Agora é possível rodar java HelloWorld.java diretamente no terminal, sem a etapa intermediária de compilação (javac).

  • Scripting com Java: O recurso suporta arquivos "Shebang" (#!/usr/bin/java --source 11), permitindo que arquivos Java sejam executados como scripts de sistema em ambientes Unix. Isso posicionou o Java como uma alternativa viável para scripts de automação e tarefas DevOps, reduzindo a barreira de entrada para a linguagem.28

4.3 var em Parâmetros Lambda (JEP 323)

O Java 11 estendeu o uso de var para parâmetros de expressões lambda.

  • Motivação: Em Java 8, lambdas podiam ser implícitas (x, y) -> x + y ou explícitas (int x, int y) -> x + y. No entanto, não era possível adicionar anotações a parâmetros implícitos. O Java 11 permite (@Nonnull var x, @Nullable var y) ->.... Isso mantém a inferência de tipo enquanto permite a aplicação de metadados para frameworks de validação ou análise estática.31

4.4 Enriquecimento da API de Strings

A classe String, a mais usada na linguagem, recebeu métodos utilitários cruciais no Java 11, reduzindo a dependência de bibliotecas externas como Commons Lang ou Guava.

  • isBlank(): Verifica se a string está vazia ou contém apenas espaços em branco (resolve a eterna verificação trim().isEmpty()).
  • lines(): Retorna uma Stream de linhas, facilitando o processamento de texto multilinha sem complexidade de RegEx.
  • strip(), stripLeading(), stripTrailing(): Evolução do trim(). O trim antigo removia apenas caracteres ASCII <= 32. O strip é compatível com Unicode, removendo todos os caracteres de espaço em branco definidos pelo padrão Unicode, essencial para aplicações globalizadas.
  • repeat(int): Repete a string N vezes.19

4.5 Epsilon GC e ZGC: O Futuro da Gestão de Memória

O Java 11 introduziu dois coletores de lixo experimentais que apontam para o futuro da plataforma:

  1. Epsilon GC (JEP 318): Um coletor "No-Op". Ele aloca memória, mas nunca a recupera. É destinado a testes de performance (para isolar o custo do GC), aplicações de curtíssima duração (serverless) onde a aplicação termina antes de esgotar a memória, ou aplicações que fazem gestão de memória "off-heap" manual.
  2. ZGC (JEP 333): Um coletor escalável de baixíssima latência. Projetado para heaps de multi-terabytes, o ZGC promete pausas de GC não excedendo 10ms, independentemente do tamanho do heap. Ele realiza a compactação e realocação de memória concorrentemente, sem parar as threads da aplicação, usando barreiras de leitura coloridas (colored pointers).35

4.6 Nest-Based Access Control (JEP 181)

Uma mudança profunda no nível da JVM. O Java sempre permitiu que classes internas (nested classes) acessassem membros privados da classe externa. No entanto, no bytecode, classes internas são arquivos separados. Para permitir esse acesso, o compilador criava "métodos ponte" (bridge methods) sintéticos com acesso de pacote, o que era uma brecha de segurança e complexidade. O Java 11 introduziu o conceito de "Ninhos" (Nests) na JVM, permitindo que classes aninhadas acessem membros privados umas das outras nativamente, sem truques de compilador, melhorando a segurança e a performance da reflexão.31

4.7 Segurança: TLS 1.3

O Java 11 implementou o protocolo TLS 1.3 (RFC 8446). Esta versão removeu algoritmos criptográficos fracos (como SHA-1 e RC4) e reduziu o handshake necessário para estabelecer conexões seguras, diminuindo a latência de conexões HTTPS e aumentando a segurança padrão da plataforma.26

Capítulo 5: As Grandes Remoções e o Fim do Legado

A evolução do Java 8 para o 11 não foi apenas aditiva. Para garantir a longevidade da plataforma, a Oracle tomou decisões difíceis de remover componentes que eram considerados "dívida técnica".

5.1 A Exclusão dos Módulos Java EE e CORBA (JEP 320)

No Java 11, os módulos relacionados ao Java EE (Enterprise Edition) que estavam empacotados no Java SE desde o Java 6 foram removidos. Isso inclui:

  • java.xml.ws (JAX-WS, SOAP)
  • java.xml.bind (JAXB, processamento de XML)
  • java.activation (JAF)
  • java.corba (Common Object Request Broker Architecture)

Motivação: Essas tecnologias evoluíam em ritmos diferentes do Java SE. Mantê-las no JDK inflava o tamanho da distribuição e dificultava a evolução.

Impacto na Migração: Aplicações que usam JAXB (comum para processamento XML/JSON legado) ou SOAP quebraram imediatamente ao compilar no Java 11. A solução exige a adição explícita dessas bibliotecas via Maven/Gradle, geralmente migrando para as versões da Jakarta EE (jakarta.xml.bind), o que introduz mudanças de namespace de pacote (javax.* para jakarta.* em versões mais recentes das libs).37

5.2 O Desacoplamento do JavaFX

O JavaFX foi removido do JDK e se tornou um módulo separado, o OpenJFX. Isso permitiu que a tecnologia de UI evoluísse independentemente. Aplicações Desktop Java agora devem incluir os módulos JavaFX e as bibliotecas nativas correspondentes em seu build path.37

5.3 O Fim do Java Web Start e Applets

O Java 11 removeu completamente o suporte a Applets e a tecnologia Java Web Start (JNLP). Isso marcou o fim oficial da execução de Java dentro de navegadores web (plugin), uma tecnologia que já havia sido depreciada pelos navegadores modernos devido a falhas de segurança recorrentes.37

Capítulo 6: Guia de Migração e Desafios Práticos

Migrar do Java 8 para o Java 11 é considerado o salto mais desafiador na história do Java. Não é apenas uma recompilação; é uma adaptação a um novo paradigma modular.

6.1 Ferramentas de Análise

O JDK 11 fornece ferramentas essenciais para planejar a migração:

  • jdeps: Analisador de dependências de classe. Ele varre os JARs da aplicação e identifica o uso de APIs internas do JDK (sun.*) que agora são inacessíveis devido ao encapsulamento do Java 9.
  • jdeprscan: Verifica o uso de APIs depreciadas ou removidas em binários compilados.38

6.2 O Desafio das Bibliotecas Internas (sun.misc.Unsafe)

Muitas bibliotecas populares (Spring, Hibernate, Mockito, Netty) usavam APIs internas do JDK para performance ou hacks de reflexão. O Java 9+ bloqueou esse acesso.

  • Solução: Atualizar todas as dependências de terceiros é o primeiro passo obrigatório. As versões modernas dessas bibliotecas já foram refatoradas para usar APIs públicas (como VarHandle no lugar de Unsafe).
  • Contorno: Para código legado que não pode ser atualizado, o Java 11 permite bandeiras de JVM como --add-opens para "abrir" forçadamente módulos encapsulados para reflexão em tempo de execução, embora isso seja uma solução paliativa.12

6.3 O Problema do "Split Package"

O sistema de módulos proíbe que dois módulos diferentes exportem o mesmo pacote. Isso era comum no Java 8, onde bibliotecas diferentes poderiam conter classes no mesmo pacote (ex: org.apache.utils). No Java 11, isso causa erro de compilação ou runtime. A resolução envolve renomear pacotes ou usar a diretiva --patch-module.8

6.4 Fontes e Renderização

O Java 11 removeu o motor de renderização de fontes proprietário "T2K" e o substituiu pelo "Freetype" (open source) no OpenJDK. Isso pode causar diferenças sutis na renderização de texto em aplicações Swing/AWT, exigindo testes visuais de regressão.44

Capítulo 7: Desempenho e Licenciamento

7.1 Ganhos de Performance

Migrar para o Java 11 geralmente traz ganhos de performance imediatos sem alteração de código, devido a:

  • G1GC Maduro: Melhorias na previsão de pausas e paralelismo.
  • Compact Strings: Redução de consumo de memória.
  • Segmented Code Cache: O JIT compiler organiza melhor o código nativo em memória, melhorando a performance de execução e a eficiência do cache da CPU.45

7.2 O Novo Cenário de Licenciamento

Com o Java 11, a Oracle mudou a licença do "Oracle JDK" para um modelo comercial pago para produção (na época do lançamento, embora regras mais relaxadas tenham surgido com o Java 17+). Isso impulsionou a adoção massiva de distribuições OpenJDK (como Eclipse Temurin, Amazon Corretto, Azul Zulu, Red Hat Build), que são gratuitas, open-source e, a partir do Java 11, tecnicamente idênticas ao Oracle JDK (feature parity), já que a Oracle abriu o código de recursos comerciais como o Java Flight Recorder e Mission Control.47

Tabelas de Referência e Comparativos

Tabela 1: Resumo Comparativo de Funcionalidades (JDK 8 vs JDK 11)

Funcionalidade Java 8 Java 11 Benefício da Migração
Modelo de Módulos Inexistente (Classpath plano) JPMS (Modules, module-info) Segurança, encapsulamento, menor footprint.
Sintaxe Tipagem explícita obrigatória Inferência var (Local e Lambda) Código mais limpo e menos verboso.
Cliente HTTP HttpURLConnection (Legado) HttpClient (Moderno, Async) Suporte a HTTP/2, WebSocket, API fluente.
Garbage Collector Parallel GC (Padrão) G1GC (Padrão e Otimizado) Menor latência, pausas previsíveis.
Strings char (UTF-16) byte (Compact Strings) Economia de memória de até 50% em Strings.
Collections Collections.unmodifiableList List.of, Map.of (Imutáveis) Imutabilidade real, criação concisa.
Docker/Container Suporte limitado (Backported) Suporte Nativo Total Respeito a limites de CPU/RAM, estabilidade.
Java EE / CORBA Incluído no JDK REMOVIDO JDK mais leve; atualização independente de libs.

Tabela 2: Principais APIs Removidas e Substitutos

Módulo Removido Uso Típico Substituto Recomendado (Dependência Maven/Gradle)
java.xml.bind Anotações JAXB (@XmlRootElement) jakarta.xml.bind:jakarta.xml.bind-api e Runtime (ex: Glassfish)
java.xml.ws SOAP Web Services (JAX-WS) jakarta.xml.ws:jakarta.xml.ws-api e implementação (ex: Metro)
java.activation MIME Type handling jakarta.activation:jakarta.activation-api
java.corba Comunicação CORBA Legada Implementações Glassfish CORBA (Raro uso moderno)
javafx.* Aplicações GUI Desktop Bibliotecas OpenJFX (org.openjfx:javafx-controls)

Esta evolução representa a maturação do Java. Ao abandonar o peso do legado e abraçar a modularidade e a modernização da infraestrutura, o Java 11 se posicionou não apenas como uma linguagem sobrevivente, mas como uma plataforma vibrante e preparada para as décadas futuras de desenvolvimento em nuvem.

Top comments (0)