我有一个调用某些函数的现有端点,并且在对端点进行休息调用时工作正常。然后我想创建一个调度程序来定期调用该函数。调度程序本身按预期工作,但现在在调度函数期间函数出现意外异常。端点的其余部分仍然有效。由于问题似乎是 RequestScoped bean,我尝试了ActivateRequestContent,但没有任何变化。
下面是最低限度可重现的示例,可以更好地解释问题。
编辑:我不想修改服务或某些外部 cron。我希望解决方案位于 Scheduler 中。
我有资源:
@Path("/hello")
public class GreetingResource {
@Inject
GreetingService greetingService;
@GET
public String hello() {
return greetingService.getGreetings();
}
}
服务:
@ApplicationScoped
public class GreetingService {
@Inject
RequestBean requestBean;
public String getGreetings() {
//do logic, call other services, save to DB, etc
if (requestBean.getAcceptLanguage().equals("en")) {
return "Hello from RESTEasy Reactive";
} else {
return "Hola desde RESTEasy Reactive";
}
}
}
还有一个 RequestScoped bean。
@RequestScoped
public class RequestBean {
private String acceptLanguage;
RequestBean(HttpHeaders httpHeaders) {
acceptLanguage = httpHeaders.getHeaderString(HttpHeaders.ACCEPT_LANGUAGE);
if (acceptLanguage == null || acceptLanguage.isBlank()) {
this.acceptLanguage = "en";
}
}
public String getAcceptLanguage() {
return acceptLanguage;
}
}
端点在 test 和 postman 中工作。
但现在我需要定期做同样的工作。
所以我添加了调度程序。
@ApplicationScoped
public class Scheduler {
@Inject
GreetingService greetingService;
@Scheduled(every = "10s")
@ActivateRequestContext
public void scheduledTask() {
try {
Log.info("Scheduler is starting");
greetingService.getGreetings();
Log.info("Scheduler is finished");
} catch (Exception e) {
Log.error("Error while running scheduler", e);
}
}
}
我预计不会有异常,但我在 ScheduledTask 中遇到异常。
java.lang.IllegalStateException: No RESTEasy Reactive request in progress
at org.jboss.resteasy.reactive.server.injection.ContextProducers.getContext(ContextProducers.java:149)
at org.jboss.resteasy.reactive.server.injection.ContextProducers.headers(ContextProducers.java:52)
at org.jboss.resteasy.reactive.server.injection.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_Bean.doCreate(Unknown Source)
at org.jboss.resteasy.reactive.server.injection.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_Bean.create(Unknown Source)
at org.jboss.resteasy.reactive.server.injection.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_Bean.create(Unknown Source)
at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:79)
at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:75)
at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.c2(Unknown Source)
at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.computeIfAbsent(Unknown Source)
at io.quarkus.arc.impl.RequestContext.getIfActive(RequestContext.java:75)
at io.quarkus.arc.impl.ClientProxies.getSingleContextDelegate(ClientProxies.java:28)
at jakarta.ws.rs.core.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_ClientProxy.arc$delegate(Unknown Source)
at jakarta.ws.rs.core.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_ClientProxy.getHeaderString(Unknown Source)
at com.example.RequestBean.<init>(RequestBean.java:12)
at com.example.RequestBean_Bean.doCreate(Unknown Source)
at com.example.RequestBean_Bean.create(Unknown Source)
at com.example.RequestBean_Bean.create(Unknown Source)
at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:79)
at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:75)
at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.c0(Unknown Source)
at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.computeIfAbsent(Unknown Source)
at io.quarkus.arc.impl.RequestContext.getIfActive(RequestContext.java:75)
at io.quarkus.arc.impl.ClientProxies.getSingleContextDelegate(ClientProxies.java:28)
at com.example.RequestBean_ClientProxy.arc$delegate(Unknown Source)
at com.example.RequestBean_ClientProxy.getAcceptLanguage(Unknown Source)
at com.example.GreetingService.getGreetings(GreetingService.java:16)
at com.example.GreetingService_ClientProxy.getGreetings(Unknown Source)
at com.example.Scheduler.scheduledTask(Scheduler.java:21)
at com.example.Scheduler_Subclass.scheduledTask$$superforward(Unknown Source)
at com.example.Scheduler_Subclass$$function$$1.apply(Unknown Source)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
at io.quarkus.arc.impl.ActivateRequestContextInterceptor.invoke(ActivateRequestContextInterceptor.java:124)
at io.quarkus.arc.impl.ActivateRequestContextInterceptor.aroundInvoke(ActivateRequestContextInterceptor.java:33)
at io.quarkus.arc.impl.ActivateRequestContextInterceptor_Bean.intercept(Unknown Source)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
at com.example.Scheduler_Subclass.scheduledTask(Unknown Source)
at com.example.Scheduler_ClientProxy.scheduledTask(Unknown Source)
at com.example.Scheduler_ScheduledInvoker_scheduledTask_b06a23f86c5479393959068a663c2a2a98c84093.invokeBean(Unknown Source)
at io.quarkus.scheduler.common.runtime.DefaultInvoker.invoke(DefaultInvoker.java:24)
at io.quarkus.scheduler.common.runtime.StatusEmitterInvoker.invoke(StatusEmitterInvoker.java:35)
at io.quarkus.scheduler.runtime.SimpleScheduler$ScheduledTask.doInvoke(SimpleScheduler.java:443)
at io.quarkus.scheduler.runtime.SimpleScheduler$ScheduledTask$2.call(SimpleScheduler.java:425)
at io.quarkus.scheduler.runtime.SimpleScheduler$ScheduledTask$2.call(SimpleScheduler.java:422)
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$0(ContextImpl.java:178)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:279)
at io.vertx.core.impl.ContextImpl.lambda$internalExecuteBlocking$2(ContextImpl.java:210)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1512)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
相关依赖:
<quarkus.platform.version>3.8.5</quarkus.platform.version>
...
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-scheduler</artifactId>
</dependency>
编辑2: 解决方案确实有效,但不太好。
given()
.when()
.get("/hello")
.then()
.statusCode(200);
-> 与 1-3 种解决方案相比,这看起来非常好,但在主代码中放心导入感觉是错误的。是不是搞错了?
您可以尝试使用 Quarkus RestClient 访问 /hello 路径。如果您需要处理身份验证,您可以执行以下操作:
访问API的类
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.ws.rs.*;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
@RegisterRestClient
public interface Api {
@GET
@Path("/hello")
JsonNode hello(@HeaderParam("Authorization") String token);
}
然后是你预定的事情
@RestClient
Api api;
@Scheduled(every = "10s")
void doTheJob(){
String token;
// do something to get the token
api.hello(token);
}