Compact Profiles no Java 8

Em 2009, o engenheiro chefe da plataforma Java na Oracle, Mark Reinhold, falou no evento JavaOne a famosa frase The classpath is dead.”. Desde a época muito se escreveu sobre o projeto JigSaw que visa modularizar a plataforma Java, mas a implementação final só sairá para o Java 9, caso o trem não se atrase novamente.

O objetivo principal do Jigsaw é trazer a modularização para a plataforma Java, mas há outras motivações: diminuir o tamanho de download (footprint) e melhorar o desempenho principalmente na inicialização (bootstrap).

Apesar do lançamento do projeto JigSaw ter sido procrastinado do Java 7 para o Java 9, foi criada uma solução intermediária para a versão 8 do Java. No Java 8 já foram definidos os perfis da plataforma, também chamados de Compact Profiles.

São três profiles (1, 2 e 3) que são compostos de vários pacotes. Compact 1 é o menor e possui apenas os pacotes mais importantes como java.lang e java.util, Compact 2 se baseia no 1 e adiciona outros pacotes como java.sql. O último, Compact 3, possui pacotes mais específicos como javax.naming.
compact-profiles

O JavaDoc possui a lista completa dos pacotes e, na descrição de cada classe, foi adicionada uma declaração que documenta os perfis compatíveis.

Os Compact Profiles tornam o Java ainda mais interessante para sistemas embarcados, pois é possível gerar uma JRE especificando um desses 3 profiles. Para tal existe a ferramenta jrecreate que vem com o download do JavaSE Embedded. Por exemplo, ao gerar uma JRE no perfil Compact 1, um arquivo em torno de 11MB é gerado, possível usar em um RaspberryPI:

jrecreate.sh --profile compact1 --dest /tmp/smallJRE/

Para a aplicação realmente funcionar em um determinado perfil, o compilador Java ganhou um novo flag: -profile. Esse flag determina o perfil (compact1, compact2 ou compact3) e o javac gera um erro caso uma classe incompatível esteja sendo utilizada.

Por exemplo, para compilar a classe abaixo é preciso usar pelo menos o Compact 2, pois o pacote java.sql não faz parte do Compact 1:

import java.sql.*;

class Teste {

	public static void main(String... args) throws SQLException {
		Connection c = DriverManager.getConnection("teste");
		System.out.println("oi");
	}
}

javac -profile compact2 Teste.java //compact1 geraria um erro

Para saber se a classe faz parte de um profile ou não, foi criada uma outra ferramenta: jdeps (java dependency analyzer). Ela vem instalada com o JDK 8 e analisa os pacotes dependentes. Para a classe acima, a jdeps mostra a saída seguinte:

jdeps -verbose:class -P Teste.class

Teste.class -> /../jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar (compact2)
Teste (Teste.class)
-> java.io.PrintStream compact1
-> java.lang.Object compact1
-> java.lang.String compact1
-> java.lang.System compact1
-> java.sql.Connection compact2
-> java.sql.DriverManager compact2
-> java.sql.SQLException compact2

Repare que a jdeps informa que a classe Teste depende do JAR rt.jar e relata todos os pacotes utilizados. jdeps também serve para analisar as dependências de um JAR. Veja abaixo um exemplo usando o JAR principal do Hibernate:

jdeps -P hibernate-core-4.3.6.Final.jar

hibernate-core-4.3.6.Final.jar → /../jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar (Full JRE)
org.hibernate (hibernate-core-4.3.6.Final.jar)
-> java.io compact1
-> java.lang compact1
-> java.math compact1
-> java.sql compact2
-> java.util compact1
-> javax.naming compact3
-> javax.transaction not found
-> org.jboss.logging not found
org.hibernate.action.internal (hibernate-core-4.3.6.Final.jar)
-> java.io compact1
-> java.lang compact1
-> java.util compact1
-> java.util.concurrent.atomic compact1
… muito mais

No Java 9, com a entrada do JigSaw, somos obrigados a definir mais meta informações sobre os JARs/Modulos como versionamento e imports/exports, que serão verificadas no build da aplicação. Isso também significa que várias bibliotecas e frameworks vão quebrar, pois se basearam em pacotes internos da JRE que o sistema de módulos vai proibir.

Para quem procura uma solução de modularização para já, deve dar uma olhada no OSGI que é foco da minha palestra na próxima QCon no Rio de Janeiro. Espero te encontrar lá!

5 Comentários

  1. Ian 16/09/2014 at 10:18 #

    Muito bom o post. Não estava sabendo dessa. Parabéns e obrigado por compartilhar.

  2. Jorge Portela 16/09/2014 at 10:51 #

    Fantástico! Bem vindo ao mundo Java!

  3. Dilnei Cunha 22/09/2014 at 16:26 #

    Muito legal o post, obrigado.

  4. Silvio Luiz 19/11/2014 at 12:03 #

    Legal essa abordagem em módulos pra o Java 8 e 9. A pergunta que fica é: essa modularização poderá ser feita dinamicamente (assim como o OSGI faz)? Como vai ficar o OSGI e ferramentas como o maven? Seria interessante poder criar seus próprios profiles pra rodar uma aplicação num subset isolado e contendo apenas os módulos dos quais depende…

Deixe uma resposta