繁体   English   中英

为什么Wildfly说在部署时,我的REST资源文件带有@RequestScoped注释,但是没有注释?

[英]Why Wildfly says that at deploy my REST resource file is annotated with @RequestScoped, however it is not?

我有一个由Resteasy实现的REST服务。 在服务中,我(由Guice)注入了一个应用程序(实现了业务逻辑并且也注入了EJB),该应用程序注入了@EJB。 当我部署它时,Wildfly 10在底部给出了例外。

只是搜索错误消息,我发现我的CDI(焊接?)配置错误。

 [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!

我有几个问题,因为我是该领域的新手,并且我需要一些前进的方向,因为我不知道我是否还没有读懂一些东西来启动和运行该应用程序,并且遇到了一个奇怪的案例。

  • Weld如何成为@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:

@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);
        }
    }
}

来自Wildfly的完整错误消息:

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 }

首先,您的构造函数带有注释

@com.google.inject.Inject

这绝对不是火腿肠进样注释来自javax.inject包。

其次,您的bean必须具有不带参数的构造函数。 如果希望通过构造函数@Inject,则必须是CDI知道的bean。

你可以试试:

  • 从CurrencyResource构造函数中删除参数。
  • 修复@Inject批注(javax.inject包)

要回答您的标题问题,请执行以下操作:默认情况下,在WildFly(如果启用了CDI和JAX-RS)中,任何JAX-RS资源都由CDI扩展进行了分析,如果未使用范围注释进行注释,则会自动添加@RequestScoped

另外,对JAX-RS资源的构造函数注入的支持是可选的,即,规范不需要。 而且我不确定RESTEasy是否支持此功能...我认为不支持。

这只是先前答案的补充。

当您将构造函数更改为不带参数时,还可以将注入操作移至init方法,而不是按字段进行注入。 这就是我们在公司中这样做的方式,我们也将wildfly 10与标准CDI一起使用。

想要这样:

public CurrencyResource(){
}

@Javax.inject.Inject
public void init(final CurrencyAppInterface currencyApp){
  this.currencyApp = currencyApp;
}

感谢所有答案!

我的代码中有很多问题:

  • 并非所有实现某些业务逻辑的代码都由@EJB注释
  • 我想通过Guice注入,然后以某种方式混合进口
  • 有一个@EJB注入,在这里我引用了类而不是接口

我为解决这个问题所做的工作:

  • 我通过业务逻辑类进行了重构,它们都是无状态会话bean
  • 它们可以很容易地被CDI包括在内,并且不再需要Guice
  • 我也解决了参考问题

效果不好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM