1

そのため、シリアライゼーション、Wicket、およびマルチスレッド プロジェクトの経験はやや限られているため、ご容赦ください。

基本的に、私の Web アプリケーション クラスは POJ (parentObject) をインスタンス化し、新しいタイマーを開始して、タイマーを含むいくつかの childObjects をインスタンス化します。これらの childObjects は、parentObject クラスのリストに格納されます。私のウィケット アプリケーションのページは、parentObject にアクセスする必要があるため、次のようにアクセスできるようにしました。

public Object getParentObject
{
   return this.parentObject;
}

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

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

現在の問題は、parentObject と childObjects の両方の timertask が、本来あるべきように毎分呼び出されなくなったことです。私のログはparentObjectの最初の開始を拾いますが、ログメッセージは二度と出力されず、親オブジェクトのtimertaskのrun()メソッドが毎分実行されていないことを示しています。

編集:問題をより明確にするために、さらにいくつかのコードを追加しました

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);
    }
}
4

1 に答える 1

3

Given your problem description I figure you bind your ParentObject directly to your components instead of binding a reference to the ParentObject. The serialization/deserialization of session scoped objects (which all pages, components and models in effect are) creates these 'new' instances (even though they are deserialized copies of the original parent object).

While you have not shown much code, I suspect you do something like this:

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

This binds the parent object to the property model, and that binds the parent object to the page (through the label component). What you should do instead is:

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

This binds the page to itself, and instructs the property model to retrieve the application dynamically, and from the application the parent object, and from that the time. This way you don't bind your objects to the page hierarchy, but retrieve them dynamically.

Another option is to use a LoadableDetachableModel that retrieves the parent object from the application, and detaches it after rendering the page.

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

See the Wicket wiki for more information on Models.

于 2012-04-17T09:49:07.693 に答える