使用CDI而不是@ManagedBean:UnproxyableResolutionException,因为超类没有no-args构造函数 [英] Using CDI instead of @ManagedBean: UnproxyableResolutionException because super class has no no-args constructor

查看:102
本文介绍了使用CDI而不是@ManagedBean:UnproxyableResolutionException,因为超类没有no-args构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将CDI用于我的JSF/Java EE应用程序.我具有以下类层次结构:

I'm trying to use CDI for my JSF/Java EE application. I have the following class hierarchy:

/**
 * base controller class
 * also contains some final methods and an inner enum class declaration
 */
public abstract class AbstractCrudController<K, E> implements Serializable {
  private Class<E> entityClass;

  public AbstractCrudController(Class<E> entityClass) {
    this.entityClass = entityClass;
  }

  // ...
}


import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class CategoryController extends AbstractCrudController<Long, Category> implements Serializable {
  public CategoryController() {
    super(Category.class);
  }
  //...
}

当我尝试在GF 3.1上部署应用程序时,出现以下CDI/Weld异常:

When I try to deploy the application on GF 3.1, I get the following CDI/Weld exception:

严重:加载时异常 app:WELD-001435普通范围的bean 班级 com.web.AbstractCrudController 无法代理,因为它没有 无参数构造函数. org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001435普通范围的Bean类 com.web.AbstractCrudController 无法代理,因为它没有 无参数构造函数. 在org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:215) 在org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:166) 在org.jboss.weld.util.Proxies.getUnproxyableTypesException(Proxies.java:191) 在org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:134) 在org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:148) 在org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:363) 在org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:349) 在org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:416) 在org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:178) 在org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128) 在org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:265) 在com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:402) 在com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:221) 在org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:351) 在com.sun.enterprise.v3.admin.CommandRunnerImpl $ 1.execute(CommandRunnerImpl.java:360) 在com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:375) 在com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1072) 在com.sun.enterprise.v3.admin.CommandRunnerImpl.access上获得1200美元(CommandRunnerImpl.java:101) 在com.sun.enterprise.v3.admin.CommandRunnerImpl $ ExecutionContext.execute(CommandRunnerImpl.java:1221)处 在com.sun.enterprise.v3.admin.CommandRunnerImpl $ ExecutionContext.execute(CommandRunnerImpl.java:1210)处 在com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:375) 在com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209) 位于com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:166) 在com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117) 在com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:234) 在com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:824) 在com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:721) 在com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1014) 在com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:220) 在com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135) 在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102) 在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) 在com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76) 在com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) 在com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) 在com.sun.grizzly.ContextTask.run(ContextTask.java:69) 在com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:530) 在com.sun.grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:511) 在java.lang.Thread.run(Thread.java:637)

SEVERE: Exception while loading the app : WELD-001435 Normal scoped bean class com.web.AbstractCrudController is not proxyable because it has no no-args constructor. org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001435 Normal scoped bean class com.web.AbstractCrudController is not proxyable because it has no no-args constructor. at org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:215) at org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:166) at org.jboss.weld.util.Proxies.getUnproxyableTypesException(Proxies.java:191) at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:134) at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:148) at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:363) at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:349) at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:416) at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:178) at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128) at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:265) at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:402) at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:221) at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:351) at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:360) at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:375) at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1072) at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:101) at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1221) at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1210) at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:375) at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209) at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:166) at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:234) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:824) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:721) at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1014) at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:220) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) at com.sun.grizzly.ContextTask.run(ContextTask.java:69) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:530) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:511) at java.lang.Thread.run(Thread.java:637)

即使我在基类中添加了一个无参数的构造函数,Weld仍然会抱怨相同的例外,即该类不可代理,因为它具有最终方法.为什么WELD强迫我更改班级设计?使用JSF @ManagedBean批注,一切正常.

Even if I add a no-args constructor to the base class, Weld still complains with the same exception that the class is not proxyable because it has final methods. Why does WELD force me to change my class design? Everything worked fine using the JSF @ManagedBean annotation.

我将不胜感激. 谢, 西奥

I would appreciate any help. Thank, Theo

推荐答案

为什么WELD强迫我更改班级设计?使用JSF @ManagedBean批注,一切正常.

Why does WELD force me to change my class design? Everything worked fine using the JSF @ManagedBean annotation.

Weld/CDI的工作方式不同.我的理解是,当您使用注入获取对bean的引用时,在大多数情况下获得的是代理对象.该代理对象对您的bean进行了子类化,并覆盖了实现委托的方法.这对CDI可以代理的类引入了一些限制.

Well, Weld/CDI doesn't work the same way. My understanding is that when you use injection to obtain a reference to a bean, what you get is in most cases a proxy object. This proxy object sub-classes your bean and overrides the methods to implement delegation. And this introduces some restrictions on the classes CDI can proxy.

CDI规范如下所示:

The CDI spec puts it like this:

5.4.1.不可替代的豆类型

某些合法的bean类型不能是 由容器代理:

5.4.1. Unproxyable bean types

Certain legal bean types cannot be proxied by the container:

  • 没有非私有构造函数且没有no的类 参数,
  • 被声明为final或具有final方法的类
  • 原始类型
  • 和数组类型.
  • classes which don't have a non-private constructor with no parameters,
  • classes which are declared final or have final methods,
  • primitive types,
  • and array types.

如果一个注入点的声明 类型不能由 容器解析为带有 正常范围,容器 自动检测到问题并 将其视为部署问题.

If an injection point whose declared type cannot be proxied by the container resolves to a bean with a normal scope, the container automatically detects the problem and treats it as a deployment problem.

我的建议是使这些方法不是最终的.

My suggestion would be to make the methods non final.

  • CDI规范
    • 第5.4节. 客户代理"
    • 第5.4.1节不可代理的bean类型"
    • 第6.3节. 正常范围和伪范围"
    • CDI Specification
      • Section 5.4. "Client proxies"
      • Section 5.4.1 "Unproxyable bean types"
      • Section 6.3. "Normal scopes and pseudo-scopes"

      这篇关于使用CDI而不是@ManagedBean:UnproxyableResolutionException,因为超类没有no-args构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