BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Artigos Introdução ao Quarkus

Introdução ao Quarkus

Pontos Principais

  • O Quarkus é uma nova tecnologia voltada para o desenvolvimento na nuvem;

  • Com o Quarkus, podemos aproveitar as vantagens de tempos de execução menores e otimizados para nuvem;

  • Não é necessário aprender novas APIs. O Quarkus foi desenvolvido com base nas melhores tecnologias da última década, como Hibernate, RESTEasy, Vert.x e MicroProfile;

  • O Quarkus é produtivo desde sua implantação;

  • O Quarkus está pronto para produção.

O Quarkus criou várias discussões no ecossistema Java Enterprise em 2019. Como os outros desenvolvedores, eu estava curioso para conhecer essa nova tecnologia e vi um grande potencial nela. O que exatamente é o Quarkus? Em que difere das outras tecnologias já estabelecidas no mercado? Como o Quarkus pode nos ajudar e ajudar as empresas? Vamos descobrir.

O que é o Quarkus

O projeto Quarkus se autodenominou Supersonic Subatomic Java. Isso é de fato real? O que isto significa? Para explicar melhor a motivação por trás do projeto Quarkus precisamos examinar o estado atual do desenvolvimento de software.

Dos servidores internos para as núvens

A maneira antiga de implantar aplicações era usando hardwares. Com a compra de uma máquina, pagamos antecipadamente pelos requisitos de hardware. O investimento já estava feito, então não haveria diferença em usar todos os recursos da máquina ou apenas uma parte. Na maioria dos casos isso não era problema, contanto que as aplicações fossem executadas. No entanto, a nuvem está mudando a maneira como desenvolvemos e implantamos as aplicações.

Na nuvem, pagamos exatamente por aquilo que usamos. Portanto, nos tornamos mais exigentes com o uso do hardware. Se a aplicação demorar 10 segundos para iniciar, temos que pagar por esses 10 segundos, mesmo se ela ainda não estiver pronta para ser consumida pelos usuários.

Java e a nuvem

Você se lembra de quando a primeira versão do Java foi lançada? Permita-me refrescar sua memória, foi em 1996. Não havia armazenamento na nuvem naquela época. Na verdade, isto só passou a existir vários anos depois. O Java definitivamente não foi feito sob medida para este novo paradigma e por isso teve que se ajustar. Mas como poderíamos mudar um paradigma depois de tantos anos amarrados a uma máquina física onde os custos não importavam tanto quanto na nuvem?

O segredo está no tempo de execução

A forma como muitas bibliotecas e estruturas do Java evoluíram ao longo dos anos focou em realizar um conjunto de melhorias durante o tempo de execução. Essa foi uma forma conveniente de adicionar recursos ao código de maneira segura e declarativa. Precisa de injeção de dependência? Certo! Use notações. Precisa de uma transação? Sem problemas! Use uma notação. Na verdade, podemos programar muitas coisas usando essas notações que o tempo de execução irá resolver para nós. Mas há sempre um problema. O tempo de execução requer uma verificação do nosso classpath e das classes para os metadados. Esta é uma operação custosa que consome tempo e memória.

A mudança de paradigma do Quarkus

O Quarkus abordou este desafio movendo as operações de alto custo processual e de memória como o Bytecode Enhancement, Dynamic ClassLoading, Proxying, entre outros, para o tempo de compilação. O resultado é um ambiente que consome menos memória, menos CPU e possui uma inicialização mais rápida. Isso é perfeito para o uso na nuvem, mas também é útil para outros casos. Todos se beneficiarão com o menor consumo de recursos, independentemente do ambiente.

Talvez o Quarkus não uma grande novidade.

Já ouviu falar ou usou tecnologias como CDI, JAX-RS ou JPA? Se sim, o Quarkus stack é composto por essas tecnologias que já existem há vários anos. Se você sabe como desenvolver essas tecnologias, saberá como desenvolver uma aplicação com o Quarkus.

Reconhece o código abaixo?

@Path("books")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public class BookApi {
    @Inject
    BookRepository bookRepository;

    @GET
    @Path("/{id}")
    Response get(@PathParam("id")Long id) {
        return bookRepository.find(id)
                             .map(Response::ok)
                             .orElse(Response.status(NOT_FOUND))
                             .build();
    }
}

Parabéns, esté é a sua primeira aplicação Quarkus!

Os melhores frameworks e padrões

O modelo de programação Quarkus é construído com base em padrões comprovados, sejam eles oficiais ou aqueles comumente aceitos. No momento, o Quarkus dá suporte de primeira classe para tecnologias como Hibernate, CDI, Eclipse MicroProfile, Kafka, Camel, Vert.x, Spring, Flyway, Kubernetes, Vault, entre outras. Ao adotar o Quarkus, seremos mais produtivos desde o primeiro dia, pois não precisamos realmente aprender novas tecnologias, apenas usar aquilo que usamos a mais de 10 anos.

Está querendo usar uma biblioteca que ainda não faz parte do ecossistema Quarkus? Há uma boa chance de que ela funcione sem problemas, sem nenhuma configuração adicional, a menos que queira executá-la no modo GraalVM Native. Se quiser fazer algumas coisas mais avançadas, poderá implementar facilmente sua própria extensão Quarkus para fornecer suporte para uma tecnologia específica e enriquecer o ecossistema Quarkus.

Instalação do Quarkus

Então, talvez esteja se perguntando se tem algum esqueleto no armário, certo?. Na verdade, sim, existe. Devemos usar no projeto um conjunto específico de dependências que são fornecidas pelo Quarkus. Não se preocupe, o Quarkus é compatível com o Maven e o Gradle. Por conveniência, podemos gerar um projeto esqueleto com a página inicial do Quarkus e selecionar quais tecnologias gostaríamos de usar. Basta importá-las em nossa IDE favorita e estamos prontos para começar. Aqui está um projeto Maven de exemplo que usa o JAX-RS com RESTEasy e JPA com Hibernate:

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.acme</groupId>
  <artifactId>code-with-quarkus</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <properties>
    <compiler-plugin.version>3.8.1</compiler-plugin.version>
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <quarkus-plugin.version>1.3.0.Final</quarkus-plugin.version>
    <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
    <quarkus.platform.version>1.3.0.Final</quarkus.platform.version>
    <surefire-plugin.version>2.22.1</surefire-plugin.version>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>${quarkus.platform.artifact-id}</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-hibernate-orm</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-jsonb</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus-plugin.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemProperties>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
          </systemProperties>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Deve ter notado que a maioria das dependências começam com groupId io.quarkus e que não são as dependências normais que podemos encontrar para Hibernate, Resteasy ou Junit.

Dependencias do Quarkus

Surge então a dúvida: Por que o Quarkus fornece as próprias versões de wrapper para essas bibliotecas populares? O motivo é fornecer uma ponte entre a biblioteca e o Quarkus para resolver as dependências de tempo de execução no tempo de compilação. É aqui que a magia do Quarkus acontece e fornece projetos com tempos de início mais rápidos e com menos uso de memória.

Isso significa que somos obrigados a usar apenas as bibliotecas específicas do Quarkus? Absolutamente, não. Podemos usar qualquer biblioteca que desejarmos. É possível executar aplicações Quarkus na JVM normalmente, onde não há limitações.

GraalVM e Native Images

Talvez você já tenha ouvido falar desse projeto chamado GraalVM da Oracle Labs. Em essência, o GraalVM é uma máquina virtual universal feita para executar aplicações de várias linguagens. Um dos recursos mais interessantes é a capacidade de construir uma aplicação em uma imagem nativa e executá-la ainda mais rápido! Na prática, isso significa que temos um executável para rodar com todas as dependências necessárias da aplicação resolvidas em tempo de compilação. Isso não é executado na JVM, é um arquivo binário executável simples, porém possui todos os componentes necessários, como gerenciamento de memória e agendamento de thread de uma máquina virtual diferente, chamada Substrate VM, para executar nossa aplicação.

Por conveniência, o projeto Maven de exemplo já possui a configuração necessária para construir o projeto como sendo nativo. É necessário ter o GraalVM no sistema com a ferramenta de imagem nativa instalada. Siga estas instruções sobre como fazer isso, caso ainda não tenha. Depois, basta fazer o build como qualquer outro projeto Maven, mas com o perfil nativo: mvn verify -Pnative. Isso irá gerar um executor binário na pasta de destino, que podemos executar como qualquer outro arquivo binário, com ./project-name-runner. A seguir veja o exemplo do resultado ao executar o comando:

[io.quarkus] (main) code-with-quarkus 1.0.0-SNAPSHOT (powered by Quarkus 1.3.0.Final) started in 0.023s. Listening on: http://0.0.0.0:8080
INFO  [io.quarkus] (main) Profile prod activated.
[io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, narayana-jta, resteasy, resteasy-jsonb]

Notou o tempo de inicialização? Apenas 0,023s. Ok, a aplicação não é muito grande, mas ainda assim é bem impressionante. Mesmo para aplicações reais, poderá ver os tempos de inicialização na ordem de milissegundos. Podemos aprender mais sobre o GraalVM neste site.

Produtividade do desenvolvedor

Vimos que o Quarkus pode ajudar a empresa a se tornar nativa na nuvem. Impressionante. Mas e os desenvolvedores? Todos nós gostamos de novidades , e também somos super preguiçosos. O que o Quarkus faz pelos desenvolvedores que nenhuma outra tecnologia pode fazer?

Bem, que tal um hot reloading que realmente funciona sem o uso de ferramentas externas ou truques complicados? Sim, é verdade. Agora, 25 anos após o nascimento do Java, temos uma maneira confiável de mudar o código e ver essas mudanças com um simples refresh. Novamente, isso é possível devido a maneira como o Quarkus funciona internamente. O segredo está no código, então não precisamos mais nos preocupar com as coisas que complicam o hot reloading. Agora, isso será uma operação trivial.

Para fazermos isso, devemos executar o Quarkus no modo de desenvolvimento. Basta executar mvn quarkus:dev e estamos prontos para continuar. O Quarkus será inicializado e estamos livres para fazer as alterações no código e vê-las imediatamente. Por exemplo, podemos alterar os parâmetros REST no terminal, adicionar novos métodos e alterar os caminhos. Depois de chamá-los, serão atualizados de acordo com as alterações do código. Muito bom, não é?

O Quarkus está pronto para a produção?

Tudo isso parece bom demais para ser verdade, mas o Quakus está realmente pronto para os ambientes de produção? Sim, ele está.

Muitas empresas já estão adotando o Quarkus como ambiente de desenvolvimento e execução. O Quarkus tem uma cadência de novas atualizações muito rápida (coisa de algumas semanas) e uma forte comunidade open source que ajuda todos os desenvolvedores da comunidade Java, estejam eles começando a utilizar o Quarkus ou sejam eles desenvolvedores avançados na tecnologia..

Confira esta aplicação de exemplo que você pode baixar ou clonar. Também pode ler algumas das histórias de adoção em algumas postagens do blog para ter uma ideia melhor das experiências do usuário ao utilizarem o Quarkus.

Conclusão

Após um ano de seu anúncio oficial, o Quarkus já está na sua versão 1.3.1.Final. Um grande esforço está sendo colocado no projeto para ajudar as empresas e desenvolvedores a escreverem aplicações que possam ser executadas nativamente na nuvem.

Não sabemos até onde o Quarkus pode chegar, mas uma coisa é certa: A ferramenta sacudiu todo o ecossistema Java em um espaço dominado pelo Spring. Creio que o ecossistema só pode vencer tendo várias opções que podem impulsionar umas às outras e assim, inovar a fim de se manterem competitivas.

Fontes

Sobre o autor

Roberto Cortez é um desenvolvedor Java apaixonado com mais de 10 anos de experiência. Ele está envolvido na comunidade open source para ajudar outras pessoas a divulgar o conhecimento sobre as tecnologias Java. É um palestrante regular nas conferências como JavaOne, Devoxx, Devnexus, JFokus e outras. Lidera o Coimbra JUG e fundou a JNation Conference em Portugal. Quando não está trabalhando, ele sai com os amigos, joga no computador e passa o tempo com a família.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT