Gerar "jar" da aplicação com arquivos .jasper (ambiente desktop). [Resolvido]

Galera, boa noite.

Estou abrindo esse tópico pq procurei na net inteira e achei muitos problemas relacionados, mas nenhum com uma solução concreta.

Eu estou com um problemaço… Depois de muita luta em um projeto pequeno meu, eu fui gerar o jar para deixar pronto e botar pra rodar no cliente. Só que depois q eu gerei o jar, o meu relatório não rodou no jar. Já no eclipse funciona normalmente.
O erro q dá eh q não é encontrado o arquivo .jasper.
Mas eu já fiz de tudo: gerei jars de várias formas, com subdiretórios das libs… em fim, não sei oq eu faço…

Alguém sabe como mapear o relatorio.jasper para q funcione na aplicação depois de gerado o jar ??

Agradeço muito desde já…

Olá caceres.

Para poder resolver este problema coloquei os arquivos .jasper dentro de pacotes dentro da minha aplicação e para chamar o relatorio de dentro do jar, realizei da seguinte maneira.
Espero que seja isto que necessita e Espero que ajude.

Até mais.

Chamada do Relatorio (Camada Visualização - Botão)

 	    JDialog viewer = new JDialog(new javax.swing.JFrame(), "Visualização do Relatório", true);
            viewer.setSize(CapturaTamanhoTela.getWidthMonitor(), CapturaTamanhoTela.getHeightMonitor());
            viewer.setLocationRelativeTo(null);
            JasperViewer jrViewer = new JasperViewer(facilCobrancaCTRFacade.relatorioAdministradores(), false); // chamando o metodo da classe abaixo
            viewer.getContentPane().add(jrViewer.getContentPane());
            viewer.setVisible(true);

Metodo para chamar o relatorio passando os parametros

public JasperPrint relatorioAdministradores() throws FileNotFoundException {
        try {
            InputStream caminhoRelatorio = this.getClass().getClassLoader().getResourceAsStream("facilcobranca/presentation/relatorio/Administradores.jasper");// caminho do arquivo dentro dos pacotes
            FileInputStream caminhoProperties = new FileInputStream("DadosEmpresa.properties");
            
	    Properties properties = ManipularArquivoProperties.lerProperties(caminhoProperties); // necessario para os parametros
            Map parameters = new HashMap();
            parameters.put("NOMEEMPRESA", properties.getProperty("nome"));
          
            return VisualizarRelatorio.chamaRelatorio(caminhoRelatorio, parameters); // Classe util, visualiza relatorio
        } catch (Exception ex) {
            JConfirmMessage.showMessageDialog(ex.getCause().getMessage(), "Atenção!!!");
            return null;
        }
    }

Class VisualizarRelatorio

public class VisualizarRelatorio {

    public static JasperPrint chamaRelatorio(InputStream caminho, Map parameters) {
        try {
            Connection con = ConexaoPostgres.getInstance().getConnection(); //Classe e metodo para recuperar uma conexão
            JasperPrint jasperPrint = JasperFillManager.fillReport(caminho, parameters, con);
            return jasperPrint;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
}

Class util para leitura de parametros de um arquivo properties.

public class ManipularArquivoProperties {

    public static Properties lerProperties(InputStream caminhoProperties) {
        try {
            Properties properties = new Properties();
            properties.load(caminhoProperties);
            caminhoProperties.close();
            return properties;
        } catch (Exception ex) {
            JConfirmMessage.showMessageDialog(ex.getCause().getMessage(), "Atenção!!!");
            return null;
        }
    }


    public static void gravarProperties(String caminhoProperties, Properties properties, String header) {
        try {
            FileOutputStream fis = new FileOutputStream(new File(caminhoProperties));
            properties.store(fis, header);
            fis.close();
        } catch (IOException ex) {
            JConfirmMessage.showMessageDialog(ex.getCause().getMessage(), "Atenção!!!");
        }
    }
}

Class para captura tamanho da tela para ajustes da visualização do relatorio

public class CapturaTamanhoTela {

    public static int getWidthMonitor() {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Dimension screenSize = toolkit.getScreenSize();
        int x = screenSize.width;
        return x - 100;
    }

    public static int getHeightMonitor() {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Dimension screenSize = toolkit.getScreenSize();
        int y = screenSize.height;
        return y - 100;
    }
}

Amigo, eu não sei se é necessário eu fazer tudo isso ai para resolver, mas vou tentar…

No meu caso o relatório gerado é um pdf. Minha aplicação busca os dados no banco normal, mas quando ela vai procurar o arquivo jasper dentro do jar para gerar o pdf, ela não encontra.

Mas eu vou tentar sim… obrigado…

Olá.ok…acredito que possa lhe ajudar um pouco, post a solução quando conseguir…abraço.

Amigo, que tipo de arquivo é esse “DadosEmpresa.properties” ?

Dessa linha de código…

FileInputStream caminhoProperties = new FileInputStream("DadosEmpresa.properties");

E quais dados vão nesse arquivo??

Esse “properties”, vc esta pegando os dados do seu javabean ??

Properties properties = ManipularArquivoProperties.lerProperties(caminhoProperties); // necessario para os parametros  
        Map parameters = new HashMap();  
        parameters.put("NOMEEMPRESA", properties.getProperty("nome"));

Pelo que eu verifiquei, vou precisar dessa parte do seu código onde referencia o diretorio do arquivo .jasper com a aplicação.

Estou no aguardo… Obrigado pela força ae.

Olá caceres, isto que me perguntou realmente faz parte de meu projeto onde leio os parametros que preciso enviar para o jasper de um arquivo de propriedades.
no seu caso acredito que não ira precisar, então no caso pode remover estas linhas

             FileInputStream caminhoProperties = new FileInputStream("DadosEmpresa.properties");  
               
         Properties properties = ManipularArquivoProperties.lerProperties(caminhoProperties); // necessario para os parametros  
             Map parameters = new HashMap();  
             parameters.put("NOMEEMPRESA", properties.getProperty("nome")); 

ficando somente

             Map parameters = new HashMap();  

Grato.

Amigo, como vc implanta um projeto desktop?

Vc gera um jar do projeto e coloca no cliente??

Se gera um jar, sua aplicação encontra normalmente o arquivo do relatorio .jasper??

Meu projeto no eclipse roda perfeitamente…

Mas como eu pretendia gerar um jar para deixar no cliente, eu tive esse problema…

Segue meu código q gera o relatorio…

public boolean gerarRelatorioDias(String file, List<Comunicacao_Dias> lista)
    {   
        try 
        {
            String fileName = "Relatorios/RelatorioEMTU.jasper";
            String outFileName = "C:\\Documents and Settings\\All Users\\Desktop\\"+file+".pdf";
            
            HashMap<String, Object> hm = new HashMap<String, Object>();
        	
        	 hm.put("carro", lista.get(0).getCarro());
             hm.put("comunicacao_anterior", lista.get(0).getComunicacao_anterior());
             hm.put("ultima_comunicacao", lista.get(0).getUltima_comunicacao());
             hm.put("dias", lista.get(0).getDias());
             
             JRDataSource jrds = new JRBeanCollectionDataSource(lista);
        	
            // Fill the report using an empty data source
            JasperPrint print = JasperFillManager.fillReport(fileName, hm, jrds);
            
            // Create a PDF exporter
            JRExporter exporter = new JRPdfExporter();
            
            // Configure the exporter (set output file name and print object)
            exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, outFileName);
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
       
            // Export the PDF file
            exporter.exportReport();
            
            //Show the PDF file.
            Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler "+outFileName);
            
            return true;
            
        } 
        catch (JRException e) 
        {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, e.getMessage());
            throw new RuntimeException(e);
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, e.getMessage());
            throw new RuntimeException(e);
        }
    }

Acho q não tem nada de errado… Se vc puder dar uma olhada fazendo um grande favor…

Obrigado…

Eu tive o mesmo problema, na ide tudo funcionava perfeitamente mas quando eu gerava o meu .jar ele não encontrava o caminho do relatorio. Ai eu fiz o seguinte que funcionou:

Primeiro eu pego o caminho do .jasper criando um File assim:

File f = new File("relatorios/SeuRelatorio.jasper"); 

Lembrando que a pasta “relatorios” e uma pasta que vai ficar no mesmo diretorio que o seu .jar.

Ai eu passo esse File para o jasper pegando o caminho completo do arquivo com o metodo getCanonicalPath() assim:

jpt = JasperFillManager.fillReport(f.getCanonicalPath(), parameters, new JRBeanCollectionDataSource(data, false));

Comigo funcionou, não sei se é a melhor solução mas fica ai a dica.

Olá caceres.

Todos os meu relatorios ficam dentro de um pacote dentro da minha aplicação desktop. (dentro do jar mesmo)
sendo assim ao fazer a busca ele pega dentro do projeto(jar), devido a seguinte linha.

 InputStream caminhoRelatorio = this.getClass().getClassLoader().getResourceAsStream("facilcobranca/presentation/relatorio/Administradores.jasper");// caminho do arquivo dentro dos pacotes  

E para implantar o sistema no cliente apenas levo o jar, sendo que dentro dele ja tem os jasper.
Até parece meio estranho colocar os jaspers dentro da aplicação,
mais se você tiver que compilar o jasper e terá que levar ao cliente, acredito que não seria muita diferente que compilar o jar e levar o jar, quase o mesmo trabalho.

E sim, aplicação encontra normalmente os relatórios.

Grato.

Euuuuuuréécaaa…

Valew amigo, esse sharingan faz a diferença hein… hehehe…

Realmente deu certo… Gerei o jar e deixei os arquivos .jasper junto com o jar da minha aplicação… E funcionou certinho…

para quem tiver o mesmo problema segue meu código implementando um relatório através de uma lista de dados e com a solução desse problema…

public boolean gerarRelatorioDias(String file, List<Comunicacao_Dias> lista)
    {   
        try 
        {
            File fileName = new File("Relatorios/RelatorioEMTU.jasper");
            String outFileName = "C:\\Documents and Settings\\All Users\\Desktop\\"+file+".pdf";
            
            HashMap<String, Object> hm = new HashMap<String, Object>();
        	
        	 hm.put("carro", lista.get(0).getCarro());
             hm.put("comunicacao_anterior", lista.get(0).getComunicacao_anterior());
             hm.put("ultima_comunicacao", lista.get(0).getUltima_comunicacao());
             hm.put("dias", lista.get(0).getDias());
             
             JRDataSource jrds = new JRBeanCollectionDataSource(lista);
        	
            // Fill the report using an empty data source
            JasperPrint print = JasperFillManager.fillReport(fileName.getCanonicalPath(), hm, jrds);
            
            // Create a PDF exporter
            JRExporter exporter = new JRPdfExporter();
            
            // Configure the exporter (set output file name and print object)
            exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, outFileName);
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
       
            // Export the PDF file
            exporter.exportReport();
            
            //Show the PDF file.
            Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler "+outFileName);
            
            return true;
            
        } 
        catch (JRException e) 
        {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, e.getMessage());
            throw new RuntimeException(e);
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, e.getMessage());
            throw new RuntimeException(e);
        }
    }

Grato a todos do guj. Quem precisar de ajuda é só pedir tbm…

abraço a todos…