स्टैक ट्रेस क्या है, और मैं इसका उपयोग अपनी एप्लिकेशन त्रुटियों को डीबग करने के लिए कैसे कर सकता हूं?


644

कभी-कभी जब मैं अपना एप्लिकेशन चलाता हूं तो यह मुझे एक त्रुटि देता है जो दिखता है:

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

लोगों ने इसे "स्टैक ट्रेस" के रूप में संदर्भित किया है। स्टैक ट्रेस क्या है? यह मेरे कार्यक्रम में हुई त्रुटि के बारे में मुझे क्या बता सकता है?


इस सवाल के बारे में - काफी बार मैं एक सवाल देखता हूं कि एक नौसिखिया प्रोग्रामर "त्रुटि प्राप्त कर रहा है", और वे बस अपने स्टैक ट्रेस और कोड के कुछ यादृच्छिक ब्लॉक को यह समझने के बिना पेस्ट करते हैं कि स्टैक ट्रेस क्या है या वे इसका उपयोग कैसे कर सकते हैं। यह सवाल नौसिखिए प्रोग्रामर के लिए एक संदर्भ के रूप में है, जिन्हें स्टैक ट्रेस के मूल्य को समझने में मदद की आवश्यकता हो सकती है।


25
इसके अलावा, यदि स्टैकट्रेस लाइन में फ़ाइल नाम और एक पंक्ति संख्या शामिल नहीं है, तो उस पंक्ति के लिए वर्ग को जटिल जानकारी के साथ संकलित नहीं किया गया था।
थोरबजोरन रावन एंडरसन

जवाबों:


589

सरल शब्दों में, स्टैक ट्रेस उस विधि कॉल की एक सूची है जो अनुप्रयोग के बीच में थी जब एक अपवाद फेंका गया था।

सरल उदाहरण

प्रश्न में दिए गए उदाहरण के साथ, हम यह निर्धारित कर सकते हैं कि आवेदन में अपवाद कहां फेंका गया था। आइए नज़र डालते हैं स्टैक ट्रेस पर:

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

यह एक बहुत ही सरल स्टैक ट्रेस है। यदि हम "at ..." की सूची की शुरुआत में कहते हैं, तो हम बता सकते हैं कि हमारी गलती कहां हुई। हम जिस चीज की तलाश कर रहे हैं वह सबसे ऊपरी विधि कॉल है जो हमारे एप्लिकेशन का हिस्सा है। इस मामले में, यह है:

at com.example.myproject.Book.getTitle(Book.java:16)

इसे डीबग करने के लिए, हम खोल सकते हैं Book.javaऔर लाइन को देख सकते हैं 16, जो है:

15   public String getTitle() {
16      System.out.println(title.toString());
17      return title;
18   }

यह इंगित करता है कि उपरोक्त कोड में कुछ (संभवतः title) है null

अपवादों की श्रृंखला के साथ उदाहरण

कभी-कभी एप्लिकेशन एक अपवाद को पकड़ लेंगे और इसे दूसरे अपवाद के कारण के रूप में फिर से फेंक देंगे। यह आमतौर पर ऐसा दिखता है:

34   public void getBookIds(int id) {
35      try {
36         book.getId(id);    // this method it throws a NullPointerException on line 22
37      } catch (NullPointerException e) {
38         throw new IllegalStateException("A book has a null property", e)
39      }
40   }

यह आपको एक स्टैक ट्रेस दे सकता है जो दिखता है:

Exception in thread "main" java.lang.IllegalStateException: A book has a null property
        at com.example.myproject.Author.getBookIds(Author.java:38)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
Caused by: java.lang.NullPointerException
        at com.example.myproject.Book.getId(Book.java:22)
        at com.example.myproject.Author.getBookIds(Author.java:36)
        ... 1 more

इस बारे में जो अलग है वह है "इसके कारण"। कभी-कभी अपवादों में कई "कारण" खंड होंगे। इन के लिए, आप आम तौर पर "मूल कारण" को ढूंढना चाहते हैं, जो स्टैक ट्रेस में "वर्गों द्वारा सबसे कम" कारणों में से एक होगा। हमारे मामले में, यह है:

Caused by: java.lang.NullPointerException <-- root cause
        at com.example.myproject.Book.getId(Book.java:22) <-- important line

फिर, यह अपवाद के साथ हम लाइन को देखने के लिए चाहते हैं 22की Book.javaक्या कारण हो सकता है देखने के लिए NullPointerExceptionयहाँ।

लाइब्रेरी कोड के साथ अधिक चुनौतीपूर्ण उदाहरण

आमतौर पर स्टैक के निशान ऊपर के दो उदाहरणों की तुलना में बहुत अधिक जटिल होते हैं। यहाँ एक उदाहरण है (यह एक लंबा है, लेकिन जंजीर अपवादों के कई स्तरों को प्रदर्शित करता है):

javax.servlet.ServletException: Something bad happened
    at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:60)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.example.myproject.ExceptionHandlerFilter.doFilter(ExceptionHandlerFilter.java:28)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.example.myproject.OutputBufferFilter.doFilter(OutputBufferFilter.java:33)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: com.example.myproject.MyProjectServletException
    at com.example.myproject.MyServlet.doPost(MyServlet.java:169)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:30)
    ... 27 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [com.example.myproject.MyEntity]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:64)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2329)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2822)
    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:705)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:693)
    at org.hibernate.impl.SessionImpl.save(SessionImpl.java:689)
    at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:344)
    at $Proxy19.save(Unknown Source)
    at com.example.myproject.MyEntityService.save(MyEntityService.java:59) <-- relevant call (see notes below)
    at com.example.myproject.MyServlet.doPost(MyServlet.java:164)
    ... 32 more
Caused by: java.sql.SQLException: Violation of unique constraint MY_ENTITY_UK_1: duplicate value(s) for column(s) MY_COLUMN in statement [...]
    at org.hsqldb.jdbc.Util.throwError(Unknown Source)
    at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
    at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:57)
    ... 54 more

इस उदाहरण में, बहुत अधिक है। हम जिस चीज के बारे में अधिक चिंतित हैं, वह हमारे कोड के तरीकों की तलाश में है , जो com.example.myprojectपैकेज में कुछ भी होगा । दूसरे उदाहरण (ऊपर) से, हम पहले मूल कारण के लिए नीचे देखना चाहते हैं, जो है:

Caused by: java.sql.SQLException

हालाँकि, इसके तहत सभी विधि कॉल लाइब्रेरी कोड हैं। तो हम इसे ऊपर "कारण" तक ले जाएंगे, और हमारे कोड से उत्पन्न होने वाली पहली विधि कॉल की तलाश करेंगे, जो है:

at com.example.myproject.MyEntityService.save(MyEntityService.java:59)

पिछले उदाहरणों की तरह, हमें MyEntityService.javaलाइन पर देखना चाहिए 59, क्योंकि यही त्रुटि उत्पन्न हुई (यह थोड़ा स्पष्ट है कि गलत क्या हुआ, क्योंकि SQLException त्रुटि बताती है, लेकिन डिबगिंग प्रक्रिया वह है जो हम बाद में करते हैं)।


3
@RobHruska - बहुत अच्छी तरह से समझाया। +1। क्या आप किसी ऐसे पार्सर के बारे में जानते हैं जो स्ट्रेचर का विश्लेषण करने के लिए एक स्ट्रिंग के रूप में अपवाद ट्रेस लेता है और उपयोगी तरीके प्रदान करता है। - जैसे getLastCausedBy () या getCausedByForMyAppCode ("com.example.myproject")
एंडी

1
@AndyDufresne - मैं किसी भी तरह से नहीं आया हूं, लेकिन फिर मैंने वास्तव में या तो नहीं देखा है।
रॉब ह्रस्का 12

1
सुझाया गया सुधार: स्टैक ट्रेस की पहली पंक्ति की व्याख्या करें जो Exception in thread "main"आपके पहले उदाहरण में शुरू होती है । मुझे लगता है कि यह व्याख्या करना विशेष रूप से उपयोगी होगा कि यह रेखा अक्सर एक संदेश के साथ होती है, जैसे कि एक चर का मूल्य, जो समस्या का निदान करने में मदद कर सकता है। मैंने खुद को संपादित करने का प्रयास किया, लेकिन मैं इन विचारों को आपके उत्तर की मौजूदा संरचना में फिट करने के लिए संघर्ष कर रहा हूं।
कोड-अपरेंटिस

5
इसके अलावा जावा 1.7 ने "सप्रेस्ड:" कहा - इस अपवाद को प्रदर्शित करने से पहले "स्टॉक्स ट्रैस" को दबाने से पहले कौन सी सूचियों को दबाया गया था। यह स्वचालित रूप से कोशिश-के-संसाधन निर्माण द्वारा उपयोग किया जाता है: docs.oracle.com/javase/specs/jls/se8/html/… और इसमें कुछ अपवाद हैं यदि संसाधन (एस) बंद होने के दौरान फेंक दिया गया था।
ढाबा

एक JEP Openjdk.java.net/jeps/8220715 है जिसका उद्देश्य "NullInstanceField 'को नहीं लिखा जा सकता क्योंकि" nnullInstanceField' शून्य जैसा विवरण प्रदान करके विशेष रूप से NPEs की समझ को और बेहतर बनाने का लक्ष्य है। "
महात्मा_पत्नी_परिवार

80

मैं इस उत्तर को पोस्ट कर रहा हूं इसलिए सबसे ऊपरी उत्तर (जब गतिविधि द्वारा क्रमबद्ध किया गया) एक ऐसा नहीं है जो सिर्फ सादा गलत है।

स्टैकट्रेस क्या है?

स्टैकट्रेस एक बहुत ही उपयोगी डिबगिंग टूल है। यह कॉल स्टैक दिखाता है (मतलब, उस समय तक किए गए फ़ंक्शन के स्टैक) को एक अनकहा अपवाद के रूप में फेंक दिया गया था (या समय स्टैकट्रेस मैन्युअल रूप से उत्पन्न हुआ था)। यह बहुत उपयोगी है क्योंकि यह न केवल आपको दिखाता है कि त्रुटि कहां हुई, बल्कि यह भी कि कोड के उस स्थान पर प्रोग्राम कैसे समाप्त हुआ। यह अगले प्रश्न की ओर जाता है:

एक अपवाद क्या है?

एक अपवाद वह है जो रनटाइम वातावरण आपको यह बताने के लिए उपयोग करता है कि एक त्रुटि हुई। लोकप्रिय उदाहरण NullPointerException, IndexOutOfBoundsException या ArithmeticException हैं। इनमें से प्रत्येक तब होता है जब आप कुछ ऐसा करने की कोशिश करते हैं जो संभव नहीं है। उदाहरण के लिए, NullPointerException को तब फेंका जाएगा जब आप किसी नल-ऑब्जेक्ट को डीरेल करने की कोशिश करेंगे:

Object a = null;
a.toString();                 //this line throws a NullPointerException

Object[] b = new Object[5];
System.out.println(b[10]);    //this line throws an IndexOutOfBoundsException,
                              //because b is only 5 elements long
int ia = 5;
int ib = 0;
ia = ia/ib;                   //this line throws an  ArithmeticException with the 
                              //message "/ by 0", because you are trying to
                              //divide by 0, which is not possible.

स्टैकट्रैक्स / अपवाद के साथ मुझे कैसे व्यवहार करना चाहिए?

सबसे पहले, पता करें कि अपवाद क्या है। अपवाद का नाम जानने के लिए Google का प्रयास करें, उस अपवाद का कारण क्या है। अधिकांश समय यह गलत कोड के कारण होगा। ऊपर दिए गए उदाहरणों में, सभी अपवाद गलत कोड के कारण हैं। तो NullPointerException उदाहरण के लिए आप यह सुनिश्चित कर सकते हैं कि aउस समय कभी भी अशक्त न हो। उदाहरण के लिए, आप aइस तरह एक चेक को इनिशियलाइज़ या शामिल कर सकते हैं:

if (a!=null) {
    a.toString();
}

इस तरह, यदि आपत्तिजनक लाइन निष्पादित नहीं की गई है a==null। वही अन्य उदाहरणों के लिए जाता है।

कभी-कभी आप यह सुनिश्चित नहीं कर सकते हैं कि आपको अपवाद नहीं मिलता है। उदाहरण के लिए, यदि आप अपने प्रोग्राम में नेटवर्क कनेक्शन का उपयोग कर रहे हैं, तो आप कंप्यूटर को इंटरनेट कनेक्शन खोने से रोक नहीं सकते हैं (जैसे कि आप उपयोगकर्ता को कंप्यूटर के नेटवर्क कनेक्शन को डिस्कनेक्ट करने से नहीं रोक सकते)। इस मामले में नेटवर्क लाइब्रेरी शायद एक अपवाद फेंक देगी। अब आपको अपवाद को पकड़ना चाहिए और इसे संभालना चाहिए। इसका अर्थ है, नेटवर्क कनेक्शन के साथ उदाहरण में, आपको कनेक्शन को फिर से खोलने या उपयोगकर्ता या उस जैसे कुछ को सूचित करने का प्रयास करना चाहिए। इसके अलावा, जब भी आप कैच का उपयोग करते हैं, तो हमेशा केवल उस अपवाद को पकड़ें जिसे आप पकड़ना चाहते हैं, जैसे व्यापक कैच स्टेटमेंट का उपयोग न करेंcatch (Exception e)वह सभी अपवादों को पकड़ लेगा। यह बहुत महत्वपूर्ण है, क्योंकि अन्यथा आप गलती से गलत अपवाद को पकड़ सकते हैं और गलत तरीके से प्रतिक्रिया कर सकते हैं।

try {
    Socket x = new Socket("1.1.1.1", 6789);
    x.getInputStream().read()
} catch (IOException e) {
    System.err.println("Connection could not be established, please try again later!")
}

मुझे क्यों नहीं उपयोग करना चाहिए catch (Exception e)?

आइए यह दिखाने के लिए एक छोटे से उदाहरण का उपयोग करें कि आपको सभी अपवादों को क्यों नहीं पकड़ना चाहिए:

int mult(Integer a,Integer b) {
    try {
        int result = a/b
        return result;
    } catch (Exception e) {
        System.err.println("Error: Division by zero!");
        return 0;
    }
}

यह कोड जो करने की कोशिश कर रहा है, वह ArithmeticExceptionसंभावित विभाजन के कारण 0. को पकड़ने के लिए है। लेकिन यह भी संभव है NullPointerExceptionकि अगर aया bहो तो फेंक दिया जाता है null। इसका मतलब है, आपको मिल सकता है NullPointerExceptionलेकिन आप इसे एक अंकगणित के रूप में मानेंगे और शायद गलत काम करेंगे। सबसे अच्छे मामले में आप अभी भी याद करते हैं कि एक NullPointerException थी। सामान की तरह यह बहुत कठिन डिबगिंग बनाता है, तो ऐसा मत करो।

TLDR

  1. यह पता लगाएं कि अपवाद का कारण क्या है और इसे ठीक करें, ताकि यह अपवाद बिल्कुल न फेंके।
  2. यदि 1. संभव नहीं है, तो विशिष्ट अपवाद को पकड़ें और इसे संभाल लें।

    • कभी भी केवल एक कोशिश / कैच न जोड़ें और फिर अपवाद को अनदेखा करें! ऐसा मत करो!
    • कभी उपयोग न करें catch (Exception e), हमेशा विशिष्ट अपवादों को पकड़ें। जो आपको बहुत सारे सिरदर्द से बचाएगा।

1
क्यों हम बग मास्क लगाने से बचना चाहिए
सुदीप भंडारी

2
मैं इस उत्तर को पोस्ट कर रहा हूं इसलिए सबसे ऊपरी उत्तर (जब गतिविधि द्वारा क्रमबद्ध किया गया) एक नहीं है, जो कि सीधे सादे गलत है, मुझे पता नहीं है कि आप किस बारे में बात कर रहे हैं क्योंकि यह संभवतः अब तक बदल गया है। लेकिन स्वीकृत उत्तर निश्चित रूप से अधिक
अंतर्विरोधी है

