JobRunr:ReflectionUtils.newInstance 中的 InstantiationException

问题描述 投票:0回答:1

我正在使用 JobRunr 6.3.0 来调度 Java 中的重复后台作业,并且遇到反射访问问题。

我试图拥有一个实现作业调度逻辑的抽象类,创建一个调用在每个子类中实现的抽象方法的作业。像这样:

public abstract class Blubb {

    public Blubb() {
        this(...defaultArgs);
    }

    protected Blubb(defaultArgs) {
        // set up
    }

    protected abstract String name();

    protected abstract Iterator<Object> getObjectsFromExternalSource();

    public void load() {
        JobScheduler scheduler = JobRunr
            .configure()
            .useStorageProvider(new InMemoryStorageProvider())
            .useBackgroundJobServer()
            .initialize()
            .getJobScheduler();

        scheduler.createRecurrently(
            RecurringJobBuilder
                .aRecurringJob()
                .withId(name())
                .withDuration(Duration.ofSeconds(10))
                .withDetails(this::run)
                .withAmountOfRetries(2)
        );
    }

    public void run() {
        Iterator<Object> objects = getObjectsFromExternalSource();

        while (objects.hasNext()) {
            // do stuff
        }
    }
}

作业创建工作正常,并且数据库中的作业看起来很好:

{
  "_id": "name",
  "version": 0,
  "jobAsJson": "{\"version\":0,\"jobSignature\":\"org.example.blah.Blubb.run()\",\"jobName\":\"org.example.blah.Blubb.run()\",\"amountOfRetries\":2,\"labels\":[],\"jobDetails\":{\"className\":\"org.example.blah.Blubb\",\"staticFieldName\":null,\"methodName\":\"run\",\"jobParameters\":[],\"cacheable\":true},\"id\":\"name\",\"scheduleExpression\":\"PT10M\",\"zoneId\":\"Etc/UTC\",\"createdAt\":\"2023-08-25T06:39:29.844981739Z\"}",
  "createdAt": {
    "$numberLong": "1692945569844"
  }
}

但是每次它尝试运行该作业时,我都会遇到以下异常:

WARN  o.j.server.BackgroundJobPerformer - Job(id=a444fd50-843a-4464-88a1-e51530056b3f, jobName='org.example.blah.Blubb.run()') processing failed: An exception occurred during the performance of the job
org.jobrunr.JobRunrException: JobRunr encountered a problematic exception. Please create a bug report (if possible, provide the code to reproduce this and the stacktrace)
    at org.jobrunr.JobRunrException.shouldNotHappenException(JobRunrException.java:43)
    at org.jobrunr.utils.reflection.ReflectionUtils.newInstance(ReflectionUtils.java:156)
    at org.jobrunr.server.runner.AbstractBackgroundJobRunner$BackgroundJobWorker.getJobToPerform(AbstractBackgroundJobRunner.java:46)
    at org.jobrunr.server.runner.AbstractBackgroundJobRunner$BackgroundJobWorker.run(AbstractBackgroundJobRunner.java:36)
    at org.jobrunr.server.runner.AbstractBackgroundJobRunner.run(AbstractBackgroundJobRunner.java:20)
    at org.jobrunr.server.BackgroundJobPerformer.runActualJob(BackgroundJobPerformer.java:89)
    at org.jobrunr.server.BackgroundJobPerformer.performJob(BackgroundJobPerformer.java:64)
    at org.jobrunr.server.BackgroundJobPerformer.run(BackgroundJobPerformer.java:42)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.InstantiationException: null
    at java.base/jdk.internal.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at org.jobrunr.utils.reflection.ReflectionUtils.newInstance(ReflectionUtils.java:154)

知道我做错了什么吗?这是类构造函数的问题吗?据我了解,JobRunr 想要一个无参数的默认构造函数? (我在上面的抽象类和子类中都有一个公共无参数构造函数和一个附加的受保护构造函数。但即使我删除所有自定义构造函数,我也会遇到相同的错误。)

java reflection constructor abstract-class jobrunr
1个回答
0
投票

罗纳德在这里 - JobRunr的创建者。

您看到的异常是因为您尝试实例化类型为

Blubb
的作业(在作业的 json 中提到),这是一个抽象类。您无法创建抽象类的实例,因此出现异常。

就您而言,我建议您查看像 Spring 这样的框架,并将

@Recurring
注释添加到不同的作业中。这也将使您的代码更具可读性。

最重要的是,

JobScheduler
实例应该是单例(出于性能原因)。

© www.soinside.com 2019 - 2024. All rights reserved.