Usando Shadow em um projeto Kotlin
Tags: kotlin, backend, braziliandevs
Published: 2021-09-20 02:59:09

## 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ê é Shadow?

[Shadow](https://github.com/johnrengelman/shadow) é um plugin para o Gradle que tem como objetivo permitir que todas as dependências, junto com o código. Permitindo juntar toda a aplicação em um único JAR.

## Vantagens

A principal vantagem para usar Shadow é no momento de levar a aplicação á produção. Pois teremos toda a aplicação em um uníco arquivo, tanto para projetos Web, quanto para bibliotecas por exemplo.

## Criando um projeto

Abra seu IntelliJ no menu inicial e clique em *New Project*:

![botão New Project no menu inicial do IntelliJ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/587xhjlyvztrdtmks1eo.png)

Depois, selecione a opção **Kotlin DSL build script**, selecione também a opção **Kotlin/JVM**, e opicionalmente remova a primeira opção **Java**. Essa opção não vai mudar em nada, pois ela dá suporte do Gradle á linguagem Java, mas apenas iremos usar Kotlin.

Após isso, clique em **Next** e escreva o nome do projeto e a localização na sua máquina. Essas duas opção são completamente pessoais, caso não tenha nenhuma ideia, coloque algo como **shadow** apenas como identificação.

## Instalando Shadow

Para instalar o Shadow, precisamos adicionar na seção `plugins` do arquivo `build.gradle.kts` o Shadow. Dessa maneira:

```kotlin
plugins {
    kotlin("jvm") version "1.5.30"
    id("com.github.johnrengelman.shadow") version "7.0.0"
}
```

Depois disso, vamos adicionar a função principal `MainKt` ao JAR final, com isso, o Shadow saberá qual é a função principal do nosso código para ser executada no JAR:

```kotlin
tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "MainKt"
    }
}
```

Com isso, nosso arquivo `build.gradle.kts` ficará assim:

```kotlin
plugins {
    kotlin("jvm") version "1.5.30"
    id("com.github.johnrengelman.shadow") version "7.0.0"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib"))
    implementation("com.github.ajalt.clikt:clikt:3.2.0")
    implementation("org.jetbrains.exposed:exposed-core:0.33.1")
    implementation("org.jetbrains.exposed:exposed-dao:0.33.1")
    implementation("org.jetbrains.exposed:exposed-jdbc:0.33.1")
    implementation("org.xerial:sqlite-jdbc:3.36.0.3")
    implementation("org.slf4j:slf4j-simple:1.7.32")
    implementation("com.github.ajalt.mordant:mordant:2.0.0-beta2")
}

tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "MainKt"
    }
}
```

Agora, clique no elefante no canto superior direito para carregar as alterações no Gradle.

![Elefante do Gradle no canto superior direito](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abopcvqqkj0a9cdwvygt.png)

## Criando um simples Hello World

Vamos criar um simples *Hello World* com Kotlin para termos conteúdo para ser compilado no projeto.

Crie um arquivo chamado `src/main/kotlin/main.kt`, com o seguinte conteúdo:

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

## Usando Shadow

Como adicionamos o Shadow como plugin do Gradle, temos duas novas tarefas, sendo a `knows`, e a `shadowjar`.

![Tarefas do Gradle relacionadas ao Shadow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmivxcx2vjm6wmusqanz.png)

A tarefa `knows` apenas mostra uma arte ASCII mostrando que "O Shadow sabe":

```
No, The Shadow Knows....

                                        .
                                .MMMMMO      .M
                              .MMMMMMMMM. MMMM.
                              .MMMMMMMMMMMMMMM.
                               .MMMMMMMMMMMMM
                               .MMMMMMMMMMMM
                            .+MMMMMMMMM,ZMMM.
                          ...7MM8D8MM.ZMMMMM.
       ..                      MMZ..MZZNMMMMM
      ....                  MMMMMMMZZZ.MMMMMMOOOOOO..
      ...                7MMMMMMMMMZZZMIMMMMOOOOOMMMM..
      .. .~.                .MMMMMOMZZZMZMMOOOOOMMMM MM.
         .MMMMM             ..MMM.7DOMOMOOOOOOOMM MMMMM Z
      ..  MMMMMMM..  .     ...MMMMMMMMMOOOOOOMMMMMMMMMM
       .    .MMMMMMM.       .MMMMM MMMMMOMOMMMMMMMMMMM
             MMMMMMMMM    .MMM.MMMMMMMMMMMOMMMMMMMMMMM
             .MMMMMMMM   $MMMM MMMMMMMMMMMMMMMMMM MMM
              MMMMMMNMMMMMMMM M.MMMMMM.MMMMMMMM MMMMMM
             ..MMMMMMMMMMMMMMMMMMMMMMMMMMMM.MNMMMMMMM .
              ...MMMMMMMMMMM MMMMMMMMMMMMM.MMMMMMMM.
                 MMMMMMMMMM.MMMMMMMMMMMMMDMMMMMMMM.
                ..MMMMMMMMMMMMMMMMMMM M,MMMMMMMMMMMMMMMZMMMMM  +D            ,
                     .:DMM.M. MMMMMMM.MMMMMMMMMMMMMMI:MMMMM      :MMO
                        . MMMMMMMMMMMMMMMMMMMM.MMMMM8   NMMMN
                       ..MMMMMMMMMMMMMMMMMMMMM  MMMMN.
                       .MMMMMMMMMMMMMMMM. MMM7  ,      . =.
                       MMMMMMMMMMMM.$MM  M   .   MM7
                      MMMMMMMMM=MI:M8  . MNOM     M
                     MMMMMMMMMM.      .
                    MMMMMM .
                   +MM
```

A outra tarefa, `shadowjar` gera o JAR executável com todas as dependências e a nossa aplicação. Essa tarefa é a principal funcionalidade do Shadow.

O output da `shadowjar` será algo parecido com isso:

```
BUILD SUCCESSFUL in 16s
2 actionable tasks: 2 executed
```

Com isso, teremos nosso JAR feito no arquivo `build/libs/shadow-1.0-SNAPSHOT-all.jar`. Dentro desse arquivo há todas as dependências da nossa aplicação, e também o nosso código. É por causa disso que esse arquivo pesa 1.7MB.

Para executar esse arquivo, podemos usar o comando `java -jar`, passando nosso arquivo JAR. dessa maneira:

```
java -jar build/libs/shadow-1.0-SNAPSHOT-all.jar
```

Executando esse comando, o output será:

```
Olá Mundo!
```

Com isso conseguimos isolar toda a aplicação e suas dependências em um único arquivo que pode ser executado usando JAR.

## Finalização

Neste artigo, aprendemos como usar o básico do Shadow, e sua principal missão de isolar toda a aplicação em um único arquivo.

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