2012-04-16 25 views
1

私はシリアル化、Wicket、マルチスレッドプロジェクトの経験が限られていますので、私には負担がかかります。Wicketアプリケーション、シリアライゼーション、Javaタイマー

本質的に私のWebアプリケーションクラスは、aを作成するPOJ(parentObject)をインスタンス化して、新しいタイマーを開始し、タイマーも持つ複数のchildObjectsをインスタンス化します。これらのchildObjectは、parentObjectクラスのリストに格納されます。私の改札アプリケーションのページはparentObjectにアクセスする必要があるので、私はそれがアクセスできるように作られた:

public Object getParentObject 
{ 
    return this.parentObject; 
} 

そしてそうのように、各ページに取得されます。

((MyApplication)Application.get()).getParentObject() 

問題は現在、ということですTimerTaskを用parentObjectとchildObjectの両方が、毎分毎分呼び出されることはありません。私のログはparentObjectの最初の開始をピックアップしますが、ログメッセージは再び出力されません。これは、親オブジェクトのtimestaskのrun()メソッドが毎分実行されていないことを通知します。

編集:それはより多くの問題が、私はあなたがParentObjectへの参照を結合するのではなく、あなたのコンポーネントに直接ごParentObjectをバインド把握あなたの問題の説明が与えられ

public class childObject implements Serializable 
{ 
    private transient NamedParameterJdbcTemplate njt; 
    private transient Timer timer; 

    public childObject(DataSource ds) 
    { 
     this.njt = new NamedParamterJdbcTemplate(ds); 
    } 

    public void start() 
    { 
     timer = new Timer(); 

     timer.schedule(new TimerTask(){ 

      public void run() 
      { 
       //do some stuff that is never happening 
      } 

     }, 0, 60000); 
    } 
} 

public class ParentObject implements Serializable 
{ 
    private DataSource ds; 
    private List<ChildObject> childObjects; 
    private transient Timer; 

    public ParentObject(DataSource ds) 
    { 
     this.ds = ds; 
     //add some stuff to childObjects 

     timer = new Timer(); 

     timer.schedule(new TimerTask(){ 

      public void run() 
      { 
       for(some condition) 
       { 
        //Do some stuff 

        if(/*condition is met*/) 
        { 
         childObjects.get(i).start(); 
        } 
       } 
      } 

     }, 0, 60000); 
    } 
} 

public MyApplication extends WebApplication 
{ 
    private ParentObject object; 
    private DataSource ds; 

    public void init() 
    { 
     super.init(); 

     ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml"); 
     ds = (DataSource) context.getBean("dataSource"); 

     parentObject = new ParentObject(ds); 
    } 
} 
+0

WicketApplicationはシングルトンであり、ページまたはセッションとしてシリアル化されません。 – bert

+0

コメントありがとうございます。私はそれを理解していますが、私のタイマーはまだ意図したとおりに動作していません。状況を表示するために擬似コードを追加しました。 – thatidiotguy

答えて

3

をクリアにするためにいくつかのより多くのコードを追加しました。セッションスコープのオブジェクト(実際にはすべてのページ、コンポーネント、モデル)のシリアル化/逆シリアル化は、(元の親オブジェクトの逆シリアル化されたコピーであっても)これらの「新しい」インスタンスを作成します。

あなたは多くのコードを示していないが、私はあなたがこのような何かを疑う:

public MyPage() { 
    Object parentObject = ((MyApplication)Application.get()).getParentObject(); 
    add(new Label("timer", new PropertyModel(parentObject, "time"))); 
} 

これは、プロパティモデルに親オブジェクトを結合し、そのラベルを通じて(ページへの親オブジェクトをバインド成分)。あなたが代わりにやるべきことは次のとおりです。

public MyPage() { 
    add(new Label("timer", new PropertyModel(this, "application.parentObject.time"))); 
} 

これは、それ自体にページを結合し、動的にアプリケーションを取得するには、プロパティモデルを指示し、アプリケーションから親オブジェクト、および時刻いるから。この方法では、オブジェクトをページ階層にバインドするのではなく、オブジェクトを動的に取得します。

もう1つのオプションは、アプリケーションから親オブジェクトを取得するLoadableDetachableModelを使用し、ページのレンダリング後にそのオブジェクトをデタッチすることです。

public class ParentObjectModel extends LoadableDetachableModel<ParentObject> { 
    @Override public ParentObject load() { 
     return ((MyApplication)Application.get()).getParentObject(); 
    } 
} 

Wicket wiki for more information on Modelsを参照してください。

+0

私は、parentObject変数をアプリケーションのパブリック変数として保存すべきだと言っていますか?これは私が現在やっていることであるため、アクセサーメソッドを使ったプライベート変数として格納するのとは異なります。 – thatidiotguy

+0

私は決して言わなかった。 Wicketは、プライベートフィールドやアクセサを使用するのに十分スマートです。それがプロパティモデルの仕組みです。 –

+0

提案していただきありがとうございます。質問を編集して、より詳細なコードを追加しました。 – thatidiotguy

関連する問題