2

バグのある Web アプリケーションを実行しています。ソースで修正する方法を知っています。ただし、アプリをオフラインにする必要があるため、アプリを再展開することはできません。(少なくとも今はそうではありません)。

「実行時に」コードを修正したいと思います。いわば生体の手術。

アプリは Java で実装され、Seam の上に構築されています。前回のリリースの前に、アプリにGroovy コンソールを追加しました。(実行時に任意のコードを実行する方法)

Groovy を使用してクラスに動作を追加する通常の方法は、次のようになります。

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

このコードはメソッドfoojava.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 のインスタンス化は既に行われており、効果はありません。

したがって、変更を「スティッキー」にする方法が必要です。私のスクリプトが実行された後、グルーヴィーな魔法はなくなりましたか? ログアウトしてから再度ログインすると、次のコードを実行して期待どおりの結果を得ることができます。

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

したがって、 foo メソッドはまだ残っており、私の変更は永続的であるように見えます...

したがって、残っている問題は、Seam にすべてのコンポーネントを強制的に再インスタンス化させる方法、および/または生きているすべてのインスタンスに永続的に変更を加える方法であると思います...?

4

2 に答える 2

1

呼び出しコードは純粋な Java であり、Groovy ではないため、ホットフィックスは永続的ではありません。

実際、Groovy の魔法は残っています。ただし、Groovy 環境から呼び出された場合のみ、それは他の Groovy コードを介して行われます。

Java 環境では、Dierk König によって造られた"Keyhole Surgery Pattern"は、コードではなく、実行時にデータを変更するためにのみ使用できることがわかりました。パターンの全機能は、純粋な Groovy 環境でのみ利用できます。

于 2009-09-08T09:02:08.443 に答える
0

Groovy ではありませんが、メソッドのシグネチャを変更/追加/削除しない限り、機能する代替アプローチは、サーバーをデバッグ モードに設定し、Java ホット コード置換機能を使用することです。ほとんどの IDE はこれをサポートしています。変更は永続的で、インスタンス化されたコンポーネントにも適用されます。もちろん、アプリサーバーがデバッグコンソールで既に構成されているか、起動後に有効にすることができます。

于 2009-09-23T01:05:22.197 に答える