1
मेरा मतलब है कि अब तक हटा दिया गया है, जहाँ तक मुझे पता है। यह मूल रूप से कहा गया है "बस एक कोशिश {} पकड़ (अपवाद ई) {} और सभी त्रुटियों को अनदेखा करें"। स्वीकृत उत्तर मेरे उत्तर की तुलना में बहुत पुराना है इसलिए मैं इस मामले पर थोड़ा अलग दृष्टिकोण देने का लक्ष्य बना रहा था। मुझे नहीं लगता कि इससे किसी को सिर्फ किसी और के जवाब को कॉपी करने या दूसरे लोगों को पहले से ही अच्छी तरह से कवर करने में मदद मिलती है।
दक्खन

यह कहना भ्रामक है "अपवाद न पकड़ें", यह केवल एक उपयोग का मामला है। आपका उदाहरण बहुत अच्छा है, लेकिन कैसे आप अपने थ्रेड लूप (रन के अंदर) के शीर्ष पर हैं? आपको हमेशा अपवाद (या शायद फेंकने योग्य) को वहां पकड़ना चाहिए और इसे लॉग इन करना चाहिए ताकि यह अदृश्य रूप से गायब न हो (जब तक कि आप ऐसा करने के लिए अपना धागा / लकड़हारा सेट नहीं करते हैं, तब तक रन से फेंके गए अपवाद आमतौर पर सही तरीके से लॉग नहीं होते हैं)।
बिल के

1
मैंने इस विशेष मामले को शामिल नहीं किया क्योंकि यह केवल मल्टीथ्रेडिंग के साथ मायने रखता है। एकल थ्रेडिंग में एक लीक अपवाद प्रोग्राम को मारता है और नेत्रहीन लॉग होता है। यदि कोई व्यक्ति अपवादों को ठीक से नहीं जानता है, तो वे आमतौर पर मल्टीथ्रेडिंग का उपयोग करना नहीं जानते हैं।
डकारन

21

रोब का उल्लेख किया है पर जोड़ने के लिए। आपके एप्लिकेशन में ब्रेक पॉइंट सेट करना स्टैक के चरण-दर-चरण प्रसंस्करण के लिए अनुमति देता है। यह डेवलपर को डिबगर का उपयोग करने के लिए सक्षम करता है यह देखने के लिए कि विधि सटीक रूप से कुछ ऐसा कर रही है जो अप्रत्याशित था।

चूँकि रोब ने NullPointerExceptionNPE (NPE) का उपयोग कुछ सामान्य रूप से करने के लिए किया है, हम इस समस्या को निम्नलिखित तरीके से दूर करने में मदद कर सकते हैं:

अगर हमारे पास एक तरीका है जो पैरामीटर लेता है जैसे: void (String firstName)

हमारे कोड में हम उसका मूल्यांकन करना चाहेंगे firstName जिसमें एक मूल्य शामिल है, हम ऐसा करेंगे:if(firstName == null || firstName.equals("")) return;

उपरोक्त हमें firstNameअसुरक्षित पैरामीटर के रूप में उपयोग करने से रोकता है । इसलिए प्रसंस्करण से पहले अशक्त जांच करके हम यह सुनिश्चित करने में मदद कर सकते हैं कि हमारा कोड ठीक से चलेगा। एक उदाहरण पर विस्तार करने के लिए जो किसी ऐसी विधि का उपयोग करता है जिसमें हम यहां देख सकते हैं:

if(dog == null || dog.firstName == null) return;

उपर्युक्त नलियों की जांच करने का उचित आदेश है, हम इस मामले में आधार वस्तु, कुत्ते से शुरू करते हैं, और फिर प्रसंस्करण से पहले सब कुछ मान्य है यह सुनिश्चित करने के लिए संभावनाओं के पेड़ के नीचे चलना शुरू करते हैं। यदि आदेश उलटा होता तो एक एनपीई संभावित रूप से फेंका जा सकता था और हमारा कार्यक्रम दुर्घटनाग्रस्त हो जाता।


माना। इस दृष्टिकोण का उपयोग यह पता लगाने के लिए किया जा सकता है कि एक बयान में कौन सा संदर्भ है, nullजब NullPointerExceptionउदाहरण के लिए जांच की जा रही है।
रॉब ह्रस्का

