Como implementar um software atualizavel

25 respostas
E

Bom dia meus caros,

Vou começar a dar manutenção agora em um sofware legado. É um software instalado localmente, e que sincroniza dados via internet periodicamente.

A questão é: Minha primeira demanda é fazer com que o software identifique quando houver uma versão nova do mesmo em um repositório online, e faça um auto-update, baixando e substituindo os arquivos que foram alterados.

Alguém poderia me indicar por onde começar… uma ferramenta ou framework que possa me ajudar nessa tarefa. Sempre fui programador WEB, estou um pouco perdido aqui.

Grato,
Diego

25 Respostas

D

JNLP (java web start)?

E

Não não, é uma aplicação isntalada localmente, implementada com swt, e que sincroniza dados periodicamente com um banco de dados online.

O que eu preciso é uma forma de fazer a aplicação saber quando existe uma versão mais nova, e realizar um auto-update, baixando e substituindo os arquivos alterados.

M

Não não, é uma aplicação isntalada localmente, implementada com swt, e que sincroniza dados periodicamente com um banco de dados online.

O que eu preciso é uma forma de fazer a aplicação saber quando existe uma versão mais nova, e realizar um auto-update, baixando e substituindo os arquivos alterados.

O que é que você quer atualizar, o software ou o banco?

D

Não não, é uma aplicação isntalada localmente, implementada com swt, e que sincroniza dados periodicamente com um banco de dados online.

O que eu preciso é uma forma de fazer a aplicação saber quando existe uma versão mais nova, e realizar um auto-update, baixando e substituindo os arquivos alterados.

O que é que você quer atualizar, o software ou o banco?
Ele quer atualizar o software…

M

Sei. Ele pode também usar uma aplicação separada que de tempos em tempos se comunica com um servidor perguntando se tem atualização. Se tiver ele baixa e substitui os arquivos. A aplicação poderia se conectar a um web service que forneça as atualizações. Bom, eu nunca usei esse JNLP, ele faz isso que eu falei?

D

Não, JNLP é uma solução na qual se desenvolve a aplicação, cria-se o jar e disponibiliza-a através de um link na internet.
O acesso à mesma é feito através de um navegador e podemos configurar para atualizar (baixar um novo jar) quando houver disponibilidade.

E

Não não, é uma aplicação isntalada localmente, implementada com swt, e que sincroniza dados periodicamente com um banco de dados online.

O que eu preciso é uma forma de fazer a aplicação saber quando existe uma versão mais nova, e realizar um auto-update, baixando e substituindo os arquivos alterados.

O que é que você quer atualizar, o software ou o banco?
Ele quer atualizar o software…

Exatamente, quero atualizar o software

E

drsmachado:
Não, JNLP é uma solução na qual se desenvolve a aplicação, cria-se o jar e disponibiliza-a através de um link na internet.
O acesso à mesma é feito através de um navegador e podemos configurar para atualizar (baixar um novo jar) quando houver disponibilidade.

Pois é, acredito que nesse caso ja não iria servir. Pois preciso que a própria aplicação identifique que existe uma atualização e faça o update.
A ideia de fazer um outro software que monitore e faça o download é mais ou menos o que eu tinha imaginado, poderia rodar a aplicação silenciosamente quando o usuário clicasse no executavel…

Existe algum framework ou tecnologia que facilite isso? Ou uma forma simples de implementar?

A

Você está usando SWT puro ou em cima da Plataforma Eclipse? Se estiver usando a Plataforma Eclipse, ela fornece mecanismos de atualização dos plugins nativamente. Basta você mapear o update site e manter ele atualizado.

E

Estou usando puro. Na verdade usei apenas os componentes visuais do SWT. O que eu quero é poder atualizar os jars da aplicação quando necessário, e o executavel, quando for feita uma nova compilação do software.

M

ezaack:
drsmachado:
Não, JNLP é uma solução na qual se desenvolve a aplicação, cria-se o jar e disponibiliza-a através de um link na internet.
O acesso à mesma é feito através de um navegador e podemos configurar para atualizar (baixar um novo jar) quando houver disponibilidade.

Pois é, acredito que nesse caso ja não iria servir. Pois preciso que a própria aplicação identifique que existe uma atualização e faça o update.
A ideia de fazer um outro software que monitore e faça o download é mais ou menos o que eu tinha imaginado, poderia rodar a aplicação silenciosamente quando o usuário clicasse no executavel…

Existe algum framework ou tecnologia que facilite isso? Ou uma forma simples de implementar?

