使用 Groovy 修复在 Web 容器内运行的代码

发布于 2024-08-03 21:38:55 字数 1369 浏览 1 评论 0原文

我正在运行一个有错误的网络应用程序。我知道如何在源中修复它。但是我无法重新部署该应用程序,因为我必须将其脱机才能执行此操作。 (至少现在不是)。

我现在想要“在运行时”修复代码可以这么说,对生命体进行手术。

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

使用 Groovy 向类添加行为的正常方法与此类似:

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

此代码将方法 foo 添加到 java.lang.String< /em> 并打印 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 方法仍然存在,看起来我的更改已经是永久性的......

所以我猜剩下的问题是 < strong>如何强制 Seam 重新实例化其所有组件和/或如何在所有活动实例上永久进行更改...?

I have a webapp running that has a bug. I know how to fix it in the sources. However I cannot redeploy the app as I would have to take it offline to do so. (At least not right now).

I now want to fix the code "at runtime". Surgery on the living object, so to speak.

The app is implemented in Java and is build on top of Seam. I have added a Groovy Console to the app previous to the last release. (A way to run arbitrary code at runtime)

The normal way of adding behaviour to a class with Groovy would be similar to this:

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

This code added the method foo to java.lang.String and prints 9. I can do the same thing with classes running inside my webapp container. New instances will thereafter show the same behaviour:

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

Works as excpected. All good so far.

My problem is now that the container, the web framework, Seam in this case, has already instantiated and cached the classes that I would like to manipulate (that is change their behaviour to reflect my bug fix).

Ideally this code would work:

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

However the instantiation of SomeService has already happened and there is no effect.

Thus I need a way to make my changes "sticky". Has the groovy magic gone after my script has been run? Well, after logging out and in again, I can run this piece of code and get the expected result:

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

So the foo method is still around and it looks like my change has been permanent...

So I guess the question that remains is how to force Seam to re-instantiate all its components and/or how to permanently make the change on all living instances...?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

飘落散花 2024-08-10 21:38:55

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

事实上,Groovy 的魔力依然存在。但仅当从 groovy 环境调用时,即通过其他 groovy 代码。

事实证明,在 Java 环境中,“锁孔手术模式”,由Dierk König 只能在运行时更改数据,不能更改代码。该模式的全部功能只能在纯 Groovy 环境中使用。

The hotfix is not persistent because the calling code is pure Java, not Groovy.

The Groovy magic in fact stays. But only when called from the groovy environment, that is through other groovy code.

Turns out that in a Java environment, the "Keyhole Surgery Pattern", as coined by Dierk König is only usable to change data at runtime, not code. The full power of the pattern is only accessible in a pure Groovy environment.

捶死心动 2024-08-10 21:38:55

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

Not Groovy, but an alternative approach that works - as long as you don't change / add / remove and method signatures - is to set the Server in debug mode and use Java Hot Code Replacement functionality. Most IDE's support this. The changes are permanent and applied to instantiated components as well.
Requires of course that the app server is already configured with the a debug console or allows to enable it after the start.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文