是否可以有一个基于 "HotReload" docker 的 java 环境?

Is it possible to have a "HotReload" docker based java environment?

我正在尝试使用 Maven 构建的 java 程序在 docker-compose 场景中 运行 并在我进行更改时热重载。 我在原始 libvm 之上添加了 trava-jdk libvm,并在适当的位置添加了 hotswapagent 库。当我 运行 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)

我要实现的 docker 文件如下

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 上应用热重载以及如何正确 运行 代码有些迷茫。

如果您想知道为什么我需要这样的 hack,我有一个具有 E2E 测试的 IoT 环境,我希望能够快速迭代新测试或失败测试,​​而无需重新编译或重新启动容器。

我没有使用过这个具体的热交换代理的经验,但一般来说回答你的问题:

  1. 当你构建 docker 图像时,你应该 运行 毕竟你自己的应用程序(通过 maven,使用 java -jar 或任何其他方式)所以,当您启动应用程序进程时,您应该让应用程序准备好进行远程调试:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9999
  1. 您应该在 docker 中公开一个调试端口,以便 IDE 将连接到主机上的该端口,并将路由到 [=45] 中的端口 9999 =] 容器。

  2. 确保应用程序是 运行ning

  3. 在 IDE 中创建“远程调试配置”,在 IntelliJ 中:Run/Debug 配置 -> 远程 -> 创建新配置并指定主机和已公开的端口在第 2 步中创建。您应该能够在将与 IDE

  4. 交互的代码中连接和放置断点
  5. 如果您对某些源文件进行了一些更改,请在连接到远程调试会话时右键单击并编译它。

  6. 如果可以完成更改,此时它将使用热交换,并且在这种情况下 "upload" 将新字节码发送到 docker 内部的远程进程,并且将在不重新加载的情况下应用此更改。

默认情况下,JVM 已经提供了 Hotspot 功能,但是这个库,我相信应该提供更多 flexible/powerful 选项。

dcevm 有项目 HotswapDocklands dedicated to runnig HotswapAgent+dcevm in Docker. It is using mapping of in-Docker /extra_class_path directory to directory out of Docker. Then all modifications done on any file inside extra_class_path are "hotspapped" using extraClassPath。要附加调试器,您必须使用 jdwp 运行 dcevm 并从 Docker.

公开调试器端口