terça-feira, 4 de agosto de 2020

Criando arquivo .sh para executar aplicação Java com passagem de parâmetros

Conforme mostrado no artigo http://www.josepojr.com/2020/07/criando-arquivo-bat-para-executar.html
a configuração para Windows, mas para Linux, temos pequenas mudanças conforme exemplo abaixo:


java -Dfile.encoding=UTF-8 -cp ".:libs/*" pacote.minha.classe.Main $*

Aonde "$*" permite que passamos parâmetros dentro da execução do script .sh no Linux.
Também, alteramos o símbolo separador de path do windows que é um ponto-e-vírgula ";" para dois pontos ":" e colocamos aspas no valor do parâmetro "cp".
Importante não deixa espaço em branco depois de "$*" para a aplicação Java não entender que aquele espaço em branco é um argumento passado para o programa.

Criando shell script para executar aplicações Java no Linux com dependências

INTRODUÇÃO


Nessa publicação explicaremos como criar o arquivo .sh para iniciar uma aplicação Java com as suas dependências (Pastas libs contendo Jars, por exemplo). Para isto, vamos criar uma aplicação simples chamada "ExemploJava".


CONFIGURAÇÃO


Essa aplicação terá uma pasta chamada "libs" para conter os jars de bibliotecas de terceiros que a aplicação pode usar (ou não) e será referenciada no classpath da aplicação Java.

Outra pasta chamada de "bin" conterá os pacotes e classes do projeto. Por exemplo, se tivermos uma classe fictícia chamada "A" dentro do pacote "a.b.c", portanto o nome completo da classe será "a.b.c.A". E dentro da pasta "bin", teremos a pasta "a" e dentro desta a pasta "b". E por último, dentro da pasta "b", teremos a pasta "c" que conterá o arquivo "A.java" definindo a classe pública "A".

Estas duas pastas estarão dentro da pasta "ExemploJava" e o script .sh ("exemploJava.sh" por exemplo) estará dentro desta pasta.

Para efeito prático, vamos adotar a classe "A" como a classe com o método main (inicializadora da aplicação Java).

Portanto, o conteúdo do arquivo .sh será:

java -Dfile.encoding=UTF-8 -cp ".:bin/:libs/*:" a.b.c.A 


Aonde temos:

-Dfile.encoding=UTF-8
aonde informa a codificação usada, muito recomendável usar unicode no UTF-8 pois é uma codificação internacional e preparada para lidar com diversos alfabetos e idiomas.


-cp ".:bin/:libs/*:"
aonde informamos as pastas, jars e arquivos .class que estarão no classpath. Estando no classpath, nossa aplicação pode carregar e usar as classes. Se não estiver no classpath, pode dar erros em tempo de execução, lançado exceções dos tipos "java.lang.ClassNotFoundException" ou "java.lang.NoClassDefFoundError" por exemplo. Além disso, se forem colocados paths (caminhos) errados, ao rodar a aplicação não dará erro a priori (por causa desses paths sem jars ou arquivos .class), mas quando a classe Main for executada e for carregando as dependências, pode chegar numa classe que não estará no classpath. Portanto, muito cuidado para colocar o caminho correto para que as dependências dentro desses caminhos sejam carregadas corretamente para dentro da JVM.

Nesse exemplo, usamos a pasta bin para conter os arquivos .class ou recursos. Mas também é possível empacotar tudo num jar e colocar nesse argumento diretamente (":meuarquivo.jar") ou colocar esse jar na pasta "bin" ou "libs".
Lembrando também que os dois-pontos ":" é o separador de paths (caminhos) entre um jar ou diretório do outro. O sinal ponto "." representa o diretório atual que o script está sendo rodado.


a.b.c.A
É o nome completo para a classe Main que será iniciada pela JVM no comando "java".
Sem essa classe Main, o comando "java" abortará, mostrando uma mensagem de erro dizendo que não foi informado uma classe com o método estático "void main(String args[])".


OBSERVAÇÃO


Muito importante, depois da classe main "A", deverá ter um espaço em branco!
Caso contrário, ao executar o script sh, dará erros dizendo que a classe "a.b.c.A" não foi localizada e nem carregada! Pois, o shell script fornecerá como parâmetro a classe de nome completo "a.b.c.A\n" com a QUEBRA DE LINHA inclusa! E logicamente, no nosso classpath (formado pelo núcleo do Java e mais as pastas informadas no parâmetro "cp") essa classe de nome completo "a.b.c.A\n" não existirá! E pior, difícil de localizar esse tipo de erro, pois a quebra de linha "\n" fica invisível no terminal!

segunda-feira, 6 de julho de 2020

Criando arquivo .bat para executar aplicação Java com passagem de parâmetros

Nesse artigo, vamos mostrar como fazer a criação do arquivo .bat para ser executado no sistema operacional Windows, chamando uma aplicação Java e podendo passar parâmetros.

Para isso, vejam esse exemplo:


set PARAMETROS=%*
java -Dfile.encoding=UTF-8 -cp .;libs/* pacote.minha.classe.Main %PARAMETROS%



Aonde a variável "PARAMETROS" define a maneira de passar o parâmetro na execução do arquivo.bat.

Para executar esse bat, salve como "arquivo.bat" e depois execute em linha de comando digitando da seguinte maneira:

arquivo.bat a b c

Aonde os parâmetros "a", "b" e "c" serão passados para a classe Main declarada em "pacote.minha.classe.Main" aonde informa a classe com o método estático "void main(String args[])" aonde que em Java é o método que é chamado na execução de um programa.

Portanto, esses parâmetros passados estarão contidos na variável "args"do programa Java. Logicamente, nesse exemplo, estou usando o parâmetro com o nome "args", mas se o nome for diferente, a passagem dos parâmetros ocorrerá normalmente e sua aplicação poderá passar!

Para o parâmetro ".;libs/*" indica uma pasta chamada "libs" e todos os jars que estiverem contidas dentro dessa pasta serão carregados no classpath da aplicação, se caso for necessário. E o "." indica o diretório atual, para procurar jars no mesmo diretório do arquivo.bat. E por último, o ";" apenas separa os diretórios listados, podendo carregar vários diretórios de jars para a aplicação rodar.

Temos abaixo um exemplo de classe Main:

public class Main {

    public static void main(String args[]) {
        for(int i=0; i < args.length; i++) {
             System.out.println("Parametro passado: " + args[i]);
        }
   }
}

Também é possível chamar diretamente o jar no arquivo.bat:

set PARAMETROS=%*
java -jar A.jar %PARAMETROS%

Aonde temos todas as dependências do jar embutidas num único jar.