TAG | Java
Sacanagem na instalação da JVM
Sem comentários · Post por Petter Rafael em Diversos, Java, Oracle
Toda empresa desenvolve produtos para obter lucro, mas algumas parecem se render a simples trocados e com isso depreciam ou a imagem da própria empresa ou a imagem do produto, um exemplo disso é a Oracle.
Desde que a Oracle comprou a Sun e com isso absorveu o Java e outros produtos que no instalador da JVM ela sorrateiramente adicionou a opção de instalar a barra de ferramentas da Ask no browser da vÃtima do usuário.
É claro que a Ask pagou um considerável valor para que a Oracle distribuÃsse sua barra de ferramentas, mas para a Oracle além deste valor não ser a salvação da lavoura só acaba por depreciar o Java.
Depreciar porque tanto no ambiente corporativo quanto doméstico a barra de ferramentas da Ask é nociva, ao ser instalada ele deprecia a performance ao uso do browser, abre conexões obscuras do browser com seus servidores e mesmo que seja removida futuramente ainda deixa vestÃgios espalhados pelo sistema, o único “benefÃcio†é a busca na web via servidores da Ask que digamos, ainda está muito longe de ser semelhante a inteligência de busca do buscador do Google.
A forma como a opção de instalar simultaneamente a barra da Ask atrapalha o processo de instalação da JVM e usuários leigos podem deixar a opção marcada com medo que ao desmarcar a JVM não seja instalada, estratégia digna de softwares adware que encontramos por aÃ, que só desacredita a confiabilidade do Java ou da JVM.
Leia mais:
Quem já trabalhou com XML no Oracle já deve ter utilizado o XMLType, este cara implementa DOM para fazer o parser e por uma série de motivos não existe uma implementação para parser SAX no PL/SQL, daà esbarramos que em alguns casos ao efetuar o parser o DOM se torna lento, principalmente um arquivo XML grande, como resolver essa situação?
A melhor saÃda então é criar uma classe Java no próprio bando de dados Oracle e esta classe irá realizar o parser de um CLOB informado e assim resolver os problemas de lentidão deste processo, a classe Java ficaria assim:
create or replace java source named "Validar" as import java.sql.*; import java.io.*; import java.lang.String; import oracle.xml.sql.dataset.*; import oracle.xml.sql.query.*; import oracle.xml.sql.*; import oracle.sql.*; import oracle.jdbc.driver.*; import oracle.xml.parser.schema.*; import oracle.xml.parser.v2.*; import org.xml.sax.*; import org.w3c.dom.*; /** * Classe para implementar parser Sax no Oracle. Devido ao fato do PL/SQL não * conter nativamente um parser Sax o mesmo foi implementado em Java. Este * processo é recomendado para a execução de Sax no Oracle via OTN. * * @author Petter * @since Março/2013 * @version 0.5 */ public class Validar { public static String validarCLOB(oracle.sql.CLOB xmldoc) { SAXParser parser = new SAXParser(); try { parser.parse(new ByteArrayInputStream(xmldoc.getBytes())); return "1"; } catch (SAXException e) { return "0 - " + e.getMessage(); } catch (Exception e) { return "Erro: " + e.getMessage(); } } } |
Isso irá criar uma classe Java no Oracle que simplesmente irá ser invocada por uma função que irá receber um CLOB que deverá “conter o XML†e irá retornar um VARCHAR2 com o retorno de 1 para caso de sucesso ou informar o erro caso ocorra algum. Veja como ficará a função:
CREATE OR REPLACE FUNCTION validarCLOB(xmldoc CLOB) RETURN varchar2 AS LANGUAGE JAVA NAME 'Validar.validarCLOB(oracle.sql.CLOB) returns java.lang.String'; |
Bem simples, basta então invocar a função e pronto, seu XML irá passar pelo parser SAX.
Leia mais:
Vejo vários desenvolvedores iniciantes com dúvidas de como quebrar em string em vários pedaços utilizando para isso um delimitador em Java, a tarefa é simples mas requer alguns cuidados para que tudo funcione a contento.
Em primeiro lugar a classe StringTokenizer é antiga e é melhor utilizar o método Split() em seu lugar.
Um desenvolvedor mais incauto faria o seguinte:
String[] varQuebra = minhaString.split(“.â€); |
No exemplo acima está a tentativa (frustada) de quebrar uma string pelo delimitador “.â€, porém não irá funcionar, pois caracteres especiais, como ponto, vÃrgula, etc não irão funcionar desta forma, é preciso primeiro identifica-lo como uma string comum, da seguinte forma:
String[] varQuebra = minhaString.split(Pattern.quote( “.â€)); |
Leia mais:
Corrigindo erro ao gerar relatório com o iReport (Jasper Reports)
Sem comentários · Post por Petter Rafael em Java
Alguma vez ao desenvolver um relatório utilizando Jasper Reports com iReport você já se deparou com a seguinte mensagem de erro:
net.sf.jasperreports.engine.JRRuntimeException: Parameter "DOCUMENT_BUILDER_FACTORY" does not exist. |
Isso ocorre devido ao fato de você ter um subReport sem conexão de dados configurada, mesmo que o seu subReport não utiliza nenhum tipo de fonte de dados externo é preciso configurar uma, pois o relatório chamador irá conter uma conexão e no vÃnculo com o subReport irá de forma implÃcita tentar acessar o parâmetro com o erro em questão.
Para corrigir este bug (eu classifico isso como um bug) basta definir no subReport uma conexão de dados, mesmo que não conecte em nada de fato, basta apenas dizer que irá utilizar uma que o parâmetro de DOCUMENT_BUILDER_FACTORY será automaticamente criado no subReport.
Para isso vá nas propriedades do subReport e em “Connection Type†selecione “Use a Data Sourceâ€.
Leia mais:
Como embutir o Multivalent em sua aplicação Java
Sem comentários · Post por Petter Rafael em Java
Existe uma API escrita em Java chamada Multivalent, ela possui um browser para navegar pela internet (se bem que com todos os avanços dos browsers nos últimos anos o browser do Multivalent se torna irrelevante), mas o grande trunfo do Multivalent é sem dúvida o Tools.
Com o Tools temos vários recursos para adicionar em nossa aplicação desenvolvida em Java ou até mesmo executar via linha de comando no terminal (DOS), mas vamos nos concentrar no recurso de compactar arquivos PDF.
Utilizando a classe Compress que está dentro do Tools do Multivalent podemos compactar arquivos PDF, acessando a página do projeto pode ver a sintaxe para executar via linha de comando e ainda todas as opções de parâmetros disponÃveis, porém o que pouca gente fala é como consumir esta classe Compress dentro de um projeto Java.
Para isso vamos fazer o download do Multivalent e incluir o arquivo .JAR na biblioteca do nosso projeto, assim podemos invocar a classe Compress ou diversas outras do Multivalent a vontade, como a classe Compress é uma classe Main devemos montar um array de parâmetros e em seguida invoca-la como atribuindo o array de parâmetros, assim terÃamos o funcionamento como se estivéssemos executando a classe Compress via linha de comando. Veja o exemplo abaixo:
List parametros = new ArrayList(); parametros.add("-compact"); parametros.add("-force"); parametros.add("-noembed"); parametros.add("-inplace"); parametros.add(“meuPDF.pdfâ€); String[] params = (String[]) parametros.toArray (new String[0]); tool.pdf.Compress.main(params); |
Uma dica, por diversas questões a equipe do Multivalent removeu o pacote Tools da última versão do Multivalent, mas uma simples busca do Google irá possibilitar que seja realizado o download de alguma versão mais antiga com o pacote Tools adicionado.
Mais uma dica, ao utilizar o parâmetro –compact, a compactação do seu arquivo PDF será excelente, porém somente o visualizador do Multivalent irá conseguir visualizar o PDF, geralmente compactamos os arquivos com –compact para economizar espaço em HD e no momento da visualização descompactamos para que o arquivo possa ser visualizado em qualquer visualizador de PDF.
Leia mais:
Uma coisa bem pouco explorada e que geralmente levanta dúvidas nos desenvolvedores Java é como gerar um arquivo texto (TXT) via JasperReport formatado (geralmente ao tentar formar o arquivo o mesmo fica com várias linhas em branco), na verdade o processo é simples e bem similar ao de gerar um arquivo PDF, porém alguns parâmetros são essenciais para que o arquivo texto seja gerado corretamente.
Vamos então simular uma situação com um aplicativo Java gerando um arquivo texto formatado via JasperReport, o que iremos precisar:
- Arquivo XML que será o repositório de dados;
- Arquivo .JASPER que é o compilado do iReport (editor visual para utilizar em conjunto com o JasperReport).
Vamos então ao código-fonte:
//Definir o local de execução (corrigir moeda, vÃrgulas, caracteres, etc) Locale locale = new Locale("pt", "BR"); parametros.put(JRParameter.REPORT_LOCALE, locale); try { // Definilção do XML e captura dos dados contidos. JRXmlDataSource xmlDataSource = new JRXmlDataSource(arqXML, noItera); xmlDataSource.setLocale(locale); //Gera a área de impressão para o JasperReport JasperPrint jasperPrint = JasperFillManager.fillReport(arqJasper, parametros, xmlDataSource); //Captura informações sobre as dimensões do documento (iReport) Integer pageHeight = jasperPrint.getPageHeight(); Integer pageWidth = jasperPrint.getPageWidth(); //Instancia o objeto que irá gerar o arquivo Texto formatado. JRTextExporter jrTextExporter = new JRTextExporter(); //Definições e parâmetros para gerar o arquivo Texto. jrTextExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); jrTextExporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, new Float(10)); jrTextExporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, pageHeight); /*Aqui você pode inserir um caractere de quebra de página caso algum interpretador do seu arquivo texto nece ssite*/ jrTextExporter.setParameter(JRTextExporterParameter.BETWEEN_PAGES_TEXT, "\f"); jrTextExporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, “meuarquivo.txtâ€); /*Aqui está o segredo, fazendo a divisão da largura da página do iReport com o número de colunas do relatóri o teremos o número correto de pixels para definir a largura dos caracteres*/ jrTextExporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, new Float(pageWidth / new Float (colunas))); //Exporta de fato o arquivo TXT jrTextExporter.exportReport(); } catch (JRException ex) { System.err.print("Erro: " + ex); } catch (Exception e){ System.err.print("Erro: " + e); } |
Geralmente vejo o pessoal errando na hora de definir a quantidade de pixels para a largura dos caracteres, fazendo a conta acima será possÃvel gerar o relatório de forma perfeita, independente do tamanho da página e da quantidade de caracteres.
Leia mais:
Algumas vezes ao executar alguma aplicação Java nos deparamos com a exceção Out of memory, isso ocorre, pois a configuração padrão da JVM (caso você não tenha alterado nenhum parâmetro na instalação) gira em torno de 8 MB, por isso devemos reconfigurar a JVM para que utilize mais memória porém algumas vezes isso não é possÃvel então devemos utilizar parâmetros de JVM durante a execução da aplicação (imagine derrubar um servidor para reconfigurar a JVM para somente uma aplicação).
Para reconfigurar o volume de memória utilizado pela JVM em tempo de execução temos dois comandos:
- -Xms: que define a quantidade mÃnima de memória Heap para a JVM;
- -Xmx: que define a quantidade máxima de memória Heap para a JVM.
Além dos problemas de Out of memory, um volume maior de memória Heap dará também mais performance durante a execução da aplicação.
Veja um caso prático de uso:
Java –Xms256M –Xmx1024M –jar seuApp.jar |
Neste exemplo eu defini 256 MB e 1024 Mb, respectivamente, limite mÃnimo e máximo para a JVM durante a execução daquela aplicação.
Uma dica, para uma JVM de 32 bits (independente se está sendo executada em um sistema operacional de 32 bits ou 64 bits) nunca coloque um valor maior do que 1024 MB para o limite máximo, isso irá causar erros na execução da aplicação devido a limitações do próprio padrão 32 bits, para o caso de sistemas operacionais 64 bits utilizando uma JVM também de 64 bits este limite não se aplica.
Leia mais:
Uma grande dúvida, e que muitas vezes atrasa os projetos, é como gerar de forma eficiente e dinâmica relatórios em aplicações Java, levando em conta que a capacidade de gerar relatórios tem que ser escalar, ou seja, tem que acompanhar a crescente demanda de necessidades por parte do cliente.
Hoje, uma das melhores soluções é a dobradinha JasperReport e iReport.
Para quem não sabe JasperReport é um framework Java que tem a capacidade de através uma definição em XML apontar para uma fonte de dados, seja ela um arquivo, uma planilha ou um banco de dados e extrair relatórios das mais diversas formas, com suporte para gráficos e formatações diversas.
Já o iReports é uma aplicativo que permite editar de maneira visual (drag-and-drop) o relatório, adicionando uma vasta gama de elementos e aprontando de forma simplificada para a fonte de dados e dessa forma gerar o arquivos necessário para o JasperReport gerar o relatório (modelo) abstraindo toda a complexidade de editar um arquivo XML na mão.
Para quem já desenvolveu com Crystal Report ou Report da Oracle o trabalho com o iReport será bem simples.
A instalação do iReport é bem simples, basta executar o arquivo e ir clicando em Next (não sem antes ler as mensagens do processo de instalação).
Para o JasperReport é importante que o seu projeto Java possua as seguintes bibliotecas incluÃdas na pasta LIB e no CLASSPATH do seu projeto:
- barbecue-1.5: para suportar código de barras;
- arial / comic-sans-ms / courier-new: fontes embarcadas;
- com-jaspersoft-ireport: framework iReport;
- commons-beanutils-1.8.2 / commons-collections-3.2.1 / commons-digester-2.1 / commons-logging-1.1: recursos comuns;
- groovy-all-1.7.5: linguagem padrão;
- iText-2.1.7: elementos de texto;
- jasperreports-5.0.0: JASPER engine de relatório;
- jdom: API para manipulação de XML;
- xalan-2.7.1: recursos de base.
O primeiro passo é realizar o download tanto da ferramenta iReport como do próprio JasperReport.
No próximo artigo iremos ver como gerar um relatório simples tendo como base de dados um arquivo XML.
Leia mais:
Executando comandos do DOS via Java – melhorando
1 comentário · Post por Petter Rafael em Dicas, Java
Voltamos a falar de Java, já leram o post anterior, sobre como executar comandos de sistema no Java? Conforme relatei ele tem um pequeno bug, que vasculhando a internet ninguém havia notado.
O bug consiste em comandos Java, como por exemplo o java –version, por uma caracterÃstica ele retorna do RunTime via método getErrorStream(), resumindo, retorna como se fosse um erro, mesmo que o comando tenha sido executado normalmente.
Como a rotina trata o retorno direto dos métodos getErrorStream() e getInputStream() a rotina acaba gerando uma informação errônea, mas como consertar? Simples, basta fazer um controle pelo retorno do exitValue(), que retornará zero no caso de sucesso ou 1 no caso de erros.
Veja como ficou a solução proposta:
public class ExecComando { public static void executar(java.lang.String scriptExec, java.lang.String typeCommand, java.lang.String command){ String[] finalCommand; finalCommand = new String[3]; finalCommand[0] = scriptExec; finalCommand[1] = typeCommand; finalCommand[2] = command; Process proc; String sucesso = "", erro = "", escuta; try{ proc = Runtime.getRuntime().exec(finalCommand); proc.waitFor(); int retorno = proc.exitValue(); BufferedReader inputSucesso = new BufferedReader(new InputStreamReader(proc.getInputStream())); BufferedReader inputErro = new BufferedReader(new InputStreamReader(proc.getErrorStream())); while ((escuta = inputSucesso.readLine()) != null) { sucesso += escuta + "\n"; } inputSucesso.close(); while ((escuta = inputErro.readLine()) != null) { erro += escuta + "\n"; } inputErro.close(); if(retorno == 0){ System.out.println("Sucesso!"); if(!erro.equals("")){ System.out.println(erro); }else{ System.out.println(sucesso); } }else{ System.out.println("Erro!"); System.out.println(erro); } }catch (IOException ex) { ex.printStackTrace(); }catch (InterruptedException ie){ ie.printStackTrace(); } } } |
Basicamente capturamos o inteiro que representa o nosso retorno e modificamos a forma como ocorre a impressão no console, assim temos o bug reportado corrigido e a rotina funcional.
Na internet é possÃvel encontrar soluções que vão desde a implementação de Threads para a captura de sucesso e erro ou ainda a possibilidade de utilizar um ProcessBuilder para parametrizar o Path do Java, mas se você procura apenas uma solução rápida, flexÃvel e funcional para servir de interface entre suas outras classes e o sistema operacional a solução apresentada aqui ainda é a mais propÃcia.
Leia mais:
Tenho visto várias pessoas necessitando de uma forma de executar comandos de DOS ou via Terminal (Linux) a partir de aplicações Java, e além da execução capturar se o mesmo foi executado com erro ou sucesso e se possÃvel o seu retorno.
Isto é bem simples de ser implementado em Java, veja o código abaixo:
public class ExecComando { public static void executar(java.lang.String scriptExec, java.lang.String typeCommand, java.lang.String command){ String[] finalCommand; finalCommand = new String[3]; finalCommand[0] = scriptExec; finalCommand[1] = typeCommand; finalCommand[2] = command; Process proc; String sucesso = "", erro = "", escuta; try{ proc = Runtime.getRuntime().exec(finalCommand); proc.waitFor(); BufferedReader inputSucesso = new BufferedReader(new InputStreamReader(proc.getInputStream())); BufferedReader inputErro = new BufferedReader(new InputStreamReader(proc.getErrorStream())); while ((escuta = inputSucesso.readLine()) != null) { sucesso += escuta + "\n"; } inputSucesso.close(); while ((escuta = inputErro.readLine()) != null) { erro += escuta + "\n"; } inputErro.close(); if(!sucesso.equals("")){ System.out.println("Sucesso!"); System.out.println(sucesso); }else if(!erro.equals("")){ System.out.println("Erro!"); System.out.println(erro); } }catch (IOException ex) { ex.printStackTrace(); }catch (InterruptedException ie){ ie.printStackTrace(); } } } |
O que este bloco de código Java faz?
Basicamente o método executar() recebe como parâmetros o terminal e o comando a ser executado, assim ele abre um processo de RunTime que vai de fato invocar o terminal e executar o comando para após feito isso ele irá capturar o InputStream em caso de sucesso ou erro e depois irá ler e converte-los em um String para finalmente ser impressa no console.
O próprio código Java é autoexplicativo e bem simples de ser estudado e assimilado.
Para executa-lo, basta acionar o método da seguinte forma:
ExecComando.executar("cmd.exe", "/C", "dir c:"); |
Em tempo, variações deste código Java estão espalhadas pela internet, mas se você executar um comando Java válido, como por exemplo java –version, será retornado um erro e o descrito da execução indicando que o comando foi executado com sucesso, o que de fato ocorre, isto é uma caracterÃstica que pode te atrapalhar, alguém sabe a solução para ela?
Faça o teste e execute o comando java –version para ver o resultado.
No próximo post irei colocar a solução para esta questão, é tão simples como o próprio código que mostrei aqui.
