Modificar e atualizar código fonte enquanto a aplicação estiver rodando

Olá pessoal, tudo certo?

É o seguinte, me surgiu um questionamento aqui e não sei bem certo onde procurar a resposta (onde procurei não encontrei nada concreto).

Estou usando a IDE Netbeans 8.2, JDK 8 e estou em fase de desenvolvimento de uma aplicação desktop, aí eu realizo uma modificação e/ou atualização no código fonte e toda vez preciso executar a aplicação novamente. A dúvida é a seguinte, há alguma maneira de fazer com que ao modificar o código fonte e a aplicação já estiver executando eu não precisar fechá-la e executar novamente? Ou seja, que ela pegue a modificação em tempo real de execução? (Isto se tratando da execução através da IDE).

Pode parecer um questionamento bobo, me parece até que já tinha lido que isso não é possível de maneira nenhuma, mas fiquei com essa “pulga atrás da orelha” e por isso estou perguntando.

Agradeço se me passarem o feedback de vocês.

:grinning:

Não.
Java é uma linguagem estática e depois de compilado vc tem que recompilar o código fonte.

O mais próximo disso que eu conheço é o xss, só que com javascript, ou seja em aplicacao web.

Em js vc pode transformar string em uma função.
Isso é o equivalente à mudar o comportamento da aplicação.

JavaScript é uma linguagem tipo lego se vc entender JSON.
Da pra fazem umas “músicas”/composições mas como hobby.

Imagine uma aplicação que possa analisar, excluir e modificar seus próprios métodos.

Eu não faço idéia de como construir isso, mais o js permite tal comportamento.

3 curtidas

Qual a necessidade disso?

Realmente o Javascript é meio doidão. Isso que você quer, vc pode fazer usando Electron (Javascript), enquanto for salvando, pode ver o resultado.

2 curtidas

Eu não conheço muito o Netbeans, mas será que não dava para você customizar os atalhos?

Por exemplo, normalmente o Ctrl+S salva as modificações. Vc poderia alterar este atalho para além de salvar o documento atual, reexecutar a sua aplicação.

1 curtida

O atalho é F5, por default, salva e compila.
Pelo que compreendi, ele queria saber se era possível modificar o bytecode em tempo de execução, exportar e aproveitar essa mudança na instância da aplicação em execução.
Somente aplicações semelhantes ao JS permitem mudar o comportamento em tempo de execução.

Por exemplo, vc cria um servidor, na camada cliente digita uma função em string, manda pro servidor e redireciona para os outros clientes.

XSS não é recomendado, por isso eu disse que isso seria apenas um hobby.

2 curtidas

Se for desktop use Electron que não vai ter esse problema.

1 curtida

Para web o play framework faz algo parecido com o que você quer.

Tem também o JRebel que faz reload de bytecode automaticamente, mas não sei se atende seu caso ou é o suficiente.

O maior problema que vejo nem é o bytecode em si, mas os valores armazenados nas classes. Imagine que você tem uma classe Pessoa com nome e sobrenome, você adiciona um novo atributo nessa classe, como essa ferramenta faria para transferir os dados da versão nova para a antiga?

1 curtida

Em Java, diretamente, não. Porém, há algumas opções que dão bastante flexibilidade nesse sentido:

Você pode criar diferentes class loaders
Que é como se você possuísse diferentes “VMs” rodando grupos de classes diferentes, que podem ser carregadas em tempo de execução. É isso que um servidor web faz, por exemplo, para poder carregar diferentes serviços sem que o servidor tenha que ser reiniciado.

Mais informações: https://www.baeldung.com/java-classloaders

Você pode utilizar a API de scripts
E integrar scripts escritos numa linguagem como JavaScript, Groovy ou Kotlin. Scripts podem ser carregados, compilados e executados em tempo de execução. Mais informações: https://docs.oracle.com/javase/7/docs/technotes/guides/scripting/programmer_guide/

Você pode usar APIs para isso

Como o JRebel, já citado pelo Abel.

2 curtidas

Primeiro, obrigada a todos pelas sugestões e respostas.

O que mais se encaixou com o que eu quero é a resposta do ViniGodoy.

Então ViniGodoy, dei uma pesquisada rápida nos classloaders, mas não achei nenhum exemplo concreto de como usá-los para o que eu quero, que no caso é rodar a minha aplicação, ir alterando o código fonte e atualizando a mesma em tempo de execução e então já poder ver o efeito da modificação sem ter que fechar a aplicação e compilar novamente. Você tem mais algum material que possa me indicar?

Acabei dando uma olhada também no JRebel e acredito que seja mesmo a solução para a minha dúvida, mas pelo que vi o mesmo é pago, há alguma alternativa ?

Grata.

1 curtida

Acho que o que você quer vai ser mais facilmente obtido ou com scripts, ou com o JRebel mesmo. Os classloaders permitem que você carregue novas classes em tempo de execução, mas não que as modifique (a menos que vc descarte um classloader e carregue outro).

Por que exatamente vc precisa disso? Qual é o seu objetivo? Talvez se entendermos melhor o seu problema, possamos te ajudar melhor.

Realmente NetBeans até então não tem a opção para fazer isso.

Agora se você pretende criar sua propria IDE ou fazer um plugin e nele colocar esse recurso, tem que considerar algumas coisas :

Estando todo o programa já rodando na memoria tem que pensar em como de fora violar a segurança da JVM pra fazer isso, se você tem dentro do seu programa um modulo que invoca Class Loaders é uma coisa.

Existem alguns projetos em curso para carregamento dinamico de modulos no java >= 9.

Se você tem um programa já rodando na memoria e deseja atualizar ele depois de compilar os fontes, mais facil seria fazer um plugin pra tirar o que esta rodando na memoria e chamar novamente o programa.

2 curtidas