我正在尝试让一个使用 maven 构建的 java 程序在 docker-compose 场景上运行,并在我进行更改时进行热重载。 我添加了trava-jdk libvm 位于原始 libvm 之上,并在适当的位置添加了 hotswapagent lib。当我运行 java -version 时,它给了我想要的东西
Starting HotswapAgent '/usr/local/openjdk-11/lib/hotswap/hotswap-agent.jar'
HOTSWAP AGENT: 10:18:24.771 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent {1.4.0} - unlimited runtime class redefinition.
HOTSWAP AGENT: 10:18:24.992 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [JdkPlugin, Hotswapper, WatchResources, ClassInitPlugin, AnonymousClassPatch, Hibernate, Hibernate3JPA, Hibernate3, Spring, Jersey1, Jersey2, Jetty, Tomcat, ZK, Logback, Log4j2, MyFaces, Mojarra, Omnifaces, ELResolver, WildFlyELResolver, OsgiEquinox, Owb, Proxy, WebObjects, Weld, JBossModules, ResteasyRegistry, Deltaspike, GlassFish, Vaadin, Wicket, CxfJAXRS, FreeMarker, Undertow, MyBatis]
openjdk version "11.0.5" 2019-10-15
OpenJDK Runtime Environment 18.9 (build 11.0.5+10)
Dynamic Code Evolution 64-Bit Server VM 18.9 (build 11.0.5+5-202001261315, mixed mode)
我的 dockerfile 来实现这一点,如下所示
FROM maven:latest
WORKDIR /tmp
RUN wget https://github.com/TravaOpenJDK/trava-jdk-11-dcevm/releases/download/dcevm-11.0.5%2B5/java11-openjdk-dcevm-linux.tar.gz
RUN tar -xvf java11-openjdk-dcevm-linux.tar.gz
RUN mv dcevm-11.0.5+5 /dcevm
WORKDIR /dcevm
RUN rm /usr/local/openjdk-11/lib/server/libjvm.so
RUN cp /dcevm/lib/server/libjvm.so /usr/local/openjdk-11/lib/server/
RUN cp -r /dcevm/lib/hotswap /usr/local/openjdk-11/lib/
现在我发现自己对如何在 Ide 上应用热重载并正确运行代码有点迷失。
如果您想知道为什么我需要这样的黑客,我有一个具有端到端测试的 IoT 环境,并且我希望能够快速迭代新测试或失败的测试,而无需重新编译或重新启动容器。
最佳答案
我没有使用此具体热插拔代理的经验,但一般来说可以回答您的问题:
- 当您构建 docker 镜像时,您应该运行自己的应用程序(通过 maven、使用 java -jar 或以任何其他方式),因此,当您启动应用程序进程时,您应该使应用程序已准备好进行远程调试:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9999
您应该在 docker 中公开一个调试端口,以便 IDE 将连接到主机上的该端口,并将其路由到 docker 容器中的端口 9999。
确保应用程序正在运行
在 IDE 中创建“远程调试配置”,在 IntelliJ 中:运行/调试配置 -> 远程 -> 创建新配置并指定您在步骤 2 中创建的主机和公开端口。您应该能够在与 IDE 交互的代码中连接并放置断点
如果您对某些源文件进行了一些更改,请在连接到远程调试 session 时右键单击并编译它。
如果可以完成更改,此时它将使用热交换,并将新字节码“上传”到 Docker 内部的远程进程(在这种情况下),并且将应用此更改而无需重新加载。
默认情况下,JVM 已经提供了 Hotspot 功能,但是我相信这个库应该提供更灵活/更强大的选项。
关于java - 是否可以有一个基于 "HotReload"docker 的 java 环境?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60055279/