是否有可能有一个基于“HotReload”的 docker java 环境?

Fab*_*sta 3 java intellij-idea maven dcevm docker

我试图让一个用 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)
Run Code Online (Sandbox Code Playgroud)

我用于实现这一目标的 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/
Run Code Online (Sandbox Code Playgroud)

现在我发现自己对如何在 Ide 上应用热重载并正确运行代码有点迷失。

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

Mar*_*nik 7

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

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

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

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

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

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

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