স্ট্যাক ট্রেস কী এবং আমি কীভাবে এটি আমার অ্যাপ্লিকেশন ত্রুটিগুলি ডিবাগ করতে ব্যবহার করতে পারি?


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 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, কারণ এই ত্রুটিটি এখানেই উদ্ভূত হয়েছিল (এটি কী ভুল হয়েছে তা কিছুটা স্পষ্ট, যেহেতু এসকিএলএক্সসেপশন ত্রুটিটি জানিয়েছে, তবে ডিবাগিং পদ্ধতিটি আমাদের পরে রয়েছে)।


3
@ রবহ্রুস্কা - খুব ভালভাবে ব্যাখ্যা করেছেন। +1 টি। আপনি কি এমন কোনও পার্সার সম্পর্কে জানেন যে ব্যতিক্রমটিকে স্ট্রিং হিসাবে গ্রহণ করে এবং স্ট্যাকট্রেস বিশ্লেষণের জন্য দরকারী পদ্ধতিগুলি সরবরাহ করে? - যেমন getLastCausedBy () বা getCausedByForMyappCode ("com.example.myproject")
অ্যান্ডি

1
@ অ্যান্ডি ডুফ্রেসনে - আমি কোনটিই পাইনি, তবে এরপরেও আমি আর সত্যিই সন্ধান করিনি।
রব হুশকা

1
প্রস্তাবিত উন্নতি: স্ট্যাক ট্রেসের প্রথম লাইনটি ব্যাখ্যা করুন যা Exception in thread "main"আপনার প্রথম উদাহরণে শুরু হয় । আমি মনে করি এটি ব্যাখ্যা করা বিশেষত সহায়ক হবে যে এই লাইনটি প্রায়শই একটি বার্তার সাথে আসে যেমন ভেরিয়েবলের মান, যা সমস্যাটি সনাক্ত করতে সহায়তা করে। আমি নিজেই একটি সম্পাদনা করার চেষ্টা করেছি, তবে আমি আপনার উত্তরটির বিদ্যমান কাঠামোর সাথে এই ধারণাগুলি ফিট করার জন্য লড়াই করছি।
কোড-শিক্ষানবিস

5
এছাড়াও জাভা ১.7 যোগ করেছে "দমনিত:" - যা এই ব্যতিক্রমের জন্য "এর দ্বারা তৈরি:" প্রদর্শন করার আগে দমন করা ব্যতিক্রম স্ট্যাকের ট্রেসগুলি তালিকাভুক্ত করে। এটি রিসোর্স কনস্ট্রাক্ট দিয়ে চেষ্টা করে স্বয়ংক্রিয়ভাবে ব্যবহার করা হয়: docs.oracle.com/javase/specs/jls/se8/html/… এবং এতে যদি ব্যয় হয় যে রিসোর্স (গুলি) বন্ধ করার সময় ছুঁড়ে দেওয়া হয়েছিল।
dhblah

একটি জেইপ ওপেনডজ.ইক.ভা.না.ট. / জেপস / 20২২০77১ রয়েছে যার লক্ষ্য হল "ফিল্ড 'নাল ইন্স্ট্যান্সফিল্ড' লিখতে পারি না কারণ 'এই.ইনলআইন্সটেন্সফিল্ডটি নাল' details
মহাত্মা_ফাতাল_রোপ

80

আমি এই উত্তরটি পোস্ট করছি তাই শীর্ষস্থানীয় উত্তর (যখন ক্রিয়াকলাপ অনুসারে সাজানো হয়) এমনটি নয় যা কেবল সাধারণ ভুল।

স্ট্যাকট্রেস কী?

একটি স্ট্যাকট্রেস একটি খুব সহায়ক ডিবাগিং সরঞ্জাম। এটি কল স্ট্যাক দেখায় (অর্থাত, ফাংশনগুলির স্ট্যাক যা সেই বিন্দু পর্যন্ত ডাকা হত) এমন সময় ব্যতীত একটি ব্যতিক্রম ছোঁড়া হয়েছিল (বা স্ট্যাকট্রেসটি ম্যানুয়ালি তৈরি হওয়ার সময়)। এটি খুব দরকারী কারণ এটি আপনাকে কেবল ত্রুটিটি কোথায় ঘটেছে তা প্রদর্শন করে না, তবে কোডটির সেই জায়গায় প্রোগ্রামটি কীভাবে শেষ হয়েছিল তাও আপনাকে প্রদর্শন করে না। এটি পরবর্তী প্রশ্নের দিকে নিয়ে যায়:

একটি ব্যতিক্রম কি?

রানটাইম এনভায়রনমেন্ট যা আপনাকে একটি ত্রুটি ঘটেছে তা জানাতে ব্যতিক্রম একটি ব্যতিক্রম। জনপ্রিয় উদাহরণগুলি হ'ল নালপয়েন্টার এক্সসেপশন, ইনডেক্সআউট অফফাউন্ডস এক্সসেপশন বা অ্যারিথমেটিক এক্সসেপশন। আপনি যখন এমন কিছু করার চেষ্টা করছেন যা সম্ভব না হয় তখন এগুলির প্রত্যেকটির কারণ হয়। উদাহরণস্বরূপ, আপনি নাল-অবজেক্টকে অবজ্ঞার চেষ্টা করার সময় একটি নালপয়েন্টার এক্সেক্সশন নিক্ষেপ করা হবে:

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.

স্ট্যাকট্রেস / ব্যতিক্রমগুলি কীভাবে আমার মোকাবেলা করা উচিত?

প্রথমে অনুসন্ধান করুন কী ব্যতিক্রম ঘটছে find ব্যতিক্রমটির নামটি গুগল করার চেষ্টা করুন ব্যতিক্রমটির কারণ কী। বেশিরভাগ সময় এটি ভুল কোডের কারণে ঘটবে। উপরের প্রদত্ত উদাহরণগুলিতে, ব্যতিক্রমগুলির সমস্তই ভুল কোডের কারণে ঘটে। সুতরাং নালপয়েন্টার এক্সসেপশন উদাহরণের জন্য আপনি নিশ্চিত করতে পারেন যে 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;
    }
}

কি এই কোড করার চেষ্টা করা হয় ধরা হয় ArithmeticException0. দ্বারা একটি সম্ভাব্য বিভাজন দ্বারা সৃষ্ট এটাও একটি সম্ভাব্য ক্যাচ NullPointerExceptionযে যদি নিক্ষিপ্ত হয় aবা bহয় null। এর অর্থ হল, আপনি একটি পেতে পারেন NullPointerExceptionতবে আপনি এটি একটি অ্যারিমেটিক এক্সেকশন হিসাবে বিবেচনা করবেন এবং সম্ভবত ভুল কাজটি করবেন। সেরা ক্ষেত্রে আপনি এখনও মিস করেন যে একটি নালপয়েন্টার এক্সসেপশন ছিল। এর মতো স্টাফ ডিবাগিংকে আরও শক্ত করে তোলে, তাই এটি করবেন না।

TLDR

  1. ব্যতিক্রমের কারণ কী তা নির্ধারণ করুন এবং এটি ঠিক করুন, যাতে এটি ব্যতিক্রমটি একেবারে ছুঁড়ে না ফেলে।
  2. যদি 1. সম্ভব না হয় তবে নির্দিষ্ট ব্যতিক্রমটি ধরুন এবং এটি পরিচালনা করুন।

    • কখনই কেবল চেষ্টা / যোগ করবেন না এবং কেবল ব্যতিক্রম উপেক্ষা করুন! যে না!
    • কখনও ব্যবহার করবেন না catch (Exception e), সর্বদা নির্দিষ্ট ব্যতিক্রমগুলি ধরুন। এটি আপনাকে অনেক মাথাব্যথা বাঁচাতে পারে।

1
কেন আমাদের বাগ মাস্কিং এড়ানো উচিত তার সুন্দর ব্যাখ্যা
সুদীপ ভান্ডারী

