[akabana-user:103] <S2Flex2>S2Flex2を使用しているswfをmx.moduleを使用してアンロードした際、処理を実行すると例外がはっせいする。

kondo [E-MAIL ADDRESS DELETED]
2007年 3月 8日 (木) 19:28:08 JST


近藤(nobu)です。

長いタイトルですみません。m( _ _ )m
しかもこの後長文で更にすみません。m( _ _ )m

S2Flex2を使用してDBから情報を取得、一覧表示するアプリを作っています。
ただ、今回、そのアプリをモジュール(mx.module)にして、他のアプリ
(こちらはmx.application)から呼び出させています。
この時に、S2Flex2から(だと思う)例外が発生しています。

■概要
1.アプリA、モジュールBを作成。
2.アプリAからモジュールBをロード。->ModuleLoader.loadModule()
3.モジュールBで、DB参照->一覧表示を行う。(S2Flex2使用)
4.アプリAからモジュールBをアンロード。->ModuleLoader.unloadModule()
5.また、アプリAからモジュールBをロード。->ModuleLoader.loadModule()
6.またモジュールBでDB参照->一覧表示を行おうとすると例外発生。

===================================================================
■例外内容
TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッ
ドにアクセスすることはできません。
	at mx.managers::CursorManager$/setBusyCursor()
	at org.seasar.flex2.rpc.remoting::S2Flex2Service/::setupCursor()
	at org.seasar.flex2.rpc.remoting::S2Flex2Service/::remoteCall()
	at Function/http://adobe.com/AS3/2006/builtin::apply()
	at
org.seasar.flex2.rpc.remoting::S2Flex2Service/http://www.adobe.com/2006/actionscript/flash/proxy::callProperty()
	at demoapp.web.app01::App01Page/read()
	at demoapp.web.app01::App01Page/readBtnOnClick()
===================================================================

なんか、setBusyCursor()内でエラーが発生している??ように見えます。

現在わかっていることは、
1.unloadModule()を実行しなければこの現象は発生しない。
 ※ただ、mx.ModuleはunloadModule()を使用しない場合、インスタンスを使い
  まわすようで、前回の状態を保持したままLoadされる。
2.SWFLoaderではこの問題は発生しない。
 ※そもそもSWFLoaderにはunloadがない。(ガベコレ任せと信じます)

SDKのソースを見てみると、flash.display.Loaderの生成・破棄をやってるので
、このあたりが怪しいような・・・というところで力尽きました。unloadModule
で何か破棄されてしまっているのではないかと思うのですが・・・。

何かお分かりでしたら、アドバイスをお願い致します。


■環境
Eclipse 3.2.1 + Language Pack
Flex Builder 2.0.1
Tomcat Plug-in
Dolteng 0.17.0
DbLuancher


以下、ソース。(S2Flex2を利用しているところまで。Dolteng使用)
===================================================================
■Main.mxml(メイン)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" xmlns:ns1="demoapp.web.menu.*" height="360"
creationComplete="init()">
	<mx:Script>
		<![CDATA[
			import mx.events.FlexEvent;
			import mx.events.StateChangeEvent;
			import mx.controls.Alert;
			import mx.modules.ModuleLoader;
			
			private function init():void
			{
				// 初期表示は menu state
				this.currentState = 'menu';
			}

			
			private function stateMenuOnEnterState(e:FlexEvent):void
			{
			}
			
			
			private function stateMenuOnClick(e:MouseEvent):void
			{

<<ModuleLoader.loadModule()実行部>>

				ModuleLoader(this.states[1].overrides[2].target).url = "App01e.swf";
				this.currentState='app'
			}


			private function stateAppOnEnterState(e:FlexEvent):void
			{
				// かなり無理やり・・・statesの特定のアプリケーションを取得できないもの
か・・・。
				ModuleLoader(this.states[1].overrides[2].target).loadModule();
			}
			
			private function stateAppOnClick(e:MouseEvent):void
			{

<<ModuleLoader.unloadModule()実行部>>

				ModuleLoader(this.states[1].overrides[2].target).unloadModule();
				this.currentState = 'menu'
			}
		]]>
	</mx:Script>
	

	<mx:states>
		<mx:State name="menu" enterState="stateMenuOnEnterState(event)">
			<mx:AddChild position="lastChild">
				<mx:Button x="10" y="10" label="app" click="stateMenuOnClick(event)"/>
			</mx:AddChild>
			<mx:AddChild position="lastChild">
				<ns1:MenuCmp x="10" y="40" width="463">
				</ns1:MenuCmp>
			</mx:AddChild>
		</mx:State>
		<mx:State name="app" enterState="stateAppOnEnterState(event)">
			<mx:AddChild position="lastChild">
				<mx:Button x="10" y="10" label="close" click="stateAppOnClick(event)"/>
			</mx:AddChild>
			<mx:AddChild position="lastChild">
			</mx:AddChild>
			<mx:AddChild position="lastChild">
				<mx:ModuleLoader x="10" y="40" width="442" height="310" id="loader">
				</mx:ModuleLoader>
			</mx:AddChild>
		</mx:State>
	</mx:states>
	
	