Rapaz, depende muito de como tu pretende disponibilizar as atualizações. Mas chutando uma possível solução, tu poderia fazer um programa que verifica a disponibilidade da atualização e caso haja faz o download da mesma via FTP e depois atualiza os arquivos nos locais devidos. Se for o caso tu pode até criar um serviço no windows que verifique essas atualizações.

D

A primeira coisa a fazer é distribuir teu software em várias partes. Isso fará com que você tenha partes distintas que podem ser atualizadas de forma independente.
A segunda é definir uma estratégia de atualização (lembrando que você deve considerar os riscos e permitir que um “downgrade” seja possível).

W

Eu fiz isto para uma aplicação Android, ela é fechada e não pode ser disponibilizada no Play. Basicamente, ao iniciar, uma thread busca novas versões num servidor ftp (comparando número de versões). Caso exista, ela faz o download pro aparelho e, quando terminar, notifica o usuário para atualizar. No Android isto é mais simples porque esta parte de “substituir” a antiga versão é feita automaticamente, uma vez que eu mando abrir o aplicativo baixado.

A aplicação que eu fiz é offline, então eu preciso executar estas tarefas de atualizações somente se houver internet disponível. A atualização só deve ser executada se o usuário quiser (ele pode estar fazendo outra coisa e preferir atualizar depois). O “inconveniente” deste caso é que eu preciso suportar um upgrade de qualquer versão para a nova -por exemplo, ele pode estar na versão 1 e subir para a 5, sendo que tudo o que foi feito na 2, 3 e 4 precisa estar disponível - o que é um pouco chato quando se usa um banco de dados local e precisa atualizá-lo.

No caso do Android eu sempre atualizo a aplicação inteira. Não atualizo somente partes, fica bem mais simples. Será que no teu caso não tem como fazer isto também? Com que frequência tu precisa atualizar esta aplicação?

D

wagnerfrancisco:
Eu fiz isto para uma aplicação Android, ela é fechada e não pode ser disponibilizada no Play. Basicamente, ao iniciar, uma thread busca novas versões num servidor ftp (comparando número de versões). Caso exista, ela faz o download pro aparelho e, quando terminar, notifica o usuário para atualizar. No Android isto é mais simples porque esta parte de “substituir” a antiga versão é feita automaticamente, uma vez que eu mando abrir o aplicativo baixado.

A aplicação que eu fiz é offline, então eu preciso executar estas tarefas de atualizações somente se houver internet disponível. A atualização só deve ser executada se o usuário quiser (ele pode estar fazendo outra coisa e preferir atualizar depois). O “inconveniente” deste caso é que eu preciso suportar um upgrade de qualquer versão para a nova -por exemplo, ele pode estar na versão 1 e subir para a 5, sendo que tudo o que foi feito na 2, 3 e 4 precisa estar disponível - o que é um pouco chato quando se usa um banco de dados local e precisa atualizá-lo.

No caso do Android eu sempre atualizo a aplicação inteira. Não atualizo somente partes, fica bem mais simples. Será que no teu caso não tem como fazer isto também? Com que frequência tu precisa atualizar esta aplicação?


A questão é que atualizações completas em softwares não mobile podem ser um problema. Ainda mais se forem muito grandes.
Modularizar permite que parte da aplicação seja atualizada.
Ele pode disponibilizar o jar funcional e quando a aplicação for iniciada, verificar se há atualização, havendo, ela só faz o download, renomeia o .jar antigo (compras.jar.old) e copia o novo jar para o lugar do antigo. Ao invés de 100MB, apenas 5MB e menos dor de cabeça se for preciso realizar downgrade…

A

Outro ponto que se deve tomar cuidado é que você precisa definir o que fazer após a atualização. Você tem, basicamente, duas opções:

1- Reiniciar a aplicação (ou solicitar ao usuário que o faça)
2- Carregar as classes do jar atualizado novamente

O Eclipse, por exemplo, utiliza a segunda opção sempre que possível, mas ela dá um trabalho considerável para você implementar do zero.

M

drsmachado:

A questão é que atualizações completas em softwares não mobile podem ser um problema. Ainda mais se forem muito grandes.
Modularizar permite que parte da aplicação seja atualizada.
Ele pode disponibilizar o jar funcional e quando a aplicação for iniciada, verificar se há atualização, havendo, ela só faz o download, renomeia o .jar antigo (compras.jar.old) e copia o novo jar para o lugar do antigo. Ao invés de 100MB, apenas 5MB e menos dor de cabeça se for preciso realizar downgrade…

