ServiceNowをYokohamaバージョンからAustraliaバージョンへアップグレードした後、これまで問題なく動作していたScript Includeが正常に動作しなくなる事象が発生しました。
調査を進めたところ、Script Includeの保存時にもコンパイルエラーが発生し、通常のデバッグ作業すら行えない状態となりました。
本記事では、発生した事象、原因、そして対応方法についてわかる範囲で紹介いたします。
発生した事象
Australiaバージョンへアップグレード後、対象のScript Includeを呼び出している処理において、以下のエラーが発生しました。
com.glide.script.RhinoEcmaError: undefined is not a function
エラーの発生箇所を特定するため、Script Includeに gs.info() を追加してログを出力しようとしました。
しかし、修正後に保存を行うと、今度は以下のコンパイルエラーが発生し、Script Include自体を保存できなくなりました。
Could not save record because of a compile error:
JavaScript parse error at line (12) column (0)
problem = Program too complex (out of locals)
そのため、通常の方法では原因調査を進めることができない状況となりました。
原因調査
該当するScript Includeは約17,000行に及ぶ非常に大規模な実装となっており、initialize() 関数内では多数の変数を定義していました。
調査のためNowSupportに問い合わせたところ、以下の回答をいただきました。
対象 Script Include の
initialize()関数内の変数定義が、新しい JavaScript Engine の制限を超えてしまうことが原因と考えられます。initialize()関数を複数の関数へ分割することで、本事象が解消されることを確認しています。
つまり、Australiaバージョンで採用されたJavaScript Engineでは、initialize() 関数内で扱えるローカル変数数などに制限があり、今回のScript Includeはその制限を超えてしまっていたことが原因でした。
なお、この事象はAustraliaより前のバージョンでは発生していませんでした。
対応方法
NowSupportの回答をもとに、initialize() 関数内に記述していた処理を複数のScript Includeに分割しました。
元のScript Includeからは、それぞれのScript Includeを呼び出す構成へ変更しています。
この改修を実施した結果、
- Script Includeを正常に保存できるようになった
undefined is not a functionのエラーも解消し、バージョンアップ前と同様の動作をした
ことを確認しました。
今回のポイント
今回の事象は、Script Includeの記述内容そのものに問題があったわけではなく、新しいJavaScript Engineの制限により発生したものでした。
長年運用されている環境や大幅なカスタマイズ等を実施している環境では、変数定義や定数管理を1つのScript Includeに集約しているケースもあるかと思います。
そのような大規模なScript Includeは、Australiaバージョン以降へのアップグレード時に同様の事象が発生する可能性があります。
アップグレード後に
undefined is not a functionProgram too complex (out of locals)
といったエラーが発生した場合は、initialize() 関数内の変数定義数やScript Includeの構成を一度確認してみることをおすすめします。
まとめ
今回は、Australiaバージョンへのアップグレード後に発生したScript Includeのコンパイルエラーについて紹介しました。
原因は新しいJavaScript Engineにおける initialize() 関数内の変数数の制限であり、処理を複数のScript Includeに分割することで解消できました。
今回のような事象は、特に大規模なScriptを利用している環境で発生する可能性があります。
Zurichバージョンを利用している環境やまだYokohamaからバージョンアップをしていない環境などではまだこの上限がないと思われるため、バージョンアップ後に同様のエラーに遭遇した場合は、JavaScript Engineの制限も原因の一つとして疑ってみるとよいかもしれません。
