我有一个由Resteasy实现的REST服务。在我注入的服务中(由Guice)一个应用程序(实现了业务逻辑并已经注入了EJB),这个应用程序注入了@EJB。当我部署它时,Wildfly 10在底部给我例外。为什么Wildfly说在部署我的REST资源文件时注解了@RequestScoped,但它不是?
只要搜索错误消息,我发现我可能会错误配置CDI(Weld?)。
[org.jboss.weld.Bootstrap] (Weld Thread Pool -- 9) WELD-000167: Class digitallibrary.masterdata.dataservice.rest.api.resources.CurrencyResource is annotated with @RequestScoped but it does not declare an appropriate constructor therefore is not registered as a bean!
我有几个问题,因为我在这方面是新的,我需要一些方向前进,因为我不知道我是否有未读的东西有此应用程序启动并运行我遇到了一个奇怪的例子。
- 如何焊接到@EJB周围?我知道我的会话bean被注入了,但是我感觉它没有任何配置需要。
- 为什么Weld认为我的CurrencyResource类是注释?不是这样。
- 它总是需要配置吗?我已经检查过Github上的Wildfly示例项目,并且我还没有看到配置。
- 我必须使用beans.xml吗?
- 嵌套注入可能导致这个问题?
- 你需要我的项目中的其他代码示例吗?
请在下面找到我的应用程序代码:
RestEasy的资源类:
@Path("/currency")
public class CurrencyResource {
private final CurrencyAppInterface currencyApp;
@com.google.inject.Inject
public CurrencyResource(final CurrencyAppInterface currencyApp) {
this.currencyApp = currencyApp;
}
@GET
@Path("/currencies")
@Produces(MediaType.APPLICATION_JSON)
public Response getCurrencies() {
System.out.println("stuff");
Collection<String> currencies = new ArrayList<String>();
currencies.add("curr1");
currencies.add("curr2");
return Response
.status(Response.Status.OK)
.entity(currencies)
.build();
}
}
RestEasy的应用程序文件:
@ApplicationPath("/api")
public class DigitalLibraryMasterDataDataservice extends Application {
private Set<Object> singletons = new HashSet<Object>();
public DigitalLibraryMasterDataDataservice(@Context ServletContext servletContext) {
}
@Override
public Set<Object> getSingletons(){
Injector injector = Guice.createInjector(new CurrencyModule());
CurrencyModule currencyModule = injector.getInstance(CurrencyModule.class);
singletons.add(currencyModule);
return singletons;
}
}
应用程序文件,实现业务逻辑,并使用会话bean 。
public class CurrencyApplication implements CurrencyAppInterface {
@EJB(name = "CurrencySessionBean")
private CurrencySessionBean currencySessionBean;
private CurrencyMapperInterface currencyMapper;
@com.google.inject.Inject
public CurrencyApplication(CurrencyMapper currencyMapper) {
this.currencyMapper = currencyMapper;
}
@Override
public Collection<CurrencyDto> getAllCurrencies() throws DigitalLibraryMasterDataDataserviceApplicationException {
try {
Collection<Currency> currencies = this.currencySessionBean.getAllCurrencies();
Collection<CurrencyDto> mappedCurrencies = this.currencyMapper.MapCurrenciesToCurrencyDtos(currencies);
return mappedCurrencies;
} catch (Exception e) {
throw new DigitalLibraryMasterDataDataserviceApplicationException("Error in application", e);
}
}
}
会话Bean:从Wildfly
@Stateless
public class CurrencySessionBean implements CurrencySessionBeanLocalInterface {
@PersistenceContext(name = "DigitalLibrary.MasterData.Dataservice.PU")
private EntityManager em;
@Override
public Collection<Currency> getAllCurrencies() throws DigitalLibraryMasterDataDataserviceEjbSessionBeanException {
try {
List<Currency> currencies = this.em.createQuery("from Currency", Currency.class).getResultList();
return currencies;
} catch (Exception e) {
throw new DigitalLibraryMasterDataDataserviceEjbSessionBeanException("Error querying currencies", e);
}
}
}
完整的错误消息:
22:56:25,818 INFO [org.hibernate.envers.boot.internal.EnversServiceImpl] (ServerService Thread Pool -- 69) Envers integration enabled? : true
22:56:26,117 WARN [org.jboss.weld.Bootstrap] (Weld Thread Pool -- 9) WELD-000167: Class digitallibrary.masterdata.dataservice.rest.api.resources.CurrencyResource is annotated with @RequestScoped but it does not declare an appropriate constructor therefore is not registered as a bean!
22:56:26,275 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-5) MSC000001: Failed to start service jboss.deployment.unit."DigitalLibrary.MasterData.Dataservice.ear".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."DigitalLibrary.MasterData.Dataservice.ear".WeldStartService: Failed to start service
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Injector with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.parentInjector
at org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.parentInjector(GuiceResteasyBootstrapServletContextListener.java:0)
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:63)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:56)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
22:56:26,279 ERROR [org.jboss.as.controller.management-operation] (DeploymentScanner-threads - 1) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "DigitalLibrary.MasterData.Dataservice.ear")]) - failure description: {
"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"DigitalLibrary.MasterData.Dataservice.ear\".WeldStartService" => "org.jboss.msc.service.StartException in service jboss.deployment.unit.\"DigitalLibrary.MasterData.Dataservice.ear\".WeldStartService: Failed to start service
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Injector with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.parentInjector
at org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.parentInjector(GuiceResteasyBootstrapServletContextListener.java:0) "}, "WFLYCTL0412: Required services that are not installed:" =>["jboss.deployment.unit.\"DigitalLibrary.MasterData.Dataservice.ear\".WeldStartService"], "WFLYCTL0180: Services with missing/unavailable dependencies" => undefined }
jax-rs spec说服务必须有一个无参数构造函数。更改CurrencyResource以使用字段注入而不是构造函数注入。 –
出于好奇,是否有你使用Guice而不仅仅是默认的Java EE CDI的原因?我对萤火虫/焊缝不熟悉,但我认为Weld是JBoss/Wildfly的注入实施,这将消除对Guice的需求。 –