16
स्ट्रिंग के साथ काम करते समय, यदि आप बराबरी पद्धति का उपयोग करना चाहते हैं, तो मुझे लगता है कि तुलना के बाईं ओर स्थिर का उपयोग करना बेहतर है, इस तरह से: इसके बजाय: अगर (firstName == null) firstName.equals ("") )) वापसी; मैं हमेशा उपयोग करता हूं: अगर (("")। बराबर (पहला नाम)) यह नलपॉइंट अपवाद को रोकता है
टोरेस

15

थ्रेडेबल परिवार द्वारा प्रस्तुत एक और स्टैकट्रेस सुविधा है - हेरफेर करने की संभावना स्टैक ट्रेस जानकारी में ।

मानक व्यवहार:

package test.stack.trace;

public class SomeClass {

    public void methodA() {
        methodB();
    }

    public void methodB() {
        methodC();
    }

    public void methodC() {
        throw new RuntimeException();
    }

    public static void main(String[] args) {
        new SomeClass().methodA();
    }
}

स्टैक ट्रेस:

Exception in thread "main" java.lang.RuntimeException
    at test.stack.trace.SomeClass.methodC(SomeClass.java:18)
    at test.stack.trace.SomeClass.methodB(SomeClass.java:13)
    at test.stack.trace.SomeClass.methodA(SomeClass.java:9)
    at test.stack.trace.SomeClass.main(SomeClass.java:27)

मैनिप्युलेटेड स्टैक ट्रेस:

package test.stack.trace;

public class SomeClass {

    ...

    public void methodC() {
        RuntimeException e = new RuntimeException();
        e.setStackTrace(new StackTraceElement[]{
                new StackTraceElement("OtherClass", "methodX", "String.java", 99),
                new StackTraceElement("OtherClass", "methodY", "String.java", 55)
        });
        throw e;
    }

    public static void main(String[] args) {
        new SomeClass().methodA();
    }
}

स्टैक ट्रेस:

Exception in thread "main" java.lang.RuntimeException
    at OtherClass.methodX(String.java:99)
    at OtherClass.methodY(String.java:55)

2
मुझे नहीं पता कि मैं इस बारे में कैसा महसूस करता हूं ... धागे की प्रकृति के साथ, मैं नए देवों को सलाह दूंगा कि वे अपने स्वयं के स्टैक ट्रेस को परिभाषित न करें।
PeonProgrammer

15

नाम को समझने के लिए : एक स्टैक ट्रेस अपवाद की एक सूची है (या आप "कारण से" की एक सूची कह सकते हैं), सबसे सतह अपवाद (जैसे सेवा परत अपवाद) से सबसे गहरी एक (उदाहरण के लिए डेटाबेस अपवाद)। जिस तरह से हम इसे 'स्टैक' कहते हैं, क्योंकि स्टैक फर्स्ट इन लास्ट आउट (FILO) है, सबसे गहरा अपवाद बहुत शुरुआत में हुआ था, तब अपवाद की एक श्रृंखला कई परिणाम उत्पन्न करती थी, सतह अपवाद अंतिम था एक समय में हुआ था, लेकिन हम इसे पहली जगह में देखते हैं।

कुंजी 1 : एक मुश्किल और महत्वपूर्ण बात यहाँ समझने की आवश्यकता है: सबसे गहरा कारण "मूल कारण" नहीं हो सकता है, क्योंकि यदि आप कुछ "बुरा कोड" लिखते हैं, तो यह कुछ अपवाद का कारण हो सकता है जो इसकी परत से गहरा है। उदाहरण के लिए, एक खराब एसक्यूएल क्वेरी सिंडीक्स त्रुटि के बजाय बोटेम में SQLServerException कनेक्शन रीसेट का कारण हो सकती है, जो कि स्टैक के बीच में हो सकती है।

-> बीच में मूल कारण का पता लगाना आपका काम है। यहाँ छवि विवरण दर्ज करें