2
আমি এই উত্তরটি পোস্ট করছি তাই শীর্ষস্থানীয় উত্তরটি (যখন ক্রিয়াকলাপ অনুসারে সাজানো হয়) এমনটি নয় যা কেবল স্পষ্টতই ভুল, আমার কোন ধারণা নেই যে আপনি কোনটির সাথে কথা বলছেন যেহেতু সম্ভবত এই মুহুর্তে এখন বদলে গেছে। তবে গৃহীত উত্তরটি অবশ্যই আরও
হস্তক্ষেপমূলক

1
আমি যেটিকে বোঝাতে চাইছিলাম সেটি এখনই মুছে ফেলা হয়েছে। এটি মূলত বলেছে "কেবল একটি চেষ্টা করুন}} ধরা (ব্যাতিক্রম)}। এবং সমস্ত ত্রুটি উপেক্ষা করুন"। গৃহীত উত্তরটি আমার উত্তরের চেয়ে অনেক বেশি পুরনো তাই আমি বিষয়টি সম্পর্কে কিছুটা আলাদা দৃষ্টিভঙ্গি দেওয়ার লক্ষ্য নিয়েছিলাম। আমি মনে করি না যে এটি কাউকে কেবল অন্যের উত্তর অনুলিপি করতে বা অন্যান্য ব্যক্তি ইতিমধ্যে কী ভালভাবে আবৃত করেছে তা কভার করতে সহায়তা করে।
ডাকারন

"ব্যতিক্রম ধরবেন না" বলা বিভ্রান্তিকর, এটি কেবলমাত্র একটি ব্যবহারের ক্ষেত্রে case আপনার উদাহরণটি দুর্দান্ত তবে আপনি যেখানে আপনার থ্রেড লুপের শীর্ষে আছেন (অভ্যন্তরীণ রান) কীভাবে? আপনার সেখানে সর্বদা ব্যতিক্রম (বা সম্ভবত থ্রোয়েবল) ধরা উচিত এবং এটি লগ করা উচিত যাতে এটি অদৃশ্যভাবে বিলীন হয় না (রান থেকে ফেলে দেওয়া ব্যতিক্রমগুলি সাধারণত আপনার থ্রেড / লগার সেট না করে সঠিকভাবে লগ হয় না)।
বিল কে

1
আমি এই বিশেষ কেসটি অন্তর্ভুক্ত করি নি কারণ এটি কেবল মাল্টিথ্রেডিংয়ের সাথে গুরুত্বপূর্ণ। একক থ্রেডিংয়ে একটি ফাঁস হওয়া ব্যতিক্রম প্রোগ্রামটিকে মেরে ফেলে এবং দৃশ্যমানভাবে লগ হয়। যদি কেউ কীভাবে ব্যতিক্রমগুলি সঠিকভাবে পরিচালনা করতে না জানেন তবে তারা সাধারণত জানেন না যে এখনও মাল্টিথ্রেডিং কীভাবে ব্যবহার করতে হয়।
ডাকারন

21

রব যা উল্লেখ করেছে তাতে যোগ করতে। আপনার অ্যাপ্লিকেশনে ব্রেক পয়েন্ট সেট করা স্ট্যাকের ধাপে ধাপে প্রক্রিয়াজাতকরণের অনুমতি দেয়। এটি বিকাশকারীকে ডিবাগারটি ব্যবহার করতে সক্ষম করে তোলে তা দেখার জন্য পদ্ধতিটি কোন সঠিক সময়ে অপ্রত্যাশিত ছিল এমন কোনও সঠিক পদ্ধতি করছে।

যেহেতু রব NullPointerExceptionসাধারণ কিছু চিত্রিত করার জন্য (এনপিই) ব্যবহার করেছে , আমরা নিম্নলিখিত পদ্ধতিতে এই সমস্যাটি সরাতে সহায়তা করতে পারি:

আমাদের যদি এমন কোনও পদ্ধতি থাকে যা পরামিতি গ্রহণ করে যেমন: void (String firstName)

আমাদের কোডে আমরা মূল্যায়ন করতে চাই যার firstNameমধ্যে একটি মান রয়েছে, আমরা এটি এইভাবে করব:if(firstName == null || firstName.equals("")) return;

