Transformando JARs em binário com GraalVM
Tags: kotlin, graalvm, backend, braziliandevs
Published: 2021-11-01 00:39:52

## Kotlinautas

Esse conteúdo é oferecido e distribuído pela comunidade [Kotlinautas](https://twitter.com/kotlinautas/), uma comunidade brasileira que busca oferecer conteúdo gratuito sobre a linguagem Kotlin em um espaço plural.

![capa Kotlinautas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jreawpvk6whxigcpmctf.png)

## O quê é um binário?

Binário é um executável do sistema. um binário pode ser executado diretamente pelo sistema, pois é composto totalmente por linguagem de máquina.

As vantagens de um binário é a velocidade de execução, que é geralmente BEM rápida, além de não precisarmos de uma linguagem instalada para rodar esse programa, pois o próprio sistema irá cuidar de rodar esse executável.

## GraalVM

[GraalVM](https://www.graalvm.org/) é uma máquina virtual da Oracle para aumentar a velocidade de aplicações. Uma das funções da GraalVM é a *Native Images*, que é uma maneira de unir código de qualquer linguagem da JVM (Java, Kotlin, Clojure, etc.) em um único arquivo totalmente em código de máquina. Eliminando a necessidade de utilizar uma JVM para rodar um projeto.

Esse processo de transformação de código JVM para binários só deve ser feito para utilizar esse binário em produção. Pois esse processo é demorado e gasta muito processamento e memória, logo, em ambiente de desenvolvimento é mais fácil utilizar o processo normal da JVM para rodar seu código.

## Instalação da GraalVM

Há alguns documentos oficiais de instalação da GraalVM para algumas plataformas, sendo:

- [Windows](https://www.graalvm.org/docs/getting-started/windows/)
- [Linux](https://www.graalvm.org/docs/getting-started/linux/)
- [MacOS](https://www.graalvm.org/docs/getting-started/macos/)

## Instalação da *Native Image*

A *Native Image* pode ser instalada usando a [GraalVM Updater](https://www.graalvm.org/reference-manual/graalvm-updater/), que é uma ferramenta utilizada para instalar utilitários da GraalVM. Essa instalação pode ser feita com o comando:

```
gu install native-image
```

## Hello World

Agora vamos criar um *Hello World* em Kotlin para gerar o JAR desse *Hello World* para transformar em binário com *Native Image*.

Isso pode ser feito com qualquer editor, não há necessidade de utilizar o IntelliJ, mas caso prefira, crie um projeto no IntelliJ para isso.


Arquivo `main.kt`:

```kotlin
fun main(){
  println("Olá Mundo!")
  }
```

Agora precisamos tranformar esse arquivo em um JAR. Para fazer isso, podemos usar o comando `kotlinc` que é o compilador do Kotlin. Vá até o caminho que esse arquivo está, e vamos fazer essa compilação com o comando abaixo:

```
kotlinc main.kt -include-runtime -d main.jar
```

Agora temos o nosso JAR no arquivo `main.jar`. Caso você queira executar esse JAR, isso pode ser feito com o comando `java -jar main.kt`, que terá `Olá Mundo!` como resultado:

```
Olá Mundo!
```

Agora precisamos transformar esse JAR em binário, podemos fazer isso com o comando `native-image`. Dessa maneira:

```
native-image --static -jar main.jar
```

Com isso o processamento irá começar. A GraalVM ao longo do processamento irá mostrar alguns dados sobre o processo:

```
$ native-image --static -jar main.jar

Build on Server(pid: 5484, port: 35163)
[main:5484]    classlist:     441.34 ms
[main:5484]        (cap):   1,017.18 ms
[main:5484]        setup:   1,581.26 ms
[main:5484]   (typeflow):   2,216.25 ms
[main:5484]    (objects):     516.04 ms
[main:5484]   (features):      86.21 ms
[main:5484]     analysis:   2,876.19 ms
[main:5484]     universe:     131.56 ms
[main:5484]      (parse):     610.96 ms
[main:5484]     (inline):     518.10 ms
[main:5484]    (compile):   2,818.48 ms
[main:5484]      compile:   4,187.55 ms
[main:5484]        image:     354.83 ms
[main:5484]        write:     164.75 ms
[main:5484]      [total]:   9,769.44 ms
```

Após o término desse processamento teremos um binário `main` com todo o código atual. Esse binário terá cerca de 12MB de tamanho.

Para executar esse binário, no Windows podemos usar o comando `main` no diretório que esse binário está, e em Linux/MacOS podemos usar `./main`.

## Velocidade

Podemos comparar o tempo de execução do JAR e do binário, caso você esteja em sistemas Linux/MacOS existe o comando `time` para medir o tempo de execução de um comando, comparando os dois métodos teremos o resultado abaixo:

```
$ time java -jar main.jar
Olá Mundo!
java -jar main.jar  0,12s user 0,02s system 64% cpu 0,114 total

$ time ./main
Olá Mundo!
./main  0,00s user 0,00s system 74% cpu 0,002 total
```

Podemos ver que a principal diferença entre os dois é a diferença de tempo que cada um executou. Enquanto `java -jar main.jar` demorou 0.12 segundos para rodar, `./main` levou 0 segundos para rodar, de maneira quase instantânea. Claro, para programas pequenos a diferença pequena, mas para programas maiores como uma aplicação web essa diferença irá ficar bem maior.

## Finalização

Neste artigo você aprendeu como utilizar a [GraalVM](https://www.graalvm.org/) para gerar binários de projetos JVM especialmente Kotlin, e executar esse binário final.

Muito obrigada por ler ❤️🏳️‍⚧️ e me segue nas redes, é tudo [@lissatransborda](https://twitter.com/lissatransborda) 👀