Play! でこれを行う例があります。v2.0ですが、v1.2.4でも同じことをしようとしています
私は同じ一般的なアプローチに従おうとしました。それは、Heroku Schedulerに、Play 環境を初期化し、その環境内で必要なタスクを実行するクラスで JVM を明示的に開始させることです。私の具体的なタスクは、JPA を使用してデータベースからデータを取得し、メーラーを使用してそのデータを使用して電子メールを生成することでした。最初のアプローチは、Play を初期化した直後にロジックを実行するだけでしたが、「JPA コンテキストが初期化されていません」という例外が発生しました。
プロファイル:
web: play run --http.port=$PORT $PLAY_OPTS
reports: java -Dapplication.path=./ -Dplay.id=staging -Dprecompiled=true -DlogLevel=INFO -cp "precompiled/java:lib/*:conf:.play/framework/play-1.2.4.jar:.play/framework/lib/*:modules/mailerPlus-0.1/lib/*:modules/fastergt-1.7/lib/*" jobs.Reports .
Reports.java:
public class Reports {
private Reports() {
super();
}
public static void main(String[] args) {
File root = new File(System.getProperty("application.path"));
if (System.getProperty("precompiled", "false").equals("true")) {
Play.usePrecompiled = true;
}
try {
Play.init(root, System.getProperty("play.id", ""));
Mails.itjbSurveyReport();
} catch (Exception e) {
Logger.error(e, "");
} finally {
Play.stop();
}
}
}
ログ:
2012-06-20T21:58:27+00:00 app[run.1]: play.exceptions.JPAException: The JPA context is not initialized. JPA Entity Manager automatically start when one or more classes annotated with the @javax.persistence.Entity annotation are found in the application.
2012-06-20T21:58:27+00:00 app[run.1]: at play.db.jpa.JPA.get(JPA.java:22)
2012-06-20T21:58:27+00:00 app[run.1]: at play.db.jpa.JPA.em(JPA.java:51)
2012-06-20T21:58:27+00:00 app[run.1]: at play.db.jpa.JPQL.em(JPQL.java:18)
2012-06-20T21:58:27+00:00 app[run.1]: at play.db.jpa.JPQL.count(JPQL.java:26)
2012-06-20T21:58:27+00:00 app[run.1]: at models.User.count(User.java)
2012-06-20T21:58:27+00:00 app[run.1]: at notifiers.Mails.itjbSurveyReport(Mails.java:246)
2012-06-20T21:58:27+00:00 app[run.1]: at jobs.Reports.main(Reports.java:35)
次に、ロジックを「ジョブ」にラップして、JPA コンテキストが初期化されるようにすることにしましたが、JPA クエリから返されたオブジェクトでクラス読み込みの問題が発生しました。
Reports.java:
public class Reports extends Job {
private Reports() {
super();
}
@Override
public void doJob() throws Exception {
Mails.itjbSurveyReport();
}
public static void main(String[] args) {
File root = new File(System.getProperty("application.path"));
if (System.getProperty("precompiled", "false").equals("true")) {
Play.usePrecompiled = true;
}
try {
Play.init(root, System.getProperty("play.id", ""));
Reports reports = new Reports();
reports.now().get();
} catch (Exception e) {
Logger.error(e, "");
} finally {
Play.stop();
}
}
}
ログ:
2012-06-20T19:04:24+00:00 app[run.1]: ClassCastException occured : securesocial.provider.ProviderType cannot be cast to securesocial.provider.ProviderType
2012-06-20T19:04:24+00:00 app[run.1]:
2012-06-20T19:04:24+00:00 app[run.1]: play.exceptions.JavaExecutionException: securesocial.provider.ProviderType cannot be cast to securesocial.provider.ProviderType
2012-06-20T19:04:24+00:00 app[run.1]: at play.jobs.Job.call(Job.java:155)
2012-06-20T19:04:24+00:00 app[run.1]: at play.jobs.Job$1.call(Job.java:66)
2012-06-20T19:04:24+00:00 app[run.1]: at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
2012-06-20T19:04:24+00:00 app[run.1]: at java.util.concurrent.FutureTask.run(FutureTask.java:166)
2012-06-20T19:04:24+00:00 app[run.1]: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:165)
2012-06-20T19:04:24+00:00 app[run.1]: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:266)
2012-06-20T19:04:24+00:00 app[run.1]: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
2012-06-20T19:04:24+00:00 app[run.1]: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
2012-06-20T19:04:24+00:00 app[run.1]: at java.lang.Thread.run(Thread.java:636)
2012-06-20T19:04:24+00:00 app[run.1]: Caused by: java.lang.ClassCastException: securesocial.provider.ProviderType cannot be cast to securesocial.provider.ProviderType
2012-06-20T19:04:24+00:00 app[run.1]: at notifiers.Mails.itjbSurveyReport(Mails.java:259)
2012-06-20T19:04:24+00:00 app[run.1]: at jobs.Reports.doJob(Reports.java:36)
2012-06-20T19:04:24+00:00 app[run.1]: at play.jobs.Job.doJobWithResult(Job.java:50)
2012-06-20T19:04:24+00:00 app[run.1]: at play.jobs.Job.call(Job.java:146)
2012-06-20T19:04:24+00:00 app[run.1]: ... 8 more
興味深いことに、上記の v2.0 バージョンでは、ローカル クラスローダーが Play 環境に渡されているようで、おそらくこの問題は解決されています。v1.2.4 でこれを行う方法がわからない
次に何をすべきかわからない...