উপরেরগুলি আমাদের firstNameঅনিরাপদ প্যারামিটার হিসাবে ব্যবহার করতে বাধা দেয় । তাই প্রক্রিয়া করার আগে নাল চেক করে আমরা আমাদের কোডটি সঠিকভাবে চলবে তা নিশ্চিত করতে সহায়তা করতে পারি। পদ্ধতিগুলির সাহায্যে কোনও বস্তু ব্যবহার করে এমন উদাহরণকে প্রসারিত করার জন্য আমরা এখানে দেখতে পারি:

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

উপরেরটি নালগুলির জন্য পরীক্ষা করার যথাযথ আদেশ, আমরা এই ক্ষেত্রে বেস অবজেক্ট, কুকুর দিয়ে শুরু করি এবং তারপরে প্রক্রিয়াজাতকরণের আগে সবকিছু বৈধ কিনা তা নিশ্চিত করার জন্য সম্ভাবনার গাছটিতে হাঁটা শুরু করি। যদি আদেশটি উল্টো হয়ে যায় তবে একটি এনপিই সম্ভাব্যভাবে ছোঁড়া হতে পারে এবং আমাদের প্রোগ্রামটি ক্র্যাশ হয়ে যাবে।


একমত। উদাহরণস্বরূপ, nullযখন কোনও NullPointerExceptionপরীক্ষা করা হয় তখন কোনও বিবৃতিতে কোন রেফারেন্স হয় তা খুঁজে পেতে এই পদ্ধতির ব্যবহার করা যেতে পারে ।
রব হুশকা

16
স্ট্রিংয়ের সাথে কাজ করার সময়, আপনি যদি সমান পদ্ধতিটি ব্যবহার করতে চান তবে আমার তুলনাটির বাম দিকের ধ্রুবকটি ব্যবহার করা ভাল বলে মনে হয়: এর পরিবর্তে: যদি (প্রথম নাম == নাল || ফার্স্টনাম.এককালস ("" )) প্রত্যাবর্তন; আমি সর্বদা ব্যবহার করি: যদি (("") সমান (প্রথম নাম)) এটি নলপয়েন্টার ব্যতিক্রমকে বাধা দেয়
টরেস

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
আমি জানি না যে আমি এটি সম্পর্কে কী অনুভব করছি ... থ্রেডের প্রকৃতির সাথে, আমি নতুন দেবগণকে তাদের নিজস্ব স্ট্যাক ট্রেসটি সংজ্ঞায়িত না করার পরামর্শ দেব।
পিয়নপ্রোগ্রামার

15

নাম বোঝার জন্য : একটি স্ট্যাক ট্রেস হল ব্যতিক্রমগুলির (বা আপনি "কারণ দ্বারা" একটি তালিকা বলতে পারেন) এর সর্বাধিক পৃষ্ঠ ব্যতিক্রম (উদাহরণস্বরূপ পরিষেবা স্তর ব্যতিক্রম) থেকে গভীরতম পর্যন্ত (উদাহরণস্বরূপ ডাটাবেস ব্যতিক্রম) is আমরা একে 'স্ট্যাক' বলার কারণটির কারণ হ'ল স্ট্যাক ফার্স্ট ইন লাস্ট আউট (ফিলিও), গভীর ব্যতিক্রমটি খুব প্রথম দিকে ঘটেছিল, তারপরে ব্যতিক্রমের একটি শৃঙ্খলা তৈরি হয়েছিল ধারাবাহিক পরিণতি, পৃষ্ঠ ব্যতিক্রম সর্বশেষ ছিল একটি সময়ে ঘটেছিল, তবে আমরা এটি প্রথম স্থানে দেখতে পাই।

কী 1 : এখানে একটি জটিল এবং গুরুত্বপূর্ণ বিষয়টি বোঝার দরকার: গভীর কারণটি "মূল কারণ" নাও হতে পারে, কারণ আপনি যদি কিছু "খারাপ কোড" লিখেন তবে এটি নীচে কিছু ব্যতিক্রম ঘটতে পারে যা এর স্তরটির চেয়ে গভীর। উদাহরণস্বরূপ, একটি খারাপ স্ক্যেল কোয়েরি সিনড্যাক্স ত্রুটির পরিবর্তে বটেমটিতে এসকিউএল সার্ভারএক্সসেপশন সংযোগ পুনরায় সেট করতে পারে, যা স্ট্যাকের ঠিক মাঝখানে থাকতে পারে।

