とめども日誌

2005/05/17

[]S2Daoのページ 23:09 S2Daoのページを含むブックマーク

S2Daoのドキュメントのところで、「バッチ更新」のリンクが反応しない。ソース見てみたらリンク元はこれで、

<a href="#Batch">バッチ更新</a>

リンク先はこう。

<a name="batch">バッチ更新</a>

大文字小文字の違いか……。IEでは大丈夫だったけどFirefoxで駄目だった。Operaもダメ。

[]循環参照? 03:10 循環参照?を含むブックマーク

Seasar使ってたら、こんなエラーが出てきた。

org.seasar.framework.container.CyclicReferenceRuntimeException: [ESSR0047]test.impl.HogeLogicImplで循環参照が発生しました

でも調べても、循環参照なんてしてない。

全然分かんなかったんだが、Tomcatのログを見たら、起動時にdiconに記述したクラスのインスタンス化に失敗していた。

これが関係あるんだろうなぁ、と思い、さらに調査してみて原因を突き止めた。

diconの指定でsingletonと指定されたコンポーネントは、SingletonComponentDeployerによってインスタンス化されるのだけど、そのコードはこういうコードになってる。

public class SingletonComponentDeployer extends AbstractComponentDeployer {

	private Object component_;
	private boolean instantiating_ = false;
...
	private void assemble() {
		if (instantiating_) {
			throw new CyclicReferenceRuntimeException(
				getComponentDef().getComponentClass());
		}
		instantiating_ = true;
		component_ = getConstructorAssembler().assemble();
		instantiating_ = false;
		getPropertyAssembler().assemble(component_);
		getInitMethodAssembler().assemble(component_);
	}
...
}

このSingletonComponentDeployerは、dicon内でsingleton指定された(singletonがデフォルトだけど)クラス1つに対し、1インスタンス出来るようになってる模様。

ここで、実際にコンポーネントインスタンスが作られるのが、この部分。

		component_ = getConstructorAssembler().assemble();

この内部では、インスタンス生成に必要な他のクラスのインスタンスがあればそれも生成している。そのクラスをインスタンス化するには、(そのクラスがシングルトンで指定されていれば)やはりSingletonComponentDeployerが使われるので、再帰的に呼び出されることになる。

そのため、このクラスをインスタンス化するのに必要なクラスはこれで、さらにそのクラスをインスタンス化するにはこれが必要で……と辿っていくと循環参照があったときに無限ループなんてことになるので、循環参照を検知する仕組みがある。それが上のinstantiating_フラグ。インスタンスを生成する上記箇所の前後でこのフラグをオン・オフすることで、循環参照を防いでる。仮に循環参照があったら、CyclicReferenceRuntimeExceptionをスローする仕組みになってる。


さて、ここでインスタンス化する時点(component_ = getConstructor〜〜の時点)で例外が発生してしまうと、フラグが立ったままインスタンス化処理が中断してしまう。


そしてその後インスタンス化しようとしていたコンポーネントを利用しようとすると、最初のインスタンス化時に失敗しているため、もう一回生成しようとする。

だけど生成前に、フラグのチェックをこのように行っているので、

		if (instantiating_) {
			throw new CyclicReferenceRuntimeException(
				getComponentDef().getComponentClass());
		}

インスタンス化途中なのにもう一回呼び出された!これは循環参照に違いない!と勘違いされ、敢え無く例外がスローされることに。

この挙動はちょっと変えて欲しいんですが……、どうでしょうか>ひがさん(id:higayasuo)ほかコミッタの方々。循環参照では無いのだから循環参照というエラーメッセージは出さないで欲しいです。

higayasuohigayasuo 2005/05/17 10:48 instantiating_ = true;
try {
component_ = getConstructorAssembler().assemble();
} finally {
instantiating_ = false;
}
にしておきます。

zwfkzwfk 2005/05/17 23:09 よろしくおねがいしま〜す♪

koichikkoichik 2005/05/18 01:37 そんなわけで (どんなわけで?),project.xml にお名前を記載させて頂こうかと思うのですがよろしいでしょうか?

zwfkzwfk 2005/05/18 08:32 おっ、こんなんでいいんですか?
んじゃ、せっかくなのでおねがいしま〜す。

えーと、載せる名前は何にしようかな?
決めたらメールしまっす。

koichikkoichik 2005/05/19 02:02 パッチ (コード) を提供して頂いたわけではなかったので微妙かと思ったのですが,対応が自明なところまで調査して頂いたのでありかな,と.独断ですが.(^^;

トラックバック - http://d.hatena.ne.jp/zwfk/20050517
2003 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 10 |