استخدام CDI بدلاً منManagedBean:UnproxyableResolutionException لأن الفئة الفائقة لا تحتوي على مُنشئ بدون وسيطات

StackOverflow https://stackoverflow.com/questions/3840240

  •  27-09-2019
  •  | 
  •  

سؤال

أحاول استخدام 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 التالي:

شديد:استثناء أثناء تحميل التطبيق: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(المدقق.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) at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifدورة .java:402) at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:221) في org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:351) at 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) at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1221) at 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) في كوم.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 (الموضوع.java:637)

حتى لو قمت بإضافة مُنشئ بدون وسيطات إلى الفئة الأساسية، لا يزال Weld يشكو مع نفس الاستثناء وهو أن الفئة غير قابلة للتوكيل لأنها تحتوي على طرق نهائية.لماذا يجبرني WELD على تغيير تصميم صفي؟كل شيء سار على ما يرام باستخدام التعليق التوضيحي JSF @ManagedBean.

وسأكون ممتنا أي مساعدة.شكر ثيو

هل كانت مفيدة؟

المحلول

لماذا يجبرني Weld على تغيير تصميم الفصل الخاص بي؟ كل شيء يعمل بشكل جيد باستخدام التعليق التوضيحي JSFManagedBean.

حسنًا ، لا يعمل اللحام/CDI بنفس الطريقة. أفهم أنه عندما تستخدم الحقن للحصول على إشارة إلى الفول ، ما تحصل عليه أغلب الحالات كائن وكيل. هذا الوكيل الكائن الفئات الفرعية الخاصة بك الفول ويتجاوز طرق تنفيذ التفويض. وهذا يقدم بعض القيود المفروضة على الفصول التي يمكن لـ CDI الوكيل.

مواصفات CDI تضعها مثل هذا:

5.4.1. أنواع الفاصوليا التي لا يمكن الاستعداد لها

لا يمكن أن يتم تحريك بعض أنواع الفاصوليا القانونية بواسطة الحاوية:

  • الفصول التي لا تحتوي على مُنشئ غير خاص بدون معلمات ،
  • الفصول الدراسية التي تم إعلانها نهائيًا أو لها طرق نهائية ،
  • الأنواع البدائية ،
  • وأنواع الصفيف.

إذا كانت نقطة الحقن التي لا يمكن أن يتم تنفيس نوعها المعلن بواسطة الحاوية إلى حبة ذات نطاق عادي ، فإن الحاوية تكتشف المشكلة تلقائيًا وتعاملها كمشكلة نشر.

اقتراحي هو جعل الأساليب غير نهائية.

مراجع

  • مواصفات CDI
    • القسم 5.4. "وكلاء العميل"
    • القسم 5.4.1 "أنواع الفاصوليا غير القابلة للاستياء"
    • القسم 6.3. "نطاقات طبيعية ومربعات زائفة"

نصائح أخرى

أنا بصدد الترحيل من الفاصوليا المُدارة بواسطة JSF إلى الفاصوليا المُدارة بواسطة CDI، ولقد أكدت للتو أنني قادر على الاستخدام ممتاز بنجاح في حبة CDI المنحدرة (مع مؤهل @Descendant "مخصص") التي "تمدد" حبة CDI السلف (مع مؤهل @Default).

سلف فول CDI مع المؤهل الافتراضي:

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

تحتوي حبة الجد على ما يلي:

@PostConstruct
protected void init() {

سليل حبة CDI مع مؤهل @Descendant:

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

الفول السليل لديه ما يلي:

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

اضطررت إلى إضافة/استخدام super.init()، لأن الأساليب الموجودة في حبة CDI السلف كانت ترفع NullPointerException، حيث لم يتم تنفيذ @PostConstruct الخاص بفاصوليا السلف في CDI @Descendant bean.

لقد رأيت / سمعت / قرأت أنه يوصى باستخدام @PostConstruct بدلاً من طريقة Constructor عند استخدام CDI، لذلك كان مُنشئ الفول السلف لديه منطق "التهيئة"، وتم استدعاء/تنفيذ مُنشئ الفول السلف تلقائيًا عند استخدام الفاصوليا المُدارة بواسطة JSF.

لأن الإجابة المقبولة صحيحة ولكن غير مكتملة أعتقد أنه يمكنني إضافة سنتان فقط للقراء المستقبليين.

يمكن حل المشكلة التي واجهتها OP بطريقتين:

  1. عن طريق إزالة final الكلمة الرئيسية من الأساليب والفئة نفسها
  2. وضع علامة على مثل هذا "فئة غير قابلة للاشمئزاز" مع @Singleton أو @Dependent النطاق الزائف (بالطبع إذا كان من المنطقي). سيعمل لأن CDI لا ينشئ كائن وكيل للفاصوليا الزائفة.

في حالة استخدام OP ، تم التوصية بـ IMHO النهج الثاني ، حيث يمكن تمييز وحدات التحكم بالتأكيد على أنها مفردة.

أتمنى أن يساعد شخص ما

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top