Esta é uma página de visão geral, visite hotswapagent.org para obter mais informações.
Classe de tempo de execução ilimitada Java e redefinição de recursos.
O objetivo principal deste projeto era eliminar a necessidade do tradicional ciclo de desenvolvimento "alterar código -> reiniciar e esperar... -> verificar". Com o tempo, esse conceito evoluiu para um novo paradigma dentro do ecossistema Java, permitindo o desenvolvimento de software em tempo real dentro de um aplicativo em execução. Essa abordagem é viável até mesmo em ambientes restritos, como contêineres Docker.
Se você for um usuário do IntelliJ, poderá simplificar a configuração de HA e DCEVM usando o plug-in IntelliJ HotSwapHelper.
Baixe e instale:
Para Java 17/21: Baixe o JBR17 ou JBR21 mais recente. Como essas versões não incluem um agente Hotswap integrado, você precisará copiar manualmente hotswap-agent.jar
para a pasta lib/hotswap
. Você pode encontrar o agente Hotswap mais recente aqui. Certifique-se de que o arquivo na pasta lib/hotswap
seja denominado hotswap-agent.jar
sem nenhum número de versão no nome do arquivo.
Para Java 11: Use TravaJDK, que possui um HotswapAgent integrado, e instale-o como um JDK alternativo. Alternativamente, o TravaJDK inclui um HotswapAgent integrado.
Para Java 8: Use jdk8-dcevm junto com o HotswapAgent.
Modos HotswapAgent:
A partir de dcevm-11.0.9
, o HotswapAgent está desabilitado por padrão. Você pode ativar o suporte para HotswapAgent usando opções JVM em um dos três modos:
O modo HotswapAgent=core
opera sem plug-ins adicionais, exceto para plug-ins JVM principais, resultando em desempenho mais rápido devido à redução de tarefas de digitalização e cópia de classe. Para usar plug-ins adicionais, você precisa configurá-los como dependências do Maven em seu arquivo pom.xml
. Por outro lado, o modo HotswapAgent=fatjar
inclui todos os plugins por padrão, o que pode retardar um pouco a inicialização do aplicativo.
-XX:HotswapAgent=fatjar
ativa o fatjar HotswapAgent interno.
-XX:HotswapAgent=core
ativa o núcleo interno HotswapAgent.
-XX:HotswapAgent=external
configura o suporte JVM para HotswapAgent e permite que o usuário forneça um hotswap-agent.jar
externo usando a opção -javaagent:
.
3. Lançamento:
Java17/21: inicie seu aplicativo com as opções -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar
para ativar o hotswap avançado (dcevm) e usar a versão fatjar do agente Hotswap. Como alternativa, modos core
ou external
podem ser usados em vez de fatjar
.
Java11: inicie seu aplicativo com as opções -XX:HotswapAgent=fatjar
para usar a versão fatjar do Hotswap Agent.
Java8: inicie seu aplicativo com as opções -XXaltjvm=dcevm -javaagent:hotswap-agent.jar
para obter uma configuração básica. Opcionalmente, você pode adicionar hotswap-agent.properties
ao seu aplicativo para configurar plug-ins e comportamento do agente.
3.Execute seu aplicativo:
Inicie o aplicativo em modo de depuração, verifique se o agente e os plugins foram inicializados corretamente:
HOTSWAP AGENT: 9:49:29.548 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent - unlimited runtime class redefinition. HOTSWAP AGENT: 9:49:29.725 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [org.hotswap.agent.plugin.hotswapper.HotswapperPlugin, org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin, org.hotswap.agent.plugin.hibernate.HibernatePlugin, org.hotswap.agent.plugin.spring.SpringPlugin, org.hotswap.agent.plugin.jetty.JettyPlugin, org.hotswap.agent.plugin.tomcat.TomcatPlugin, org.hotswap.agent.plugin.zk.ZkPlugin, org.hotswap.agent.plugin.logback.LogbackPlugin] ... HOTSWAP AGENT: 9:49:38.700 INFO (org.hotswap.agent.plugin.spring.SpringPlugin) - Spring plugin initialized - Spring core version '3.2.3.RELEASE'
4.Verifique a redefinição
Salve um recurso alterado e/ou use o recurso HotSwap do seu IDE para recarregar as alterações
Cada estrutura de aplicação (Spring, Hibernate, Logback, ...) precisa de um mecanismo especial de recarregamento para se manter atualizado após a redefinição da classe (por exemplo, recarregamento da configuração do Hibernate após a introdução de uma nova classe de entidade). O agente Hotswap funciona como um sistema de plugins e é fornecido pré-configurado com todos os principais plugins do framework. É fácil escrever seu plugin personalizado, mesmo como parte de seu aplicativo.
Este projeto é muito complexo devido a muitos frameworks suportados e várias versões. A contribuição comunitária é obrigatória para mantê-lo vivo. Você pode começar criando um plugin dentro de sua aplicação ou escrevendo um exemplo/teste de integração. Sempre há necessidade de melhorias na documentação :-). Obrigado por qualquer ajuda!
Java Hotswap aprimorado - alterar o corpo do método, adicionar/renomear um método, campo, ... A única operação não suportada é alterar a superclasse.
Você pode usar o Java Hotswap padrão do IDE no modo de depuração para recarregar a classe alterada
ou defina a propriedade autoHotswap -XXaltjvm=dcevm -javaagent:PATH_TO_AGENThotswap-agent.jar=autoHotswap=true
para recarregar as classes alteradas após a compilação. Esta configuração permite até mesmo recarregar em um sistema de produção sem reiniciar.
Configuração automática - todas as classes e recursos locais, conhecidos pelo aplicativo Java em execução, são automaticamente descobertos e observados para recarregamento (todos os arquivos no sistema de arquivos local, não dentro de qualquer arquivo JAR).
Caminho de classe extra - Precisa alterar uma classe de tempo de execução dentro do JAR dependente? Use a propriedade extraClasspath para adicionar qualquer diretório como caminho de classe para observar arquivos de classe.
Recarregar recurso após uma alteração - os recursos do diretório webapp geralmente são recarregados pelo servidor de aplicativos. Mas e outros recursos como src/main/resources? Use a propriedade watchResources para adicionar qualquer diretório para observar uma alteração de recurso.
Suporte de framework - através do sistema de plugins, muitos frameworks são suportados. Novos plugins podem ser facilmente adicionados.
Rápido - até que o plugin seja inicializado, ele não consome nenhum recurso nem torna o aplicativo lento (consulte Sobrecarga de tempo de execução para obter mais informações)
Se você tiver algum problema ou dúvida, pergunte no fórum HotswapAgent.
Este projeto é semelhante ao JRebel. As principais diferenças são:
HotswapAgent (DCEVM) suporta Java8, Java11 e Java17!
HotswapAgent não precisa de nenhuma configuração adicional para configuração básica do projeto.
JRebel está atualmente mais maduro e contém mais plugins.
JRebel não é de código aberto nem gratuito.
JRebel modifica o bytecode de todas as classes ao recarregar. Você precisa de um plugin IDE especial para corrigir a depuração.
HotswapAgent extraClasspath é semelhante à configuração do JRebel
HotswapAgent adiciona configuração watchResources
Consulte o projeto HotswapAgentExamples GitHub. O objetivo de um aplicativo de exemplo é:
complexos testes de integração automatizados (verifique várias configurações antes de um lançamento, consulte o script run-tests.sh
)
para verificar o uso do plugin no "mundo real" durante o desenvolvimento do plugin (ou seja, dentro de um contêiner)
para fornecer uma solução funcional para configurações típicas de aplicativos
sandbox para simular problemas em configurações existentes ou novas
Sinta-se à vontade para bifurcar/ramificar e criar um aplicativo para sua configuração (funcional, mas o mais simples possível). As configurações gerais serão mescladas no master.
Não é necessário :) Sério! Todas as alterações são transparentes e tudo que você precisa fazer é baixar o patch+agente e configurar seu aplicativo/servidor de aplicativos. Como usamos o comportamento hotswap java padrão, seu IDE funcionará conforme o esperado. No entanto, trabalhamos em plug-ins IDE para ajudar no download e na configuração.
Alguns plug-ins já estão disponíveis:
Adicione duas ações ao lado do botão "Depurar" no intellij, Executar com hotswap, Depurar com hotswap.
Ao clicar na ação, os parâmetros VM serão definidos para você, não há necessidade de definir os parâmetros VM manualmente.
Código-fonte e documentação: https://github.com/gejun123456/HotSwapHelper.
A configuração básica é definida para recarregar classes e recursos do classpath conhecido pelo aplicativo em execução (classloader). Se precisar de uma configuração diferente, adicione o arquivo hotswap-agent.properties à raiz do caminho de classe (por exemplo, src/main/resources/hotswap-agent.properties
).
A documentação detalhada das propriedades disponíveis e dos valores padrão pode ser encontrada no arquivo de propriedades do agente
A sintaxe completa das opções de linha de comando é:
-javaagent:[yourpath/]hotswap-agent.jar=[option1]=[value1],[option2]=[value2]
O agente Hotswap aceita as seguintes opções:
autoHotswap = true - observe todos os arquivos .class em busca de alterações e faça Hotswap automaticamente da classe no aplicativo em execução (em vez de executar o Hotswap a partir de sua sessão de depuração IDE)
disablePlugin=[pluginName] - desativa um plugin. Observe que isso proibirá completamente o carregamento do plugin (ao contrário da opção disablePlugin em hotswap-agent.properties, que desabilitará apenas o plugin para um carregador de classe. Você pode repetir esta opção para cada plugin a ser desabilitado.
Adicionar opção vm -Dhotswapagent.disablePlugin=Spring,SpringBoot para desabilitar plug-ins, funciona da mesma forma que a opção do agente disablePlugin na seção anterior.
O agente Hotswap faz o trabalho de recarregar recursos e configuração do framework (Spring, Hibernate, ...), mas depende do mecanismo padrão Java hotswap para recarregar classes. O hotswap Java padrão permite apenas a alteração do corpo do método, o que o torna praticamente inutilizável. DCEVM é um patch JVM (Hotspot) que permite quase qualquer alteração estrutural de classe no hotswap (com exceção de uma alteração de hierarquia). Embora o agente hotswap funcione mesmo com java padrão, recomendamos usar DCEVM (e todos os tutoriais usam DCEVM como JVM de destino).
O agente Hotswap é um contêiner de plug-ins com gerenciador de plug-ins, registro de plug-ins e vários serviços de agente (por exemplo, para observar alterações de classe/recurso). Ajuda com tarefas comuns e problemas de carregamento de classe. Ele verifica o caminho de classe em busca de classes anotadas com a anotação @Plugin, injeta serviços de agente e registra ganchos de recarga. A modificação do bytecode em tempo de execução é fornecida pela biblioteca javaasist.
Plugins administrados pelo Hotswap Agent geralmente são focados em uma estrutura específica. Por exemplo, o plugin Spring usa serviços HA para:
Modifique as classes raiz do Spring para obter contextos do Spring e caminho de varredura registrado
Fique atento a qualquer alteração de recurso em um caminho de varredura
Fique atento a um hotswap de um arquivo de classe dentro de um pacote de caminho de varredura
Recarregar definição de bean após uma alteração
... e muitos outros
CXF-JAXRS (3.x) - redefina o recurso JAXRS após a redefinição da classe de recurso, reinjete a instância se integrada com Spring e CDI (Weld/OWB).
Deltaspike (1.x,2.x) - mensagens, ViewConfig, repositório, recarregamento de proxy. Reinjeção de beans CDI com escopo Deltaspike.
ELResolver (2.x-5.x) (JuelEL, Appache Commons EL, Oracle EL 3.0) - limpe o cache do ELResolver na mudança de classe. Suporte hotswap para #{...} expressões.
FreeMarker - limpe o cache de introspecção de classe dos beans Apache Freemarker na alteração da definição de classe.
Hibernate (3.x-6.x) - Recarrega a configuração do Hibernate após a criação/alteração da entidade.
iBatis - recarregamento da configuração do iBatis.
IDEA - suporte para desenvolvimento do IntelliJ IDEA em IDEA
Jackson - limpa os caches internos do Jackson quando a classe é redefinida.
Jersey1 - recarrega o contêiner Jersey1 após a definição ou redefinição do recurso raiz ou da classe do provedor.
Jersey2 - recarrega o contêiner Jersey2 após a definição ou redefinição do recurso raiz ou da classe do provedor.
Logback - Recarregamento da configuração de logback.
Log4j2 - Recarregamento da configuração Log4j2.
Mojarra (2.x) – suporte para alterações no pacote de recursos do aplicativo (arquivo de propriedades). Suporte para reinjeção/recarregamento de beans ViewScoped.
MyBatis (5.3) - recarrega a configuração após alterações no arquivo mapeador
MyFaces (2.x-4.x) - suporte para alterações no pacote de recursos do aplicativo (arquivos de propriedades). Suporte para reinjeção/recarregamento de beans ViewScoped.
OmniFaces - suporte para reinjeção/recarregamento de beans ViewScoped.
OpenWebBeans - (CDI) (1.x-4.x) - recarrega a definição da classe do bean após a definição/alteração da classe. Os beans podem ser recarregados de acordo com a estratégia definida no arquivo de propriedades.
OsgiEquinox - Suporte Hotswap para plugin Eclipse ou desenvolvimento da plataforma Eclipse.
RestEasy (2.x, 3.x) - Limpa e registra redefinições de classes.
Spring (3.2.x+, 4.x, 5.x) - Recarregue a configuração do Spring após a definição/alteração da classe.
Spring Boot (1.5.x+, 2.0.x) - Recarregamento dinâmico de arquivos de configuração do Spring Boot em tempo real.
Vaadin (23.x, 24.x) – Atualize rotas, modelos de modelos e, na prática, qualquer coisa na hora.
WebObjects - Limpe os caches de codificação de valores-chave, componentes, ações e validação após a mudança de classe.
Weld (CDI) (2.x-5.x) - recarrega a definição da classe do bean após a definição/alteração da classe. Os beans podem ser recarregados de acordo com a estratégia definida no arquivo de propriedades.
Wicket - limpa os caches do wicket se os arquivos de propriedades forem alterados
WildFlyELResolver - Limpa BeanELResolver após qualquer redefinição de classe.
ZK (5x-7x) - Estrutura ZK (http://www.zkoss.org/). Altere os valores padrão das propriedades da biblioteca para desabilitar caches, mantenha o cache de rótulo e o cache do resolvedor de bean.
JBossModules - adiciona caminho de classe extra ao carregador de classes do módulo do JBoss. (Mosca Selvagem)
Jetty - adicione classpath extra ao carregador de classe do aplicativo. Todas as versões que suportam WebAppContext.getExtraClasspath devem ser suportadas.
Tomcat (7.x,8.x,9.x,10.x) configura o Apache Tomcat com extraClasspath e propriedade webApp. Suporta também GlassFish, Payara e Tomee7.
Undertow - adicione classpath, watchResources e webappDir extras ao gerenciador de recursos do undertow.
Weblogic - adicione classpath extra ao carregador de classe do aplicativo.
AnonymousClassPatch - Troque nomes de classes internas anônimas para evitar alterações incompatíveis.
ClassInit - inicializa novos membros estáticos/valores de enum após a redefinição de classe/enum e mantém os valores estáticos sobreviventes. (Correção de limitação conhecida do DCEVM)
Hotswapper - Observe qualquer alteração no arquivo de classe e recarregue-o (hotswap) rapidamente por meio do Java Platform Debugger Architecture (JPDA)
Proxy (suportado com.sun.proxy, CGlib) - redefine classes de proxy que implementam ou estendem interfaces ou classes alteradas.
Encontre a documentação detalhada de cada plugin no arquivo README.md principal do projeto do plugin.
Depende de quantas estruturas você usa e quais caches estão desabilitados. Exemplos de medições para um grande aplicativo corporativo do mundo real baseado em Spring + Hibernate, executado no Jetty.
Setup | Startup time -----------------------------|------------- Run (plain Java) | 23s Debug (plain Java) | 24s Debug (plain DCEVM) | 28s Agent - disabled all plugins | 31s Agent - all plugins | 35s
Você pode escrever um plugin diretamente como parte do seu aplicativo. Defina pluginPackages=your.plugin.package
dentro de sua configuração hotswap-agent.properties
para descobrir classes anotadas @Plugin
. Você também precisará da dependência JAR do agente para compilar, mas tome cuidado para NÃO adicionar o JAR ao seu aplicativo; ele deve ser carregado apenas como um javaagent. Dependência do Maven:
org.hotswapagent HotswapAgent ${project.version} provided
Consulte ExemploPlugin (parte de TestApplication) para ver um plugin simples comentado. Leia o leia-me do agente para entender os conceitos do agente. Verifique o código-fonte dos plug-ins existentes para obter mais exemplos.
Inicie o script run-tests.sh
no diretório principal. Atualmente, você precisa configurar o diretório de localização JAVA_HOME manualmente. Pelo menos o Java 11 com DCEVM deve ser verificado antes do lançamento. Todos os testes automáticos são configurados para falhar em todo o script no caso de falha de um único teste.
Vá para o diretório que representa a raiz do repositório. Caso DCEVM seja denominado dcevm
mvn release:prepare mvn release:perform
Agente de troca a quente:
Jiri Bubnik – coordenador do projeto, implementação inicial
Alexandros Papadakis - Versionamento Maven, Weld, JSF, Hibernate3, RestEasy, plug-ins WildFly
Erki Ehtla - plugin Spring, plugin Proxy
Vladimir Dvorak - ELResolver, OsgiEquinox, Weld, Owb, Deltaspike, Jvm, Jdk, JBossModules, ClassInit, JSF, Mybatis
Sergey Lysenko - plugin de solda
Samuel Pelletier - plugin WebObjects
Jan Tecl - web design
@liuzhengyang - plugin jackson
Lukasz Warzecha - plugin Log4j2
@muwaiwai - plugin iBatis
Thomas Heigl - plugin Wicket
AJ Banck - plugin FreeMarker
Sinan Yumak - Mojarra, plug-ins MyFaces
smallfour - plugin Mybatis
@cvictory - plugin Spring, plugin Spring Boot
@homejim - plugin MyBatis, plugin MyBatisPlus
DCEVM:
Thomas Würthinger – implementação inicial.
Ivan Dubrov - ex-coordenador de projetos, atualização para Java7+Java8, patches, sistema de compilação (Gradle)
Kerstin Breitender - colaboradora.
Christoph Wimberger - contribuidor.
Vladimir Dvorak - migração java9,java11,jbr17,jbr21, contribuidor
Jiri Bubnik - migração java9,java11