XMLエクスポートやインポートの時に出てくるプログラスバーがあるあれです。
ソースコード見てたらTransactionTemplateを使ってあれこれやるらしいのだけど、まんまコピペ―したらエラーが出た。
エラーの内容は、この人と一緒。answers.atlassian.com
で、原因はclassloaderの混合。Confluenceコアでは org.springframework.transaction.support.TransactionTemplate を使うのだけど、プラグんでは使っているSpringが違うとかでこれが使えない。そのため、com.atlassian.sal.api.transaction.TransactionTemplate を使う。そのあたりはこの辺で説明されてた。
Using Transaction Template - Atlassian Answers
Managing a Session Manually - Atlassian Answers
あるいは、Job Module - Atlassian Developersこのあたりのドキュメントでも良いかもしれない。
で、解決策としては
とりえあず、TransactionTemplateオブジェクトを作る。これはInjectionで作れるのでそれで作ってしまおう。
private TransactionTemplate transactionTemplate; public void setTransactionTemplate(TransactionTemplate tt) { this.transactionTemplate = tt; }
Servletならコンストラクタ引数にTransactionTemplate transactionTemplateとでも入れておけばできる。
タスクマネージャを作って、タスクの生成
時間のかかる処理を実装するタスクオブジェクトを設計。コンストラクタで先ほどのtransactionTemplateを持たせてメソッドrunInternalを実装する。こんな感じ。
public class FooLongRunningTask extends ConfluenceAbstractLongRunningTask { @Override protected void runInternal() { transactionTemplate.execute(new TransactionCallback<Object>() { @Override public Object doInTransaction() { // ここに時間のかかる処理 } }); }
最後にタスクの実行
LongRunningTaskManagerをインジェクションで取得して、先ほどのタスクをオブジェクトにして
if (isLongRunningTaskSupported() && !isSynchronous()) { taskId = longRunningTaskManager.startLongRunningTask(getAuthenticatedUser(), task); log.info("Started log-running task {} for export of space {}", taskId, getSpaceKey()); } else { log.info("Starting synchronous export of space {}; long-running tasks not enabled", getSpaceKey()); task.run(); }
として実行。isLongRunningTaskSupported()とかは良く分からないけどとりあえずXMLエクスポートのコードをコピペで。