バグのある 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 のインスタンス化は既に行われており、効果はありません。
したがって、変更を「スティッキー」にする方法が必要です。私のスクリプトが実行された後、グルーヴィーな魔法はなくなりましたか? ログアウトしてから再度ログインすると、次のコードを実行して期待どおりの結果を得ることができます。
def someService = new com.my.package.SomeService()
println someService.foo(3)
したがって、 foo メソッドはまだ残っており、私の変更は永続的であるように見えます...
したがって、残っている問題は、Seam にすべてのコンポーネントを強制的に再インスタンス化させる方法、および/または生きているすべてのインスタンスに永続的に変更を加える方法であると思います...?