java - 如何使用 Play! 实现预定的一次性流程v1.2.4 和 Heroku Scheduler 插件

标签 java heroku playframework playframework-1.x

有一个example for doing this with Play! v2.0但我正在尝试对 v1.2.4 做同样的事情

我尝试遵循相同的通用方法,即获取 Heroku Scheduler使用初始化 Play 环境的类显式启动 JVM,然后在该环境中执行所需的任务。我的具体任务是使用 JPA 从数据库中检索一些数据,然后使用 Mailer 使用该数据生成电子邮件。最初的方法只是在初始化 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 .

报告.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 查询返回的对象的类加载问题:

报告.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 中如何做到这一点

不知道下一步该做什么...

最佳答案

这是一个工作示例应用程序:
https://github.com/jamesward/play1-scheduled-job-demo

技巧是从 Play 的类加载器(来自 HelloJob.java )加载作业:

Class c = Play.classloader.loadClass("jobs.HelloJob");
Job s = (Job) c.newInstance();
s.run();

关于java - 如何使用 Play! 实现预定的一次性流程v1.2.4 和 Heroku Scheduler 插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11128689/

相关文章:

java - 将光标移动到 while 循环 ResultSet 后的第一行

java - 无法在mac上运行java程序

heroku - 使用rabbitmqadmin访问CloudAMQP/Heroku

python - Heroku: “Process exited with status 127” 部署 python Django App 后

Python/Django 在 Heroku 上的 gunicorn 上崩溃

scala - Play Framework : How to implement proper error handling

java - 如何使用正则表达式替换括号中的字符串?

Java套接字编程。如何在后台等待服务器响应?

proxy - Play Framework 可以充当代理服务器或反向代理吗?

linux - 无法安装 Play 2.0 支持 - INTELIJ 12