Nesse caso creio que usar alguma coisa baseada na arquitetura OSGI irá facilitar a vida dele. Fazer uma aplicação baseada em Eclipse ou Netbeans talvez seja a solução. Agora mesmo facilitando ainda dá um bocado de trabalho. Pricipalmente porque nem sabemos se o software que ele fez foi projetado para ser atualizável.

E

drsmachado:
A primeira coisa a fazer é distribuir teu software em várias partes. Isso fará com que você tenha partes distintas que podem ser atualizadas de forma independente.
A segunda é definir uma estratégia de atualização (lembrando que você deve considerar os riscos e permitir que um “downgrade” seja possível).

Comecei a desenvolver um atualizador que segue mais ou menos esse principio, mas ainda estou bem no inicio. No caso optei com gerar um rash de todos os arquivos do sistema(jar, executaveis, bancos embarcados, etc), e armazar esse rash em um xml que mapeia a localização dos arquivos. Então, quando o usuário iniciar o programa ele starta o atualizador primeiro, semelhante um cliente de MMO por exemplo. Se houver internet ele vai baixar o xml de um ftp, e comprar os rashs. Os que estiverem diferentes ele faz o download do respectivo arquivo, verifica se esta ok(não corrompeu), substitui o antigo e atualiza o xml. Então o atualizador starta o sistema ja atualizado e fecha.

Uma vez iniciado o sistema verificará se existe atualização do atualizador, num processo parecido.

Se alguem tiver dicas para facilitar o desenvolvimento, ou achar que não é uma boa estratégia, por favor, contribua =D

Grato a todos,
Diego

W

drsmachado:
wagnerfrancisco:
Eu fiz isto para uma aplicação Android, ela é fechada e não pode ser disponibilizada no Play. Basicamente, ao iniciar, uma thread busca novas versões num servidor ftp (comparando número de versões). Caso exista, ela faz o download pro aparelho e, quando terminar, notifica o usuário para atualizar. No Android isto é mais simples porque esta parte de “substituir” a antiga versão é feita automaticamente, uma vez que eu mando abrir o aplicativo baixado.

A aplicação que eu fiz é offline, então eu preciso executar estas tarefas de atualizações somente se houver internet disponível. A atualização só deve ser executada se o usuário quiser (ele pode estar fazendo outra coisa e preferir atualizar depois). O “inconveniente” deste caso é que eu preciso suportar um upgrade de qualquer versão para a nova -por exemplo, ele pode estar na versão 1 e subir para a 5, sendo que tudo o que foi feito na 2, 3 e 4 precisa estar disponível - o que é um pouco chato quando se usa um banco de dados local e precisa atualizá-lo.

No caso do Android eu sempre atualizo a aplicação inteira. Não atualizo somente partes, fica bem mais simples. Será que no teu caso não tem como fazer isto também? Com que frequência tu precisa atualizar esta aplicação?


A questão é que atualizações completas em softwares não mobile podem ser um problema. Ainda mais se forem muito grandes.
Modularizar permite que parte da aplicação seja atualizada.
Ele pode disponibilizar o jar funcional e quando a aplicação for iniciada, verificar se há atualização, havendo, ela só faz o download, renomeia o .jar antigo (compras.jar.old) e copia o novo jar para o lugar do antigo. Ao invés de 100MB, apenas 5MB e menos dor de cabeça se for preciso realizar downgrade…

Pois é, é preciso verificar o tamanho da aplicação e a frequência de atualização…

A

O problema é que implementar OSGi corretamente em um sistema legado é muito caro. Seria bacana em um processo de reescrita do software.

A

ezaack:
drsmachado:
A primeira coisa a fazer é distribuir teu software em várias partes. Isso fará com que você tenha partes distintas que podem ser atualizadas de forma independente.
A segunda é definir uma estratégia de atualização (lembrando que você deve considerar os riscos e permitir que um “downgrade” seja possível).

Comecei a desenvolver um atualizador que segue mais ou menos esse principio, mas ainda estou bem no inicio. No caso optei com gerar um rash de todos os arquivos do sistema(jar, executaveis, bancos embarcados, etc), e armazar esse rash em um xml que mapeia a localização dos arquivos. Então, quando o usuário iniciar o programa ele starta o atualizador primeiro, semelhante um cliente de MMO por exemplo. Se houver internet ele vai baixar o xml de um ftp, e comprar os rashs. Os que estiverem diferentes ele faz o download do respectivo arquivo, verifica se esta ok(não corrompeu), substitui o antigo e atualiza o xml. Então o atualizador starta o sistema ja atualizado e fecha.

Uma vez iniciado o sistema verificará se existe atualização do atualizador, num processo parecido.

Se alguem tiver dicas para facilitar o desenvolvimento, ou achar que não é uma boa estratégia, por favor, contribua =D

Grato a todos,
Diego

Somente se atente se o software foi iniciado com os jars atualizáveis no classpath. Se for, a atualização pode não surtir efeito porque as classes atualizadas já podem ter sido carregadas antes da atualização.

E

Ataxexe:
ezaack:
drsmachado:
A primeira coisa a fazer é distribuir teu software em várias partes. Isso fará com que você tenha partes distintas que podem ser atualizadas de forma independente.
A segunda é definir uma estratégia de atualização (lembrando que você deve considerar os riscos e permitir que um “downgrade” seja possível).

Comecei a desenvolver um atualizador que segue mais ou menos esse principio, mas ainda estou bem no inicio. No caso optei com gerar um rash de todos os arquivos do sistema(jar, executaveis, bancos embarcados, etc), e armazar esse rash em um xml que mapeia a localização dos arquivos. Então, quando o usuário iniciar o programa ele starta o atualizador primeiro, semelhante um cliente de MMO por exemplo. Se houver internet ele vai baixar o xml de um ftp, e comprar os rashs. Os que estiverem diferentes ele faz o download do respectivo arquivo, verifica se esta ok(não corrompeu), substitui o antigo e atualiza o xml. Então o atualizador starta o sistema ja atualizado e fecha.

Uma vez iniciado o sistema verificará se existe atualização do atualizador, num processo parecido.

Se alguem tiver dicas para facilitar o desenvolvimento, ou achar que não é uma boa estratégia, por favor, contribua =D

Grato a todos,
Diego

Somente se atente se o software foi iniciado com os jars atualizáveis no classpath. Se for, a atualização pode não surtir efeito porque as classes atualizadas já podem ter sido carregadas antes da atualização.

Mas nesse caso o atualizador seria um sistema separado, inciado antes da aplicação. O sistema principal só seria estartado após a atualização. E quanto a reescrever o sistema para modulariza-lo é algo fora de questão, infelizmente.

A

ezaack:
Ataxexe:
ezaack:
drsmachado:
A primeira coisa a fazer é distribuir teu software em várias partes. Isso fará com que você tenha partes distintas que podem ser atualizadas de forma independente.
A segunda é definir uma estratégia de atualização (lembrando que você deve considerar os riscos e permitir que um “downgrade” seja possível).

Comecei a desenvolver um atualizador que segue mais ou menos esse principio, mas ainda estou bem no inicio. No caso optei com gerar um rash de todos os arquivos do sistema(jar, executaveis, bancos embarcados, etc), e armazar esse rash em um xml que mapeia a localização dos arquivos. Então, quando o usuário iniciar o programa ele starta o atualizador primeiro, semelhante um cliente de MMO por exemplo. Se houver internet ele vai baixar o xml de um ftp, e comprar os rashs. Os que estiverem diferentes ele faz o download do respectivo arquivo, verifica se esta ok(não corrompeu), substitui o antigo e atualiza o xml. Então o atualizador starta o sistema ja atualizado e fecha.

Uma vez iniciado o sistema verificará se existe atualização do atualizador, num processo parecido.

Se alguem tiver dicas para facilitar o desenvolvimento, ou achar que não é uma boa estratégia, por favor, contribua =D

Grato a todos,
Diego

Somente se atente se o software foi iniciado com os jars atualizáveis no classpath. Se for, a atualização pode não surtir efeito porque as classes atualizadas já podem ter sido carregadas antes da atualização.

Mas nesse caso o atualizador seria um sistema separado, inciado antes da aplicação. O sistema principal só seria estartado após a atualização. E quanto a reescrever o sistema para modulariza-lo é algo fora de questão, infelizmente.

Então não creio que terá problemas. É uma boa forma de se atualizar o software.

Você pode, também, fazer uma verificação de atualização não no início do sistema, mas no decorrer do seu uso e, caso seja necessário atualizar, grave essa informação em um arquivo que será lido na próxima vez que o usuário iniciar o sistema. Dessa forma você minimiza o tempo necessário para inicialização caso não haja atualizações. Um bônus seria poder notificar o usuário da atualização e até reiniciar o sistema para que ela seja feita (se o usuário escolher fazer isso, claro), dá um toque legal.

E

Ataxexe:
ezaack:
Ataxexe:
ezaack:
drsmachado:
A primeira coisa a fazer é distribuir teu software em várias partes. Isso fará com que você tenha partes distintas que podem ser atualizadas de forma independente.
A segunda é definir uma estratégia de atualização (lembrando que você deve considerar os riscos e permitir que um “downgrade” seja possível).

Comecei a desenvolver um atualizador que segue mais ou menos esse principio, mas ainda estou bem no inicio. No caso optei com gerar um rash de todos os arquivos do sistema(jar, executaveis, bancos embarcados, etc), e armazar esse rash em um xml que mapeia a localização dos arquivos. Então, quando o usuário iniciar o programa ele starta o atualizador primeiro, semelhante um cliente de MMO por exemplo. Se houver internet ele vai baixar o xml de um ftp, e comprar os rashs. Os que estiverem diferentes ele faz o download do respectivo arquivo, verifica se esta ok(não corrompeu), substitui o antigo e atualiza o xml. Então o atualizador starta o sistema ja atualizado e fecha.

Uma vez iniciado o sistema verificará se existe atualização do atualizador, num processo parecido.

Se alguem tiver dicas para facilitar o desenvolvimento, ou achar que não é uma boa estratégia, por favor, contribua =D

Grato a todos,
Diego

Somente se atente se o software foi iniciado com os jars atualizáveis no classpath. Se for, a atualização pode não surtir efeito porque as classes atualizadas já podem ter sido carregadas antes da atualização.

Mas nesse caso o atualizador seria um sistema separado, inciado antes da aplicação. O sistema principal só seria estartado após a atualização. E quanto a reescrever o sistema para modulariza-lo é algo fora de questão, infelizmente.

Então não creio que terá problemas. É uma boa forma de se atualizar o software.

Você pode, também, fazer uma verificação de atualização não no início do sistema, mas no decorrer do seu uso e, caso seja necessário atualizar, grave essa informação em um arquivo que será lido na próxima vez que o usuário iniciar o sistema. Dessa forma você minimiza o tempo necessário para inicialização caso não haja atualizações. Um bônus seria poder notificar o usuário da atualização e até reiniciar o sistema para que ela seja feita (se o usuário escolher fazer isso, claro), dá um toque legal.

Muito boa a ideia, acho q vai ser interessante. O cliente deu a entender que a atualização deveria ser algo um pouco foçado, ja que esse sistema esta a integrado a outros, e todos devem estar em sintonia, mas vou levantar a questão com ele =)

D

acho que a lógica é essa:

1- no servidor você lança a nova versão com todos os arquivos
2- usuário clica no jar que na verdade é um atualizador.
3- o atualizador faz uma requisição http para o servidor e verifica se versão do servidor > versão atual e se Atualizacao == Obrigatoria, se sim, atualizador solicita permissão para atualização
4- Se usuário clica em Sim -> faz uma cópia da aplicação atual e salva em um diretório chamado backup(versao), e salva o diretório original em uma variavel.
5- Se usuário clica em Não e Atualização == Obrigatória, informa mensagem para o usuário dizendo que só é possivel utilizar a aplicação após a atualização (usuário neste caso deveria manter conexão com internet, ou ele continuaria usando a versão antiga do programa.)
6- Servidor compara o Hash e verifica se existem arquivos novos, se sim calcula o total em Mb de todos os arquivos, coloca uma barra de progresso conforme o usuário vai baixando, calcula quantidade de Mbps e coloca um tempo de duração.
7- após toda cópia ele faz uma busca recursiva gerando hash de todos os arquivos que foram copiados, e compara os mesmos com o servidor.

8- durante todo o processo de atualização o sistema faz try-Catch e caso ocorra excessão em qualquer ponto salva em um arquivo (atualizacao).log, envia um post para o servidor contendo a exception/ou e-mail, e mais importe, exclui os arquivos da instalação FAIL e volta o diretório backup(versao) para o diretório original.

eu faria esse feijão com arros, outra forma de se fazer é Zipar a aplicação dividir com o winRar em partes minusculas, e salvar toda a nova versão em um diretório, depois você só renomeia a versão antiga e coloca a nova no lugar em seguida Descompacta os arquivos…dessa forma se o usuário cancelar/internet cair sei la, você apenas compara o hash do ultimo arquivo e se estiver OK você continua a cópia.

J

O que normalmente eu utilizo nos meus projetos para resolver esse tipo de problema(poder atualizar partes críticas de um sistema) é criar uma arquitetura modular(de plugins) usando reflections do java. É possível implementar as partes totalmente desacopladas da aplicação.

Um exemplo é um software de cftv no qual o driver de cada câmera é um jar a parte como um plugin. Você coloca numa pasta e o sistema encontra o mais adequado para a reprodução de cada câmera.

Criado 21 de agosto de 2013
Ultima resposta 23 de ago. de 2013
Respostas 25
Participantes 7