-> মাঝখানে মূল কারণটি সনাক্ত করা আপনার কাজ। এখানে চিত্র বর্ণনা লিখুন

কী 2 : আর একটি জটিল তবে গুরুত্বপূর্ণ বিষয় প্রতিটি "কারণ বাই" ব্লকের ভিতরে রয়েছে, প্রথম লাইনটি গভীর স্তর ছিল এবং এই ব্লকের জন্য প্রথম স্থান হয় happen এই ক্ষেত্রে,

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 দ্বারা ডেকে আনা হয়েছিল যা বুটস্ট্র্যাপ বলেছিল ava জাভা 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

অন্যান্য পোস্টগুলি স্ট্যাক ট্রেস কী তা বর্ণনা করে তবে এটি দিয়ে কাজ করা এখনও শক্ত হতে পারে।

আপনি যদি একটি স্ট্যাক ট্রেস পেতে এবং ব্যতিক্রমের কারণ ট্রেস করতে চান তাহলে, বুঝতে একটি ভালো শুরু বিন্দু এটি ব্যবহার করতে হয় জাভা ট্রেস স্ট্যাক কনসোল মধ্যে অন্ধকার । আপনি যদি অন্য আইডিই ব্যবহার করেন তবে অনুরূপ বৈশিষ্ট্য থাকতে পারে, তবে এই উত্তরটি গ্রহন সম্পর্কে।

প্রথমে নিশ্চিত হয়ে নিন যে আপনার কাছে আপনার সমস্ত জাভা উত্স কোনও একিপ্লিজ প্রকল্পে অ্যাক্সেসযোগ্য।

তারপরে জাভা দৃষ্টিকোণে কনসোল ট্যাবে ক্লিক করুন (সাধারণত নীচে)। যদি কনসোল ভিউটি দৃশ্যমান না হয় তবে মেনু বিকল্প উইন্ডো -> প্রদর্শন প্রদর্শনে যান এবং কনসোলটি নির্বাচন করুন ।

তারপরে কনসোল উইন্ডোতে, নীচের বোতামটিতে ক্লিক করুন (ডানদিকে)

কনসোল বোতাম

এবং তারপরে ড্রপ-ডাউন তালিকা থেকে জাভা স্ট্যাক ট্রেস কনসোলটি নির্বাচন করুন ।

কনসোলে আপনার স্ট্যাক ট্রেস আটকে দিন। এরপরে এটি আপনার উত্স কোড এবং অন্য যে কোনও সোর্স কোড উপলব্ধ লিংকের একটি তালিকা সরবরাহ করবে।

আপনি যা দেখতে পাচ্ছেন এটিই হ'ল (একিপেস ডকুমেন্টেশন থেকে চিত্র):

অ্যাকলিপস ডকুমেন্টেশন থেকে ডায়াগ্রাম

সর্বাধিক সাম্প্রতিক পদ্ধতিতে কল করা হবে স্ট্যাকের শীর্ষে , যা শীর্ষ লাইন (বার্তা পাঠ্য বাদে)। স্ট্যাকের নিচে যেতে সময়মতো ফিরে যায়। দ্বিতীয় লাইনটি এমন পদ্ধতি যা প্রথম লাইনে ডাকে ইত্যাদি is

আপনি যদি ওপেন সোর্স সফ্টওয়্যার ব্যবহার করে থাকেন তবে যদি আপনি পরীক্ষা করতে চান তবে আপনাকে আপনার প্রকল্পের উত্সগুলি ডাউনলোড করতে এবং সংযুক্ত করতে হবে। সোর্স জারগুলি ডাউনলোড করুন আপনার প্রকল্পে, আপনার ওপেন সোর্স মডিউলটির জন্য জারটি সন্ধান করতে রেফারেন্সড লাইব্রেরি ফোল্ডারটি খুলুন (ক্লাস ফাইলগুলির সাথে একটি) তারপরে ডান ক্লিক করুন, বৈশিষ্ট্য নির্বাচন করুন এবং উত্স জারের সংযুক্ত করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.