1. लक्ष्यहीन, पहचान योग्य 'बीन' अशक्त करने का संकल्प लिया
यह इस बात से उबलता है कि प्रबंधित बीन का उदाहरण स्वयं उस पहचानकर्ता (ईएलएन बीन नाम) द्वारा ईएल में नहीं पाया जा सकता है जैसे कि #{bean}
।
कारण की पहचान को तीन चरणों में तोड़ा जा सकता है:
ए। सेम का प्रबंधन कौन कर रहा है?
ख। (डिफ़ॉल्ट) प्रबंधित बीन नाम क्या है?
सी। बैकिंग बीन क्लास कहाँ है?
1 क। सेम का प्रबंधन कौन कर रहा है?
पहला कदम यह जाँचना होगा कि बीन के प्रबंधन के लिए कौन सा सेम प्रबंधन ढांचा जिम्मेदार है। यह JSF के माध्यम से है @ManagedBean
? या यह सीडीआई के माध्यम से है @Named
? या यह वसंत के माध्यम से है @Component
? क्या आप यह सुनिश्चित कर सकते हैं कि आप कई सेम प्रबंधन ढांचे विशिष्ट एनोटेशन को एक ही बैकिंग बीन क्लास पर नहीं मिला रहे हैं? जैसे @Named @Component
, या @Named @ManagedBean
, या @ManagedBean @Component
। ये गलत है। बीन को अधिकतम एक बीन प्रबंधन ढांचे द्वारा प्रबंधित किया जाना चाहिए और उस ढांचे को ठीक से कॉन्फ़िगर किया जाना चाहिए। यदि आपको पहले से ही पता नहीं है कि किसे चुनना है, तो हेड टू बैकिंग बीन्स (@ManagedBean) या CDI बीन्स (@ नाम)? और स्प्रिंग जेएसएफ एकीकरण: जेएसएफ प्रबंधित बीन में स्प्रिंग घटक / सेवा को कैसे इंजेक्ट किया जाए?
यदि यह JSF है जो सेम के माध्यम से प्रबंधन कर रहा है @ManagedBean
, तो आपको निम्नलिखित सुनिश्चित करने की आवश्यकता है:
faces-config.xml
जड़ घोषणा JSF 2.0 के साथ संगत है। तो XSD फ़ाइल और कम से कम JSF 2.0 या उच्चतर निर्दिष्ट version
करना चाहिए और इस प्रकार 1.x नहीं।
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
JSF 2.1 के लिए, बस की जगह 2_0
और 2.0
से 2_1
और 2.1
क्रमशः।
यदि आप JSF 2.2 या उच्चतर पर हैं, तो सुनिश्चित करें कि आप सभी स्थानों पर xmlns.jcp.org
नाम स्थान का उपयोग कर रहे हैं java.sun.com
।
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
JSF 2.3 के लिए, बस की जगह 2_2
और 2.2
से 2_3
और 2.3
क्रमशः।
आप गलती से आयात नहीं किया javax.annotation.ManagedBean
बजाय javax.faces.bean.ManagedBean
। आईडीई स्वतः पूर्ण के साथ देखें, ग्रहण को सूची में पहले आइटम के रूप में गलत तरीके से स्वचालित रूप से जाना जाता है।
- आपने एक अलग प्रबंधित बीन नाम के साथ एक ही बैकिंग बीन क्लास पर
@ManagedBean
JSF 1.x शैली <managed-bean>
प्रविष्टि द्वारा ओवरराइड नहीं किया faces-config.xml
। इस पर एक पूर्वता होगी @ManagedBean
। faces-config.xml
JSF 2.0 के बाद से प्रबंधित बीन का पंजीकरण आवश्यक नहीं है, बस इसे हटा दें।
- JSF API संबंधित JAR में आपका रनटाइम क्लासपाथ स्वच्छ और डुप्लिकेट से मुक्त है। सुनिश्चित करें कि आप कई JSF कार्यान्वयन (Mojarra और MyFaces) का मिश्रण नहीं कर रहे हैं। सुनिश्चित करें कि आप एक और JSF या यहाँ तक कि Java EE API JAR फ़ाइल को वेबएप पर उपलब्ध नहीं कराते हैं जब लक्ष्य कंटेनर पहले ही JSF API को बॉक्स से बाहर कर देता है। जेएसएफ इंस्टॉलेशन निर्देशों के लिए हमारे जेएसएफ विकी पेज का " इंस्टॉलेशन जेएसएफ" अनुभाग भी देखें । यदि आप कंटेनर-बंडल किए गए JSF को WAR से कंटेनर के बजाय स्वयं ही अपग्रेड करना चाहते हैं, तो सुनिश्चित करें कि आपने लक्ष्य कंटेनर को WAR- बंडल JSF API / impl का उपयोग करने का निर्देश दिया है।
- यदि आप एक JAR में JSF प्रबंधित बीन्स की पैकेजिंग कर रहे हैं, तो सुनिश्चित करें कि JAR में कम से कम JSF 2.0 संगत है
/META-INF/faces-config.xml
। यह भी देखें कि जेएसएफ प्रबंधित बीन्स को कैसे संदर्भित करें जो एक जार फ़ाइल में प्रदान किए गए हैं?
आप कर रहे हैं वास्तव में जुरासिक JSF 1.x का उपयोग कर, और आप अपग्रेड नहीं कर सकते, तो आप के माध्यम से सेम रजिस्टर करने की आवश्यकता <managed-bean>
में faces-config.xml
के बजाय @ManagedBean
। अपने प्रोजेक्ट बिल्ड पथ को ठीक करने के लिए मत भूलें जैसे कि आपके पास JSF 2.x लाइब्रेरी अब और नहीं है (ताकि @ManagedBean
एनोटेशन भ्रमपूर्ण रूप से सफलतापूर्वक संकलित न हो)।
यदि यह CDI है, जो सेम के माध्यम से प्रबंधन कर रहा है @Named
, तो आपको निम्नलिखित सुनिश्चित करने की आवश्यकता है:
CDI 1.0 (Java EE 6) को /WEB-INF/beans.xml
WAR में CDI को सक्षम करने के लिए एक फ़ाइल की आवश्यकता होती है । यह खाली हो सकता है या इसमें केवल निम्नलिखित सामग्री हो सकती है:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
CDI 1.1 (Java EE 7) बिना किसी beans.xml
या खाली beans.xml
फाइल के, या उपरोक्त CDI 1.0 संगत CDI 1.0 beans.xml
के समान व्यवहार करेगा। वहाँ जब एक CDI 1.1 संगत beans.xml
एक स्पष्ट साथ version="1.1"
, तो यह डिफ़ॉल्ट रूप से केवल पंजीकृत करेंगे @Named
सेम के साथ एक स्पष्ट CDI गुंजाइश टिप्पणी के रूप में इस तरह के @RequestScoped
, @ViewScoped
, @SessionScoped
, @ApplicationScoped
, आदि मामले में आप सब सेम रजिस्टर करने के लिए के रूप में CDI कामयाब सेम इरादा रखते हैं, यहां तक कि उन में कोई स्पष्ट बिना CDI गुंजाइश, सेट के /WEB-INF/beans.xml
साथ संगत CDI 1.1 का उपयोग करें bean-discovery-mode="all"
(डिफ़ॉल्ट है bean-discovery-mode="annotated"
)।
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
CDI 1.1+ के साथ bean-discovery-mode="annotated"
(डिफ़ॉल्ट) का उपयोग करते समय , सुनिश्चित करें कि आपने गलती से एक JSF स्कोप आयात नहीं किया था जैसे कि javax.faces.bean.RequestScoped
CDI स्कोप javax.enterprise.context.RequestScoped
। आईडीई स्वत: पूर्ण के साथ देखें।
- जब Mojarra 2.3.0-2.3.2 और CDI 1.1+
bean-discovery-mode="annotated"
(डिफ़ॉल्ट) का उपयोग कर रहे हैं, तो आपको एक बग के कारण Mojarra को 2.3.3 या नए में अपग्रेड करने की आवश्यकता है । यदि आप अपग्रेड नहीं कर सकते हैं, तो आपको या तो सेट करने की जरूरत bean-discovery-mode="all"
है beans.xml
, या जेएसएफ 2.3 विशिष्ट @FacesConfig
एनोटेशन को डब्ल्यूएआर में एक अनियंत्रित वर्ग पर डालने की जरूरत है (आमतौर पर किसी तरह का एक एप्लिकेशन स्कोप्ड स्टार्टअप क्लास)।
- गैर-जावा ईई कंटेनर जैसे टॉमकैट और जेट्टी सीडीआई बंडल के साथ जहाज नहीं करता है। आपको इसे मैन्युअल रूप से इंस्टॉल करने की आवश्यकता है। यह सिर्फ लाइब्रेरी JAR (एस) को जोड़ने की तुलना में थोड़ा अधिक काम है। टॉमकैट के लिए, सुनिश्चित करें कि आप इस उत्तर में दिए गए निर्देशों का पालन करते हैं: टॉमकैट पर सीडीआई कैसे स्थापित और उपयोग करें?
- CDI API संबंधित JAR में आपका रनटाइम क्लासपाथ स्वच्छ और डुप्लिकेट से मुक्त है। सुनिश्चित करें कि आप कई CDI कार्यान्वयन (वेल्ड, OpenWebBeans, आदि) का मिश्रण नहीं कर रहे हैं। सुनिश्चित करें कि आप किसी अन्य CDI या यहां तक कि Java EE API JAR फ़ाइल को वेबैप के साथ प्रदान नहीं करते हैं जब लक्ष्य कंटेनर पहले से ही CDI API को बॉक्स से बाहर कर देता है।
यदि आप एक JAR में JSF विचारों के लिए CDI प्रबंधित बीन्स की पैकेजिंग कर रहे हैं, तो सुनिश्चित करें कि JAR में कम से कम एक वैध /META-INF/beans.xml
(जिसे खाली रखा जा सकता है)।
मामले में यह स्प्रिंग है जो सेम के माध्यम से प्रबंध कर रहा है@Component
, तो आपको निम्नलिखित के बारे में सुनिश्चित करने की आवश्यकता है:
वसंत को इसके प्रलेखन के अनुसार स्थापित और एकीकृत किया जा रहा है । महत्वपूर्ण रूप से, आपको कम से कम यह करने की आवश्यकता है web.xml
:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
और इसमें faces-config.xml
:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
(उपरोक्त सभी मैं वसंत के संबंध में जानता हूं - मैं वसंत नहीं करता - अन्य संभावित वसंत संबंधित कारणों के साथ संपादित / टिप्पणी करने के लिए स्वतंत्र महसूस करता हूं; उदाहरण के लिए कुछ XML कॉन्फ़िगरेशन से संबंधित परेशानी)
मामले में यह एक है पुनरावर्तक घटक जो अपने के माध्यम से (नेस्ट) सेम प्रबंधित कर रहा है var
विशेषता (जैसे <h:dataTable var="item">
, <ui:repeat var="item">
,<p:tabView var="item">
, आदि) और आप वास्तव में मिला एक "लक्ष्य नहीं पहुंचा जा सकता, पहचानकर्ता 'आइटम' अशक्त का संकल्प", तो आप निम्न में से सुनिश्चित करने की आवश्यकता :
#{item}
में संदर्भित नहीं है binding
किसी भी बच्चे घटक के attribtue। यह गलत है क्योंकि binding
विशेषता व्यू बिल्ड टाइम के दौरान चलती है, व्यू रेंडर समय के दौरान नहीं। इसके अलावा, घटक के पेड़ में शारीरिक रूप से केवल एक घटक होता है जिसे बस हर पुनरावृत्ति दौर के दौरान पुन: उपयोग किया जाता है। दूसरे शब्दों में, आपको वास्तव में binding="#{bean.component}"
इसके बजाय का उपयोग करना चाहिए binding="#{item.component}"
। लेकिन बेहतर यह है कि आप इस तरह से हल करने के लिए सोची गई समस्या के लिए कंपोनेंट बीनिंग से पूरी तरह से छुटकारा पाएं और जांच करें / उचित दृष्टिकोण पूछें। यह भी देखें कि JSF में 'बाइंडिंग' विशेषता कैसे काम करती है? इसका उपयोग कब और कैसे किया जाना चाहिए?
1b। (डिफ़ॉल्ट) प्रबंधित बीन नाम क्या है?
दूसरा चरण पंजीकृत प्रबंधित बीन नाम की जाँच करना होगा। जेएसएफ और स्प्रिंग उपयोग कन्वेंशन जावाबीन्स विनिर्देशन के अनुरूप हैं जबकि सीडीआई में सीडीआई इम्प्लांट / संस्करण के आधार पर अपवाद हैं।
FooBean
नीचे की तरह एक बैकिंग बीन क्लास,
@Named
public class FooBean {}
सभी बीन प्रबंधन ढांचे में #{fooBean}
JavaBeans विनिर्देश के अनुसार एक डिफ़ॉल्ट प्रबंधित बीन नाम होगा ।
FOOBean
नीचे की तरह एक बैकिंग बीन क्लास,
@Named
public class FOOBean {}
जिसका अयोग्य क्लासनाम जेएसएफ में कम से कम दो राजधानियों के साथ शुरू होता है और स्प्रिंग में एक अयोग्य श्रेणी के नाम का डिफ़ॉल्ट प्रबंधित बीन नाम होता है #{FOOBean}
, जो जावाबीन्स की विशिष्टता के अनुरूप होता है। CDI में, यह जून 2015 से पहले जारी किए गए वेल्ड संस्करणों में भी है, लेकिन जून 2015 के बाद जारी किए गए वेल्ड संस्करणों में नहीं (2.2.14 / 2.3.0.B1 / 3.0.0.A9) और OpenWebBeans में निरीक्षण के कारण सीडीआई कल्पना । उन वेल्ड संस्करणों में और सभी OWB संस्करणों में यह केवल पहले अक्षर के साथ है #{fOOBean}
।
यदि आपने स्पष्ट रूप से foo
नीचे की तरह एक प्रबंधित बीन नाम निर्दिष्ट किया है ,
@Named("foo")
public class FooBean {}
या समतुल्य रूप से @ManagedBean(name="foo")
या @Component("foo")
, तो यह केवल द्वारा उपलब्ध हो जाएगा #{foo}
इस प्रकार और नहीं द्वारा #{fooBean}
।
1c। बैकिंग बीन क्लास कहाँ है?
तीसरा कदम दोहरीकरण होगा यदि बैकिंग बीन क्लास निर्मित और तैनात WAR फ़ाइल में सही स्थान पर है। सुनिश्चित करें कि आपने प्रोजेक्ट पूरी तरह से पूरी तरह से स्वच्छ, पुनर्निर्माण, पुनर्विकास और पुनः आरंभ किया है और यदि आप वास्तव में कोड लिखने में व्यस्त थे और अधीर रूप से ब्राउज़र में F5 दबा रहे थे। यदि अभी भी व्यर्थ है, तो बिल्ड सिस्टम को एक WAR फ़ाइल का उत्पादन करने दें, जिसे आप तब निकालें और एक ज़िप टूल के साथ निरीक्षण करें। .class
बैकिंग बीन क्लास की संकलित फ़ाइल को इसके पैकेज संरचना में रहना चाहिए /WEB-INF/classes
। या, जब इसे JAR मॉड्यूल के हिस्से के रूप में पैक किया जाता है, तो संकलित .class
फ़ाइल वाले JAR में निवास करना चाहिए /WEB-INF/lib
और इस तरह EAR के /lib
या कहीं और नहीं।
यदि आप ग्रहण का उपयोग कर रहे हैं, तो सुनिश्चित करें कि बैकिंग बीन क्लास में है src
और इस प्रकार नहीं WebContent
, और सुनिश्चित करें कि प्रोजेक्ट> बिल्ड ऑटोमैटिकली सक्षम है। आप Maven उपयोग कर रहे हैं, कि समर्थन सेम कक्षा में है यह सुनिश्चित कर लें src/main/java
और इस तरह नहीं में src/main/resources
या src/main/webapp
।
यदि आप EJB + WAR (s) के साथ एक EAR के भाग के रूप में वेब एप्लिकेशन को पैकेजिंग कर रहे हैं, तो आपको यह सुनिश्चित करने की आवश्यकता है कि बैकिंग बीन क्लासेस WAR मॉड्यूल में हैं और इस प्रकार EAR मॉड्यूल या EJB मॉड्यूल में नहीं हैं। बिजनेस टियर (EJB) किसी भी वेब टियर (WAR) से संबंधित कलाकृतियों से मुक्त होना चाहिए, ताकि बिजनेस टियर कई अलग-अलग वेब टियर्स (JSF, JAX-RS, JSP / सर्वलेट, आदि) में पुन: प्रयोज्य हो।
2. लक्ष्यरहित, 'इकाई' निरर्थक है
यह उस नेस्टेड प्रॉपर्टी entity
को उबाल देता है जैसा कि #{bean.entity.property}
लौटाया गया था null
। यह आमतौर पर केवल तभी सामने आता है जब JSF को नीचे की तरह इनपुट घटक के माध्यम से मान सेट करना property
होता है, जबकि #{bean.entity}
वास्तव में वापस आ जाता है null
।
<h:inputText value="#{bean.entity.property}" />
आपको यह सुनिश्चित करने की आवश्यकता है कि आपने मॉडल इकाई को पहले से तैयार कर लिया है @PostConstruct
, या <f:viewAction>
विधि में, या शायद एक add()
एक्शन विधि के मामले में आप CRUD सूचियों और / या एक ही दृश्य पर संवाद के साथ काम कर रहे हैं।
@Named
@ViewScoped
public class Bean {
private Entity entity; // +getter (setter is not necessary).
@Inject
private EntityService entityService;
@PostConstruct
public void init() {
// In case you're updating an existing entity.
entity = entityService.getById(entityId);
// Or in case you want to create a new entity.
entity = new Entity();
}
// ...
}
के महत्व के रूप में @PostConstruct
; यदि आप एक सेम प्रबंधन ढांचे का उपयोग कर रहे हैं जो सीडीआई जैसे प्रॉक्सी का उपयोग करता है , तो एक नियमित निर्माणकर्ता में ऐसा करना विफल होगा । हमेशा @PostConstruct
प्रबंधित बीन @PreDestroy
इंस्टॉलेशन पर हुक करने के लिए उपयोग करें (और प्रबंधित बीन इंस्टेंस विनाश पर हुक करने के लिए उपयोग करें)। इसके अतिरिक्त, एक कंस्ट्रक्टर में आपके पास अभी तक किसी भी इंजेक्ट की गई निर्भरता तक पहुंच नहीं होगी, यह भी देखें कि NullPointerException कंस्ट्रक्टर में @ इंजेक्ट बीन को एक्सेस करने की कोशिश कर रहा है ।
यदि इसके entityId
माध्यम से आपूर्ति की जाती है <f:viewParam>
, तो आपको <f:viewAction>
इसके बजाय उपयोग करने की आवश्यकता होगी @PostConstruct
। यह भी देखें कि कब उपयोग करें f: viewAction / preRenderView बनाम PostConstruct?
आपको यह सुनिश्चित करने की भी ज़रूरत है कि null
यदि आप इसे केवल एक add()
एक्शन विधि में बना रहे हैं, तो पोस्टबैक के दौरान आप गैर- मॉडल को संरक्षित करते हैं । सबसे आसान होगा सेम को व्यू स्कोप में रखना। यह भी देखें कि सही बीन गुंजाइश कैसे चुनें?
3. लक्ष्यहीन, 'अशक्त' अशक्त लौट आया
यह वास्तव में # 2 के रूप में एक ही कारण है, केवल (पुराने) ईएल कार्यान्वयन का उपयोग किया जा रहा है कुछ अपवाद संदेश में प्रदर्शित करने के लिए संपत्ति के नाम को संरक्षित करने में छोटी गाड़ी है, जिसे अंततः 'अशक्त' के रूप में गलत तरीके से उजागर किया गया है। यह केवल डिबगिंग बनाता है और थोड़ा मुश्किल को ठीक करता है जब आप कुछ नेस्टेड गुणों को पसंद करते हैं #{bean.entity.subentity.subsubentity.property}
।
समाधान अभी भी समान है: सुनिश्चित करें कि प्रश्न में नेस्टेड इकाई null
सभी स्तरों में नहीं है।
4. लक्ष्यहीन, '' 0 '' शून्य हो गया
यह भी # 2 के समान कारण है, केवल (पुराने) ईएल कार्यान्वयन का उपयोग अपवाद संदेश तैयार करने में छोटी गाड़ी है। यह केवल तभी प्रकट होता है जब आप []
EL में ब्रेस नोटेशन का उपयोग करते हैं , #{bean.collection[index]}
जहां #{bean.collection}
स्वयं नॉन-नल है, लेकिन निर्दिष्ट इंडेक्स में आइटम मौजूद नहीं है। इस तरह के संदेश की तब व्याख्या की जानी चाहिए:
लक्ष्यहीन, 'संग्रह [0]' शून्य हो गया
समाधान भी # 2 के समान है: सुनिश्चित करें कि संग्रह आइटम उपलब्ध है।
5. लक्ष्यहीन, 'ब्रैकेटसफिक्स' शून्य हो गया
यह वास्तव में # 4 के रूप में एक ही कारण है, केवल (पुराने) ईएल कार्यान्वयन का उपयोग अपवाद संदेश में प्रदर्शित करने के लिए पुनरावृत्ति सूचकांक को संरक्षित करने में कुछ छोटी है, जो अंततः 'ब्रैकेटसफिक्स' के रूप में गलत तरीके से उजागर हुआ है जो वास्तव में चरित्र है ]
। यह केवल डिबगिंग बनाता है और संग्रह में एक से अधिक आइटम होने पर थोड़ा कठिन होता है।
अन्य संभावित कारण javax.el.PropertyNotFoundException
: