Использование CDI вместо @ManagedBean: UnproxyableResolutionException, потому что у суперкласса нет конструктора без аргументов - PullRequest
8 голосов
/ 01 октября 2010

Я пытаюсь использовать CDI для моего приложения JSF / Java EE. У меня есть следующая иерархия классов:

/**
 * 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:

SEVERE: исключение при загрузке приложение: WELD-001435 Нормальный объем фасоли учебный класс com.web.AbstractCrudController не является прокси, потому что он не имеет Конструктор без аргументов. org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001435 Класс бобов нормального объема 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) at java.lang.Thread.run (Thread.java:637)

Даже если я добавлю конструктор без аргументов в базовый класс, Weld все равно будет жаловаться с тем же исключением, что класс не является проксируемым, поскольку у него есть финальные методы. Почему WELD заставляет меня менять дизайн моего класса? Все работало нормально, используя аннотацию JSF @ManagedBean.

Буду признателен за любую помощь. Поблагодарить, Тео

Ответы [ 3 ]

16 голосов
/ 01 октября 2010

Почему WELD заставляет меня менять дизайн моего класса? Все работало нормально, используя аннотацию JSF @ManagedBean.

Ну, Weld / CDI работает не так. Насколько я понимаю, когда вы используете инъекцию для получения ссылки на бин, вы получаете в большинстве случаев прокси-объект. Этот прокси-объект подклассов вашего компонента и переопределяет методы для реализации делегирования. И это вводит некоторые ограничения на классы CDI может прокси.

В спецификации CDI это выглядит так:

5.4.1. Непроксируемые типы бинов

Некоторые легальные типы бинов не могут быть прокси в контейнере:

  • классы, которые не имеют не приватного конструктора без параметры,
  • классы, которые объявлены как final или имеют финальные методы,
  • примитивных типов,
  • и типы массивов.

Если точка впрыска, объявленная тип не может быть прокси Контейнер превращается в боб с нормальная сфера, контейнер автоматически обнаруживает проблему и рассматривает это как проблему развертывания.

Мое предложение было бы сделать методы не окончательными.

Ссылки

  • CDI Спецификация
    • Раздел 5.4. «Клиентские прокси»
    • Раздел 5.4.1 «Непроксируемые типы бинов»
    • Раздел 6.3. "Нормальные области видимости и псевдоскопы"
0 голосов
/ 11 ноября 2015

Поскольку принятый ответ правильный, но неполный, я думаю, что могу добавить свои два цента только для будущих читателей.

Проблема, с которой столкнулся ОП, может быть решена двумя способами:

  1. Удаляя ключевое слово final из методов и самого класса
  2. Пометка такого "проксифицируемого класса" псевдоскопом @Singleton или @Dependent (конечно, если это имеет смысл).Это будет работать, потому что CDI не создает прокси-объект для псевдообозначенных bean-компонентов.

В случае использования OP рекомендовался второй подход IMHO, поскольку контроллеры определенно могут быть помечены как одиночные.

Надеюсь, это кому-нибудь поможет

0 голосов
/ 21 ноября 2012

Я нахожусь в процессе перехода от управляемых компонентов JSF к управляемым компонентам CDI, и я только что подтвердил, что могу успешно использовать super в компоненте-потомке CDI (с «настраиваемым» квалификатором @Descendant), который «расширяет» bean-компонент CDI-предка (с квалификатором @Default).

Предок CDI-бина с квалификатором @Default:

@Default
@Named("pf_pointOfContactController")
@SessionScoped
public class pf_PointOfContactController implements Serializable {

Бин-предок имеет следующее:

@PostConstruct
protected void init() {

Компонент bean-компонента CDI с квалификатором @Descendant:

@Descendant
@Named("pf_orderCustomerPointOfContactController")
@SessionScoped
public class pf_OrderCustomerPointOfContactController extends pf_PointOfContactController {

Компонент-компонент Bean имеет следующее:

@PostConstruct
public void init(){
    super.init();

Мне пришлось добавить / использовать super.init (), потому что методыв bean-компоненте CDI предка возникало исключение NullPointerException, поскольку @PostConstruct бина-предка не выполняется в компоненте CDI @Descendant.

Я видел / слышал / читал, что рекомендуется использовать @PostConstruct вместо метода Constructor, когдаиспользуя CDI, конструктор bean-компонента-предка имел логику инициализации, а конструктор bean-компонента-предка автоматически вызывался / выполнялся при использовании управляемых JSF-компонентов.

...