RESOLVIDO: Ajuda para desenvolver um atualizador para meu sistema Java

22 respostas Resolvido
programaçãojavamysql
F

Galera, desenvolvi um sistema em Java desktop (Swing) que está rodando atualmente em no mínimo 30 máquinas (clientes), todas na rede local, constantemente estou fazendo melhorias na minha aplicação e todas as vezes que gero uma nova versão tenho que ir de máquina em máquina com o novo “.jar” num pendrive para substituir a versão antiga.

O que preciso fazer:

  1. Colocar o “.jar” atualizado numa máquina da rede que uso atualmente como servidor;

  2. Informar a nova versão ou no BD ou num xml por exemplo nesta máquina que é o servidor;

  3. Quando as máquinas clientes abrirem o sistema ele consulta a versão do “.jar” em execução e verifica que existe uma nova versão disponível (através da leitura do xml ou do BD no servidor) e informa o usuário que será atualizado;

  4. Neste momento ele fecha o “.jar” em execução, faz o download do “.jar” novo e substitui o “.jar” na máquina do cliente.

  5. Reinicia o sistema já com o “.jar” atualizado.

    Exemplo

Acredito que não servirá só para mim, milhares de usuários serão gratos com esta ajuda, por favor, me ajudem a desenvolvermos juntos.

Obs.: Localizei algumas coisas na Net mas tudo relacionado a Java Web, preciso desenvolver para Java Desktop.

22 Respostas

J

Pode usar Java Web Start na sua rede local.

R

web start nao funciona com o layout absoluto, outra opção é usar o serviço de FTP, clica no button q redireciona lá pro link e salva no pc…

J

O que teria haver Java Web Start com layout?

R

Então, eu também não sei… Mesmo com a biblioteca lá, o programa não abre, diz que tá faltando o driver do layout

J

Deve estar faltando referenciar algum jar.

R

Pior que não, tava tudo certinho

F

Add @ViniGodoy pra nós ajudar nesta empreitada hehe

S

Uma coisa não tem nada a ver com a outra.
Ou faltaram jars no seu classpath ou você esqueceu de assinar digitalmente os mesmos.

Java Web Start é interessante, mas dá muita dor de cabeça devido às restrições de segurança nos browsers.

Antigamente eu atualizava uma aplicação desktop programaticamente.
Havia uma pasta update que estava no início do classpath da aplicação.
Quando a aplicação era inicializada, ela tentava conectar com o servidor de atualizações.
Se havia .class mais recentes no servidor, a aplicação baixava os mesmos pra dentro da pasta update e o sistema era reiniciado.

J

Java Web Start roda fora do browser, é um arquivo que se baixa como qualquer outro. As restrições são do próprio Java.

S

Sim, me expressei mal.

J

Entendi. Não tenho domínio de Java, não sei se seria a melhor opção, mas foi uma sugestão. Pois a equipe que trabalha com Java consegue rodar um client Java de qualquer canto da rede interna usando Java Web Start, com atualização transparente e centralizada. Antes era Applet, que neste caso sim sofreu pela restrição dos browsers.

R

Quando eu inicio a aplicação pelo Netbeans ele abre normal, quando eu faço aquele esquema de compilar tudo em um jar só, junto com as bibliotecas, ele também funciona normal…

Estava tudo setado corretamente

V

Entendi o que vc quer fazer, mas não entendi qual é a dúvida…

F

@ViniGodoy, na verdade não sei nem por onde começar, queria uma ajudinha pra desenvolver essa classe de atualização.

V

Aí fica difícil… Vc espera que a gente poste o código todo?

Comece estudando o que aparenta ser óbvio:

  • Como trabalhar com um xml ou json de configuração
  • Como acessar um serviço de um servidor remoto
  • Como copiar dados no java

Pq para atualizar basta substituir arquivos… isso não é lá muito difícil.

R

Já fiz um atualizador destes a uns anos.
Basicamente me utilizei de um segundo app que faz o trabalho pq n se conseguiria fazer o mesmo jar se sobrepor.
O app do programa baixava o atualizador.jar caso n tinha ainda na máquina, o executava e se fechava, a partir de então o trabalho era do atualizador baixar, trocar a versão e rodar o app novamente.

F

Não, fica tranquilo @ViniGodoy nem quero que vocês façam sozinhos, só gostaria de compartilhar o desenvolvimento junto com alguém que possui mais conhecimento e experiência que eu, só pra receber uns toques, umas dicas, indicação de bibliotecas, etc… o resto é comigo.

F

@Rodrigo_Void você utilizou alguma biblioteca? ou escreveu na unha mesmo? compartilha algo comigo pra eu poder analisar e adaptar pra minha necessidade aqui.

R

Não, nem sei se existe pra isso.
o código é mto simples.
A maior parte do código é a que faz download do arquivo, talvez pra isso possa usar uma lib.

F

Pessoal, deixa comigo, estou quase chegando lá, assim que finalizar posto o código fonte aqui para todos.

F
Solucao aceita

Galera, pegando um pouco da dica de cada um aqui cheguei num resultado satisfatório, rodando tudo conforme eu queria, abaixo vou tentar explicar passo a passo do que foi feito para caso alguém pesquisar sobre o tema consiga essa ajuda adicional.

1-Criei uma nova tabela no meu BD chamada update, nesta tabela eu vou informar a nova versão do sistema a ser atualizada e o caminho em que se encontra o “.jar” atualizado:

CREATE TABLE `update` (
	`cod` INT(11) NOT NULL AUTO_INCREMENT,
	`versao` VARCHAR(50) NOT NULL,
	`origem` VARCHAR(9000) NOT NULL,
	`observacao` VARCHAR(9000) NOT NULL,
	PRIMARY KEY (`cod`)
)

2-No meu sistema principal desenvolvi na classe main um método que consulta na tabela update a nova versão e confronta com a versão do .jar em execução, caso seja igual não faz nada, apenas abre o formulário de login, caso a versão .jar em execução seja diferente da versão informada na tabela update fecho o jar em execução e abro um segundo jar chamado “Updater.jar”.

2.1-Método no main do meu sistema principal que faz a verificação da versão:

Variáveis globais

private static String APP_PATCH = System.getProperties().getProperty("user.dir");//Diretório deste .jar
    private static String VERSAO_ATUAL = "4.7";//Versão deste .jar
    private static String NOVA_VERSAO = "";

No main chamo o método carregaVersao().

Método carregaVersao():

//Carrega os dados da versão presente no BD
    public static void carregaVersao() {
        try {
            Connection conn = Conexao.getConnection();
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery(""
                    + " SELECT versao, origem, observacao "
                    + " FROM `update` "
                    + " ORDER BY cod "
                    + " DESC LIMIT 1");
            while (rs.next()) {
                NOVA_VERSAO = rs.getString("versao");
            }
            st.close();
            rs.close();
            conn.close();

            //Verifica se a versão atual confere com a nova para realizar ou não a atualização
            if (VERSAO_ATUAL.equalsIgnoreCase(NOVA_VERSAO)) {//Mesma versão, 
                new CircleFrameLogin().setVisible(true);//Apenas abre a tela de Login
            } else {//Se as versões forem diferentes
                java.awt.Desktop.getDesktop().open(new File(APP_PATCH + "\\Updater.jar"));//Abre o Updater
                System.exit(0);//Fecha este .jar
                new Control().fecharApp();
            }

        } catch (Exception e) {
            System.err.println("Erro " + e);
        }
    }

Agora vamos pro sistema de atualização, trata-se de um projeto separado, crie um novo projeto para desenvolver este atualizador:

3-No novo projeto crie um JFrame e dentro dele crie algumas variáveis globais e dois métodos:

3.1-Variáveis globais:

private static String APP_PATCH = System.getProperties().getProperty("user.dir");//Diretório deste .jar
private static String NOVA_VERSAO = "";
private static String ORIGEM = "";
private static String OBSERVACAO = "";
SwingWorker worker;

3.2-Agora crie o método carregaVersao()

//Carrega os dados da versão presente no BD
    public void carregaVersao() {
        try {
            Connection conn = Conexao.getConnection();
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery(""
                    + " SELECT versao, origem, observacao "
                    + " FROM `update` "
                    + " ORDER BY cod "
                    + " DESC LIMIT 1");
            while (rs.next()) {
                NOVA_VERSAO = rs.getString("versao");
                ORIGEM = rs.getString("origem");
                OBSERVACAO = rs.getString("observacao");
                txtVersao.setText("Nova versão: " + NOVA_VERSAO);
            }
            st.close();
            rs.close();
            conn.close();
        } catch (Exception e) {
            System.out.println("Erro");
        }
    }

3.3-Agora crie o método copyFile(File source, File destination)

//Método que copia e substitui o arquivo jar
    public static void copyFile(File source, File destination) throws IOException {
        if (destination.exists()) {
            destination.delete();
        }
        FileChannel sourceChannel = null;
        FileChannel destinationChannel = null;
        try {
            sourceChannel = new FileInputStream(source).getChannel();
            destinationChannel = new FileOutputStream(destination).getChannel();
            sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
        } finally {
            if (sourceChannel != null && sourceChannel.isOpen()) {
                sourceChannel.close();
            }
            if (destinationChannel != null && destinationChannel.isOpen()) {
                destinationChannel.close();
            }
        }
    }

4-Agora no inicializador do formulário você chama os métodos:

public formUpdate() {
        initComponents();
        carregaVersao();

System.out.println("Começou");
        worker = new SwingWorker() {
            @Override
            protected Object doInBackground() throws Exception {
                try {
                    //Thread.sleep(5000);
                    File source = new File(ORIGEM);
                    File destination = new File(APP_PATCH + "\\PCP.jar");
                    copyFile(source, destination);
                } catch (IOException ex) {
                    Logger.getLogger(formUpdate.class.getName()).log(Level.SEVERE, null, ex);
                }
                return null;
            }

            @Override
            public void done() {
                try {
                    System.out.println("Finalizou a atualização");
                    java.awt.Desktop.getDesktop().open(new File(APP_PATCH + "\\PCP.jar"));//Abre o Updater
                    worker.cancel(true);
                    System.exit(0);
                    new Control().fecharApp();
                } catch (IOException ex) {
                    Logger.getLogger(formUpdate.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        worker.execute();
    }

É isso, espero que ajude quem precisar, obrigado @rodriguesabner, @ViniGodoy, @staroski, @javaflex

D

bom dia, fim um atualizador com base neste seu exemplo, ele trava e nao faz nada, poderia me dar uma mao?

Criado 17 de junho de 2018
Ultima resposta 12 de jan. de 2025
Respostas 22
Participantes 7