【问题标题】:Hotfixing Code running inside Web Container with Groovy使用 Groovy 在 Web 容器中运行的修补程序代码
【发布时间】:2009-09-07 17:12:50
【问题描述】:

我正在运行一个有错误的 web 应用程序。我知道如何在源代码中修复它。但是我无法重新部署该应用程序,因为我必须使其脱机才能这样做。 (至少不是现在)。

我现在想在“运行时”修复代码可以说是对活体进行手术。

该应用程序是用 Java 实现的,并且构建在 Seam 之上。我在上一个版本之前的应用中添加了 Groovy 控制台。 (一种在运行时运行任意代码的方法)

使用 Groovy 向类添加行为的正常方式类似于:

String.metaClass.foo= { x -> x * x }
println "anything".foo(3)

此代码将方法 foo 添加到 java.lang.String 并打印 9。我可以对在我的 webapp 容器中运行的类执行相同的操作。此后,新实例将显示相同的行为:

com.my.package.SomeService.metaClass.foo= { x -> x * x }
def someService = new com.my.package.SomeService()
println someService.foo(3)

按预期工作。到目前为止一切顺利。

我现在的问题是容器,即 Web 框架,在本例中为 Seam,已经实例化并缓存了我想要操作的类(即更改它们的行为以反映我的错误修复)。

理想情况下,这段代码可以工作:

com.my.package.SomeService.metaClass.foo= { x -> x * x }
def x = org.jboss.seam.Component.getInstance(com.my.package.SomeService)
println x.foo(3)

但是 SomeService 的实例化已经发生并且没有效果。

因此,我需要一种方法来使我的更改“具有粘性”。在我的脚本运行之后,groovy 魔法消失了吗?嗯,注销再登录后,我可以运行这段代码,得到预期的结果:

def someService = new com.my.package.SomeService()
println someService.foo(3)

所以 foo 方法仍然存在,看起来我的更改是永久性的......

所以我想剩下的问题是如何强制 Seam 重新实例化它的所有组件和/或如何永久地对所有活动实例进行更改。 ..?

【问题讨论】:

    标签: java dynamic groovy seam web-frameworks


    【解决方案1】:

    修补程序不是持久的,因为调用代码是纯 Java,而不是 Groovy

    Groovy 的魔力实际上仍然存在。但只有从 groovy 环境调用时,即通过其他 groovy 代码。

    事实证明,在 Java 环境中,由 Dierk König 创造的"Keyhole Surgery Pattern" 仅可用于在运行时更改数据,而不是代码。该模式的全部功能只能在纯 Groovy 环境中使用。

    【讨论】:

      【解决方案2】:

      不是 Groovy,而是另一种可行的方法 - 只要您不更改/添加/删除和方法签名 - 将服务器设置为调试模式并使用 Java 热代码替换功能。大多数IDE都支持这一点。这些更改是永久性的,并且也适用于实例化的组件。 当然要求应用服务器已经配置了调试控制台或允许在启动后启用它。

      【讨论】:

        猜你喜欢
        • 2011-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-23
        • 2018-02-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多