कुंजी 2 : एक और मुश्किल लेकिन महत्वपूर्ण बात प्रत्येक "कॉज बाय" ब्लॉक के अंदर है, पहली पंक्ति सबसे गहरी परत थी और इस ब्लॉक में पहले स्थान पर थी। उदाहरण के लिए,

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
           at com.example.myproject.Author.getBookTitles(Author.java:25)
               at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

Book.java:16 को Auther.java:25 द्वारा कॉल किया गया था जिसे Bootstrap.java:14 द्वारा पुकारा गया था, Book.java:16 मूल कारण था। यहाँ कालानुक्रम क्रम में ट्रेस स्टैक की तरह एक आरेख संलग्न करें। यहाँ छवि विवरण दर्ज करें


8

बस अन्य उदाहरणों में जोड़ने के लिए, आंतरिक (नेस्टेड) ​​वर्ग हैं जो $संकेत के साथ दिखाई देते हैं । उदाहरण के लिए:

public class Test {

    private static void privateMethod() {
        throw new RuntimeException();
    }

    public static void main(String[] args) throws Exception {
        Runnable runnable = new Runnable() {
            @Override public void run() {
                privateMethod();
            }
        };
        runnable.run();
    }
}

इस स्टैक ट्रेस में परिणाम होगा:

Exception in thread "main" java.lang.RuntimeException
        at Test.privateMethod(Test.java:4)
        at Test.access$000(Test.java:1)
        at Test$1.run(Test.java:10)
        at Test.main(Test.java:13)

5

अन्य पोस्ट बताते हैं कि स्टैक ट्रेस क्या है, लेकिन इसके साथ काम करना मुश्किल हो सकता है।

यदि आप एक स्टैक ट्रेस प्राप्त करते हैं और अपवाद के कारण का पता लगाना चाहते हैं, तो यह समझने में एक अच्छी शुरुआत बिंदु ग्रहण में जावा स्टैक ट्रेस कंसोल का उपयोग करना है। । यदि आप किसी अन्य आईडीई का उपयोग करते हैं तो एक समान सुविधा हो सकती है, लेकिन यह उत्तर ग्रहण के बारे में है।

सबसे पहले, सुनिश्चित करें कि आपके पास अपने सभी जावा स्रोत एक ग्रहण परियोजना में उपलब्ध हैं।

फिर जावा परिप्रेक्ष्य में, कंसोल टैब (आमतौर पर तल पर) पर क्लिक करें । यदि कंसोल दृश्य दिखाई नहीं देता है, तो मेनू विकल्प विंडो पर जाएं -> दृश्य दिखाएं और कंसोल का चयन करें

फिर कंसोल विंडो में, निम्न बटन पर क्लिक करें (दाईं ओर)

शान्ति बटन

और फिर जावा स्टैक ट्रेस कंसोल का चयन करें ड्रॉप-डाउन सूची से ।

कंसोल में अपने स्टैक ट्रेस चिपकाएँ। यह तब आपके स्रोत कोड और किसी भी अन्य स्रोत कोड में लिंक की एक सूची प्रदान करेगा।

यह वही है जो आप देख सकते हैं (ग्रहण दस्तावेज़ से चित्र):

ग्रहण प्रलेखन से आरेख

सबसे हालिया मेथड कॉल कॉल स्टैक के शीर्ष पर होगी , जो शीर्ष पंक्ति (संदेश पाठ को छोड़कर) है। स्टैक नीचे जाने से समय में वापस चला जाता है। दूसरी पंक्ति वह विधि है जो पहली पंक्ति को कॉल करती है, आदि।

यदि आप ओपन-सोर्स सॉफ़्टवेयर का उपयोग कर रहे हैं, तो आपको अपनी परियोजना के स्रोतों को डाउनलोड और संलग्न करना पड़ सकता है यदि आप जांच करना चाहते हैं। स्रोत जार डाउनलोड करें, अपनी परियोजना में, अपने ओपन-सोर्स मॉड्यूल (वर्ग फ़ाइलों के साथ एक) के लिए अपना जार खोजने के लिए संदर्भित लाइब्रेरी फ़ोल्डर खोलें, फिर राइट क्लिक करें, गुण चुनें और स्रोत जार संलग्न करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.