Gerenciando versões com SDKMAN!
Tags: java, ubuntu, productivity
Published: 2021-05-10 17:29:30

![alongtimeago](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xx39p5tp6i6dwjbka5p1.jpg)
 Bom, quando comecei a programar, colegas me contaram sobre a existência de uma ferramenta que podia me auxiliar ao instalar as versões do Java. Porém, como eu tinha acabado de começar, fiquei confuso sobre como essa ferramenta funcionava exatamente, então deixei para um futuro.

Anos se passaram, até que em um belo dia, sentei para trabalhar e, como de costume, fui olhar os Pull Requests para revisar os códigos da equipe. Me deparei com um PR que atualizava a versão do Java em nosso projeto. Nesse momento varias coisas vieram na minha cabeça:
- Puts, isso vai dar um trabalho, atualizar Path, configurar IDE...
- Onde será que tem essa versão? De qual distribuidora eu baixo?
- Será que é tranquilo instalar ou requer muito esforço?
- E se eu definir como _default_ e quebrar meus outros projetos?


... e um pensamento veio mais forte ainda: e agora quem poderá me defender?

## Eu, o SDKMAN!

Software Development Kit Manager (algo como, Gerente de Kit de Desenvolvimento de Software) é uma ferramenta que gerencia as versões paralelas de vários SDKs, tambem chamados de "candidates" (candidatos). O nome mais conhecido é **SDKMAN!**, assim mesmo, com exclamação no final.

O _SDKMAN!_ nos auxilia para tratar de nossas configurações como se fossem um "detalhe", algo simples, algo que não deveríamos dedicar muito esforço. Afinal, devemos deixar a árdua labuta para nossas práticas de código.

Fornecendo uma interface via linha de comando (CLI) que nos ajuda a instalar, listar, alternar e remover esses candidatos. 

Além disso, podemos destacar alguns pontos positivos, como:
- By Developers, for Developers: o _SDKMAN!_ se encarrega de definir as variáveis de ambiente para nós
- Java all the way down: Podemos instalar vários candidatos para JVM, assim como Java, Groovy, Scala, Kotlin, Maven, Gradle e etc...
- Lightweight: Super leve, escrito em Bash (e funciona com zsh também). Só precisa de cURL e zip/unzip instalados.
- Multi-platform: Roda em sistemas UNIX, como Mac OSX, Linux, e etc.
- APIs e Open-Source: Novos clientes podem ser facilmente escritos consumindo a API deles e é um projeto open source.
- Podemos adicionar também nossa própria versão para ser gerenciada pelo _SDKMAN!_.

## Como instalar?

Vamos seguir nas versões UNIX like, pois são as que eu tenho mais intimidade.

> Eu não utilizo o Windows como meu sistema operacional padrão, mas em sua [própria documentação](https://sdkman.io/install), diz que hoje tem algumas formas disponíveis para instalar. Caso alguém tenha alguma dúvida, pode mandar que tento ajudar de alguma forma.


Primeiro vamos abrir o terminal e rodar o comando:

```sh
curl -s "https://get.sdkman.io" | bash
```

E pronto, o _SDKMAN!_ está instalado. Temos duas opções:

1. Podemos apenas reiniciar o terminal.

1. Rodar o comando `source` para adicionar ao nosso arquivo de configuração:

```sh
source "$HOME/.sdkman/bin/sdkman-init.sh"
```

Feito isso, podemos rodar o comando `sdk version` e ver que o _SDKMAN!_ foi devidamente instalado.

## Mas e agora? Como utilizar?

Se instalar foi fácil, utilizar é mais ainda! Vamos ver os candidatos disponíveis com o comando:

```sh
sdk list
```

Apareceram vários né? Vamos pensar no nosso problema inicial que era atualizar a versão do Java para fazer o review do código, então podemos adicionar ao comando `list` o candidato que queremos:

```sh
sdk list java
```

O resultado será algo parecido com:

```txt
================================================================================
Available Java Versions
================================================================================
 Vendor        | Use | Version      | Dist    | Status     | Identifier
--------------------------------------------------------------------------------
 AdoptOpenJDK  |     | 16.0.1.j9    | adpt    |            | 16.0.1.j9-adpt      
               |     | 16.0.1.hs    | adpt    |            | 16.0.1.hs-adpt     
...
 Alibaba       |     | 11.0.9.4     | albba   |            | 11.0.9.4-albba      
               |     | 8.5.5        | albba   |            | 8.5.5-albba         
 Amazon        |     | 16.0.1.9.1   | amzn    |            | 16.0.1.9.1-amzn     
               |     | 16.0.0.36.1  | amzn    |            | 16.0.0.36.1-amzn
...
```

Olha que legal! O _SDKMAN!_ trouxe de uma forma um pouco diferente, né? Apareceram as versões disponíveis do Java. Vamos entender um pouco sobre cada coluna:

- Vendor: mais conhecido como o fornecedor daquela versão.
- Use: flag para dizer qual é a versão que estamos utilizando atualmente.
- Version: qual versão do Java do candidatos.
- Dist: distribuição, um slug para o fornecedor.
- Status: mostra quais versões temos instaladas.
- Identifier: um ID, é unico e é utilizado para instalar ou remover uma versão.

Agora que temos uma ideia do que é cada coluna, para instalar nos precisamos passar ao `sdk` a identificação da versão que queremos instalar. No nosso caso vai ser a `16.0.1.9.1-amzn`. Então, rodamos o comando:

```sh
sdk install java 16.0.1.9.1-amzn
```

Durante essa instalação, seremos perguntados se queremos definir como a versão _default_ do Java. Pode confirmar!

E está lá, rodando o comando `java --version` e o `javac --version` vemos que a versão é a 16 que acabamos de instalar! Fácil, né?

Agora só falta configurarmos em nossas IDEs. Pode ser na de sua preferência. Aqui, irei mostrar tanto no IntelliJ quanto no Eclipse, que são as que tenho maior intimidade.

### IntelliJ

1. Abra o IntelliJ e vá em _File > Project Structure_.
2. Na parte de _Project SDK_ clique em _Edit_.
3. Clique no _+_ (add new sdk) e passe o caminho do SDK para que aponte para a _current_, que sempre irá a versão configurada no _SDKMAN!_. No meu caso é algo como: `/home/gabriel/.sdkman/candidates/java/current%`. Se você quiser, pode apontar para algum dos candidatos que você baixou pelo _SDKMAN!_.
4. Após adicionado, volte em _Project Structure_ e em SDKs selecione a versão que você acabou de criar.
5. No menu _Run_, vá em _Edit configurations_, para editar as configurações de execução do projeto.
6. Expanda _Environment_ e, em _JRE_, selecione a versão _current_ do Java que você instalada pelo _SDKMAN!_.


### Eclipse

1. Abra o Eclipse e vá em _Project > Properties_ e entre na aba _Libraries_.
2. Clique em _Modulepath > Add Library_ e selecione _JRE System Library_.
3. Apos clicar em _Next_, selecione _Workspace default JRE (X.x.x.x.x-slug)_.
4. Pra confirmar se tudo está correto, ao lado do icone de _Run_, clique na setinha para baixo e entre em _Run Configurations_.
5. Clique na aba _JRE_, e veja se está marcado _Project JRE_. Pronto!


## Comandos extras:
 
**Alternar** entre as versões que você tem instalada em sua máquina, é super simples!
 
Para usar uma versão (temporariamente):

```sh
sdk use java 15.0.2.7.1-amzn
```

Quando você abrir um outro terminal, a versão será a default.
 
Para definir como default (permanentemente):

```sh
sdk default java 15.0.2.7.1-amzn
```

Para ver qual é a **versão atual**:

```sh
sdk current java
```

Para **desinstalar** uma versão:

```sh
sdk uninstall java 16.0.1.9.1-amzn
```

Ao usar o _SDKMAN!_, as versões são baixadas para sua máquina. Para **atualizar as versões dos candidatos**, rode o comando:

```sh
sdk update
```

## Como desinstalar:

Caso não tenha acostumado, teve algum problema ou algo relacionado, é fácil desintalar o _SDKMAN!_.

Podemos usar o comando:

```sh
 rm -rf ~/.sdkman
```

Agora é onde está o pulo do gato! Temos que abrir algum dos arquivos de inicialização, como o `.bashrc`, `.bash_profile`, `.profile` e/ou `.zshrc` em um editor de textos.

No fim do arquivo você deve encontrar o bloco a seguir:

```txt
#THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!
 
[[ -s "/home/dudette/.sdkman/bin/sdkman-init.sh" ]] && source "/home/dudette/.
 
sdkman/bin/sdkman-init.sh"
```

Apague este bloco por completo e salve. Prontinho! O _SDKMAN!_ está completamente deletado de sua máquina!

## Referências:

A documentação do _SDKMAN!_ é bem completinha, você pode ver em: https://sdkman.io/

Diferença entre as distribuições das JDKs: https://sdkman.io/jdks

Pronto, agora você pode fazer a mesma coisa para tudo que o _SDKMAN!_ oferece suporte :)