2

我试图让一个用 maven 构建的 java 程序在 docker-compose 场景上运行,并在我进行更改时热重载。我在原始 libvm 之上添加了trava-jdk 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 上应用热重载并正确运行代码有点迷茫。

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

4

2 回答 2

6

我没有使用此具体热插拔代理的经验,但总的来说可以回答您的问题:

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

  2. 确保应用程序正在运行

  3. 在 IDE 中创建“远程调试配置,在 IntelliJ 中:运行/调试配置 -> 远程 -> 创建新配置并指定您在步骤 2 中创建的主机和公开端口。您应该能够连接和在将与 IDE 交互的代码中放置断点

  4. 如果您对某些源文件进行了一些更改,请在连接到远程调试会话时右键单击并编译它。

  5. 如果可以完成更改,它将在此时使用热交换,并在这种情况下将新字节码“上传”到 docker 内的远程进程,并将应用此更改而无需重新加载。

默认情况下,JVM 已经提供了 Hotspot 功能,但是我相信这个库应该提供更灵活/强大的选项。

于 2020-02-04T12:57:42.597 回答
3

有一个项目HotswapDocklands专门用于在 Docker 中运行 HotswapAgent+dcevm。它使用 Docker/extra_class_path内目录到 Docker 外目录的映射。然后对内部任何文件所做的所有修改都使用extraClassPathextra_class_path到 dcevm进行“hotspapped” 。要附加调试器,您必须使用 jdwp 运行 dcevm 并从 Docker 公开调试器端口。

于 2020-02-06T14:40:00.023 回答