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.