</mx:Application>

■App01e.mxml(S2Flex2を使用しているアプリ。mx.moduleで作成)
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" width="364"
height="264" xmlns:ns1="demoapp.web.app01.*">
	<ns1:App01 width="100%" height="100%">
	</ns1:App01>
</mx:Module>


■App01.mxml(App01e.mxmlの実態(コンポーネント))
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="366"
height="262" xmlns:seasar="http://www.seasar.org/s2flex2/mxml"
xmlns:app01="demoapp.web.app01.*">
	<seasar:S2Flex2Service id="service" destination="app01_app01Service"
showBusyCursor="true"/>
	<app01:App01Page id="page"/>

	<mx:Button x="0" y="0" label="read" id="readBtn"/>
	
	<mx:DataGrid x="0" y="28" width="100%" height="234" id="dg">
		<mx:columns>
			<mx:DataGridColumn headerText="社員コード" dataField="empCd"/>
			<mx:DataGridColumn headerText="社員名" dataField="empNm"/>
			<mx:DataGridColumn headerText="部署コード" dataField="pstCd"/>
		</mx:columns>
	</mx:DataGrid>
	
	<mx:Label x="60" y="2" text="0" width="90" textAlign="right" id="recCnt"/>
	<mx:Label x="158" y="2" text="件" width="22"/>
	
</mx:Canvas>


■App01Page.as(App01.mxmlのPageクラス)
package demoapp.web.app01 {

	import mx.controls.Alert;
	import mx.rpc.AsyncToken;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.events.FaultEvent;
	import flash.events.Event;
	import demoapp.entity.mst.MstEmployee;
	import demoapp.web.AbstractPage;
	import demoapp.web.AppMode;
	import flash.events.MouseEvent;
	import mx.collections.ArrayCollection;

	[Bindable]
	public class App01Page extends AbstractPage {

		public var model: MstEmployee;

		public var appMode: int;

		override public function onCreationComplete(event: Event): void {
			super.onCreationComplete(event);
			setInitEntryMode();
		}
		
		public function setInitEntryMode(): void {
			appMode = AppMode.NEUTRAL;
			model = null;
		}
		
		public function setNewEntryMode(): void {
			appMode = AppMode.NEW;
		}

		public function setCorEntryMode(): void {
			appMode = AppMode.COR;
		}
		
		public function convertFormData(): void {
			loadFormData(this.model);
		}
		
		/**
		 * 情報取得メソッド
		 *
		 */
		public function read():void {
			remoteCall(service.read(), readOnSuccess, readOnFault);
		}
		public function readOnSuccess(e:ResultEvent, token:Object=null):void {
			var mArray:Array = e.result as Array;
			var mArrayCollection:ArrayCollection = new ArrayCollection(mArray);
			
			// 取得結果をDataGridにバインディング
			document.dg.dataProvider = mArrayCollection;
			
			// 件数を表示
			document.recCnt.text = mArrayCollection.length;
		}
		public function readOnFault(e:FaultEvent, token:Object=null):void {
			Alert.show("read is fault");
		}
		
		public function readBtnOnClick(e:MouseEvent):void
		{
			read();
		}
	}
}
===================================================================



akabana-user メーリングリストの案内