Что такое стектрейс java
Перейти к содержимому

Что такое стектрейс java

  • автор:

Как работать со стектрейсами в джаве

Навык решения проблем — один из наиблоее ценных навыков программиста. Когда вы будете выполнять задания нашего курса, то, скорее всего, в процессе вашей работы будут возникать те или иные трудности. Одна из часто встречающихся проблем — какого почему это не работает?! К счастью, люди, которые разрабатывают языки программирования или фреймворки к ним, предусмотрели все это и придумали такую крутую вещь, как стектрейс (stacktrace).

Если говорить простыми словами это просто путь выполнения вашей программы, сгруппированный по стекам её выполнения. Если вы не знаете, что такое стек выполнения, то рекомендуем сначала ознакомиться с этой статьей

Консольное приложение

Вы можете в любой момент посмотреть текущий стек вызовов в любой программе, всего лишь остановившись на брейкпоинте в режиме дебага, например: hello-world

Нас интересует левая часть вкладки дебага. В ней будет показан поток, который дошел до точки остановки (в нашем случае это main»@1 in group «main — то есть основной поток). Чуть ниже будет показан искомый call stack. Он начинается, как и любая программа в джаве, с мейн-класса main:7, JavaBasics (com.epam.izh.rd.online) , далее в этом методе произошел вызов метода demo:8, DemoService (com.epam.izh.rd.online.service) , а затем и getEvenDigits:55, SimpleMathService (com.epam.izh.rd.online.service) То есть элементы call stack’a расположены в порядке, идентичному схеме First In Last Out (как и в настоящем стеке)

Давайте попробуем воспроизвести самую встречающуюся ошибку начинающих (и не только) программистов — NullPointerException Запустили, смотрим в консоль и видим следующее: hello-world

Что же мы можем здесь понять? Самая первая строчка — это просто команда, которой IDE запустила нашу программу, это нам не интересно. А вот далее — Exception in thread «main» java.lang.NullPointerException — и есть причина ошибки нашей программы. Но как понять где она реально произошла? В этом нам поможет стектрейс, а именно самый верхний стек, на котором мы находились в тот момент времени — at com.epam.izh.rd.online.service.SimpleMathService.getEvenDigits(SimpleMathService.java:55) . Видим, что ошибка возникает в методе getEvenDigits класса SimpleMathService в строке 55.

Spring-приложение

К сожалению, в реальной работе мы почти не пишем консольных программ, а пользуемся фреймворками. Давайте попробуем сделать ошибку в простом web-приложении (в котором используется Spring Boot) и разобраться, в чем причина.

У нас получился следующий стектрейс (чтобы лучше было видно, можно открыть эту картинку в новой вкладке): hello-world

На первый взгляд, ничего не понятно. Но давайте разберем по шагам, что тут написано. Как можно заметить, здесь всего 5 стектрейсов: hello-world

Первый (1) стектрейс начинается методом Thread.run — это начало того потока, в котором произошла ошибка (дело в том, что обычно веб-приложения) имеют не единственный поток выполнения. Далее мы видим что выскочил BeanCreationException — не удалось создать бин bookController . Но это не причина возникновения этой ошибки, если присмотреться, то в стектрейсах (2) и (3) аналогичное исключение с бинами bookService и bookDao — это потому что бин bookController зависел от них. А в стектрейсе (4) другая ошибка — NoSuchBeanDefinitionException . Обычно это означает что спринг не нашел дефинишена бина, а дефолтный бин не был предусмотрен контейнером, но при этом мы ожидаем, что этот бин будет создан.

Ну и наконец в стектрейсе (5) мы видим исходную ошибку. Почему же в итоге стектрейсов получилсь 5? Дело в том, что во всех серьезных проектах используется техника ExceptionWrapping-a подробнее про это можно прочитать в этой статье

Developed by Timur Sokolov and Ilia Isakhin.

We believe that knowledge is the most powerful tool you can use to change your life for better.

Что такое stack trace, и как с его помощью находить ошибки при разработке приложений?

Иногда при запуске своего приложения я получаю подобную ошибку:

Мне сказали, что это называется «трассировкой стека» или «stack trace». Что такое трассировка? Какую полезную информацию об ошибке в разрабатываемой программе она содержит?

Немного по существу: довольно часто я вижу вопросы, в которых начинающие разработчики, получая ошибку, просто берут трассировки стека и какой-либо случайный фрагмент кода без понимания, что собой представляет трассировка и как с ней работать. Данный вопрос предназначен специально для начинающих разработчиков, которым может понадобиться помощь в понимании ценности трассировки стека вызовов.

Nicolas Chabanovsky's user avatar

Простыми словами, трассировка стека – это список методов, которые были вызваны до момента, когда в приложении произошло исключение.

Простой случай

В указанном примере мы можем точно определить, когда именно произошло исключение. Рассмотрим трассировку стека:

Это пример очень простой трассировки. Если пойти по списку строк вида «at…» с самого начала, мы можем понять, где произошла ошибка. Мы смотрим на верхний вызов функции. В нашем случае, это:

Для отладки этого фрагмента открываем Book.java и смотрим, что находится на строке 16 :

Это означает то, что в приведенном фрагменте кода какая-то переменная (вероятно, title ) имеет значение null .

Пример цепочки исключений

Иногда приложения перехватывают исключение и выбрасывают его в виде другого исключения. Обычно это выглядит так:

Трассировка в этом случае может иметь следующий вид:

В этом случае разница состоит в атрибуте «Caused by» («Чем вызвано»). Иногда исключения могут иметь несколько секций «Caused by». Обычно необходимо найти исходную причину, которой оказывается в самой последней (нижней) секции «Caused by» трассировки. В нашем случае, это:

Аналогично, при подобном исключении необходимо обратиться к строке 22 книги Book.java , чтобы узнать, что вызвало данное исключение – NullPointerException .

Еще один пугающий пример с библиотечным кодом

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

В этом примере приведен далеко не полный стек вызовов. Что вызывает здесь наибольший интерес, так это поиск функций из нашего кода – из пакета com.example.myproject . В предыдущем примере мы сначала хотели отыскать «первопричину», а именно:

Однако все вызовы методов в данном случае относятся к библиотечному коду. Поэтому мы перейдем к предыдущей секции «Caused by» и найдем первый вызов метода из нашего кода, а именно:

Stack Trace и с чем его едят

Принцип работы коллекции Stack

В этой статье вы узнаете и поймете, как работает такое явление в Java, как StackTrace, так же известное как «Трассировка стека вызовов». Эта информация была структурирована для новичков, столкнувшихся с этим понятием в начале девятого уровня Java Syntax. Я думаю все из вас, хоть раз, но встречали похожие ошибки при работе в вашем IDE, независимо от того будь это Idea, Eclipse или что-то другое. Это, как вы уже догадались и есть наша трассировка. Но не спешите паниковать, сейчас мы с вами разложим данный пример на пальцах. Для начала необходимо понять тот факт, что StackTrace работает как Стэк и это видно из его названия. На этом месте мы остановимся чуть поподробнее. На восьмом уровне вы уже познакомились с коллекциями и знаете что они делятся на три группы Set — множество, List — список, Map — словарь (или карта). По мнению JavaRush (c). Наш Stack входит в группу List . Принцип его работы можно описать как LIFO, что расшифровывается как Last In First Out(Последний пришел, первый ушел). А именно это такой список похожий на стопку книг, чтобы взять элемент который мы положили в Stack первым, нам необходимо сначала извлечь все элементы которые мы добавили в наш список после. Как это указано на картинке выше в отличии например от обычного списка ArrayList где мы можем получить любой элемент из списка по индексу. Еще раз для закрепления. Получение элемента из Стэка возможно только с конца! В то время как первый добавленный в него элемент находится в начале(или на дне как удобнее). Вот какие методы имеет наш Stack Object push() — Добавляет элемент в верх стека. Object pop() — Возвращает элемент, находящийся в верхней части стэка, удаляя его в процессе. Object peek() — Возвращает элемент, находящийся в верхней части стэка, но не удаляет его. int search() — Ищет элемент в стеке. Если найден, возвращается его смещение от вершины стека. В противном случае возвращается -1. boolean empty() — Проверяет, является ли стек пустым. Возвращает true, если стек пустой. Возвращает false, если стек содержит элементы. Так для чего же в Java нужен StackTrace построеный на принципах работы Stack ? Давайте разберем пример ошибки ниже, которая возникла в процессе выполнения такой вот простой программы. У нас есть класс Test с двумя методами. Всем привычный main и convertStringToInt логика которого заключается в конвертировании и возврате полученной извне(а именно из метода main ) строки в целочисленное число типа int . Как вы видите мы намеренно передали вместо строки с какой-нибудь цифрой, параметр null . Данный параметр наш метод не смог правильно обработать и вызвал ошибку NumberFormatException . Как вы знаете программа начинает отрабатывать свою работу из метода main и в этот момент она создает новый Стэк с названием StackTrace куда кладет текущее значение ее работы под номером 1, далее мы переходим в метод convertStringToInt и программа опять заносит параметры нашего нахождения в созданный ранее StackTrace под номером 2, далее вызывается не видимый нашему глазу метод parseInt находящийся в классе Integer и это уже будет элемент под номером 3 нашего StackTrace , в этом методе будет еще один внутренний вызов добавленный в StackTrace под номером 4 для проверки элемента на null который и приведет к ошибке. Программе необходимо вывести нашу ошибку с указанием всей цепочки наших переходов до момента возникновения ошибки. Тут то ей и приходит на помощь ранее созданный StackTrace с данными наших переходов. До возникновения ошибки, программа шла вглубь методов, но как только возникла ошибка, все начинает происходить в обратном порядке. Печатается строка с описанием проблемы(№1 на примере), далее берется последнее (и находящееся на вершине) добавленное значение в наш Стэк оно было под номером четыре и печатается в консоль(№2 на примере) и мы видим что проблема возникла в классе Integer на 614 строке кода и вызвала эту строку, строка 770 метода parseInt того же класса(№3 на примере) которая при добавлении в Стэк была под номером три и этот метод класса Integer все еще не видимый нам был вызван уже нашим методом convertStringToInt располагающемся на 10 строке нашей программы(№4 на примере, а при добавлении он был вторым), а его в свою очередь вызвал main на 6 строке(№5 на примере, а при добавлении соответственно первый). Вот так вот, складируя в Стек шаг за шагом наши вызываемые методы мы смогли вернуться обратно в main параллельно печатая информацию что именно привело нас к ошибке. Но StackTrace это не только работа с ошибками, он позволяет получить нам кучу интересной информации о процессе работы нашего приложения. Давайте разберем еще один популярный пример в комментариях к основной лекции 9го уровня. У нас есть код и к нему сразу прикреплю картинку визуализирующую процесс работы программы: alt=»Stack Trace и с чем его едят — 2″ width=»800″ height=»500″ />Тут наша программа безошибочно выполняет свою работу и заканчивается. Вот что мы увидим в выводе консоли: Как у нас получился такой вывод и что же произошло в пятом методе начиная с 20й строки? Боюсь самое лучше что я смогу сделать это добавить самое популярное объяснение(в сокращении) юзера Кирилла из комментариев к лекции. Обратимся к строчке по созданию StackTrace и разберем ее поэлементно: StackTraceElement[] — указание на тип массива(На ранних уровнях вы уже проходили массивы типа int[], String[], вот тут тоже самое). stackTraceElements — имя массива, может быть любым с учетом общих правил наименования на работу эту не влияет. Thread.currentThread() — получение ссылки на текущий поток, в котором выполняются методы, которые мы хотим отследить(пока это не важно, подробнее потоки вы будете разбирать на 16 уровне в квесте Java Core) getStackTrace() — получаем весь Стэк вызываемых методов(Это обычный геттер для StackTrace ) Теперь посмотрим, чем нам может быть полезен созданный массив. Мы понимаем, что в массиве хранится инфа о выполненных методах.(с) И для этого в 21й строке мы запускаем модифицированный цикл for под названием forEach (кстати кто еще не изучил этот цикл, советую почитать о нём) и выводим данные из массива в консоль, а именно информацию какие методы выполнялись в процессе работы посредством конструкции element.getMethodName() . Внимание как мы видим нулевым элементом массива у нас оказался сам getStackTrace() соответственно так как в момент получения массива данных он был последним методом что выполнился и тем самым оказавшись на верхушке Стэка , а помня про нашу конструкцию «Последний пришел, первый ушел» сразу же первым добавляется в массив под нулевым элементом. Вот что еще мы можем получить из StackTraceElement : String getClassName() — Возвращает имя класса. String getMethodName() — Возвращает имя метода. String getFileName() — Возвращает имя файла (в одном файле может быть много классов). String getModuleName() — Возвращает имя модуля (может быть null). String getModuleVersion() — Возвращает версию модуля (может быть null). int getLineNumber() — Возвращает номер строки в файле, в которой был вызов метода. Теперь, когда вы поняли общий принцип работы, советую вам самим опробовать разные методы StackTrace в вашей Ide. Даже если вы не совсем всё усвоили, продолжайте обучение и мозаика сложится так же как сложилась у меня в данном вопросе. Желаю вам всем успехов! P.s. Если вам понравился данный материал, пожалуйста поддержите лайком. Вам не трудно, мне приятно. Спасибо и увидимся на 41 уровне 😉

What is a Java Stack Trace? How to Read & Analyze Traces

What is a Java Stack Trace? How to Read & Analyze Traces

A Java stack trace is displayed when an error or exception occurs. The stack trace, also called a backtrace, consists of a collection of stack records, which store an application's movement during its execution.

The stack trace includes information about program subroutines and can be used to debug or troubleshoot and is often used to create log files. These exceptions could be custom (defined by the user) or built-in. Examples include RuntimeException , NullPointerException , and ArrayIndexOutofBoundsException .

Now that you know what a stack trace is, let’s take a look at some examples, how to analyze stack traces, and how you can avoid a stack trace altogether with error handling.

Examples of Java Stack Traces

Example 1 — Temperature Conversion from Celsius to Fahrenheit

Let's look at an example of converting temperatures from Celsius to Fahrenheit. Only an integer or float input is valid here. But if we try to provide another data type, such as a string, the compiler will throw an exception and print the stack trace.

When we run the above code and enter some invalid value, let’s say the string "hero," we get the following output:

Example 2 — Function Chaining

This is an example of function chaining, in which one function calls another in a chain-like fashion. Unlike in Example 1, no exception is thrown here, but the stack trace is explicitly printed using the dumpstack() method (a useful method when creating log files). This is good practice because we can use this code later for maintenance or to check the overall health or condition of the application.

When the above code is executed, we get the following output:

How to Read and Analyze Example 1’s Stack Trace

Let’s consider Example 1 for this analysis. Below is the breakdown of the output from its execution:

The first line in the stack trace:

First line in stack trace

The bottom line in the stack trace:

Bottom line in stack trace

Now, let’s look at the entire stack trace and try to analyze it:

The main() method is at the bottom of the stack because that is where the program began. By reading from bottom to top, we can now identify where and what exception is being raised. Tracing the source of this error back to the main() method reveals that an exception occurs when the user's input is taken.

The second line from the top shows that the float input was taken using the function nextFloat() , which in turn calls the next() function, which in turn calls the throwFor() function. As a result, it throws an InputMismatchException .

How to Fix Example 1’s Code Using Error Handling and Stack Traces

Stack traces and exceptions are clearly related, as evidenced by the preceding examples. Stack traces can be avoided; in short, some common error handling techniques can be used to handle and resolve any exceptions thrown by the code during execution. The technique listed below can help avoid a stack trace.

Examine, Investigate, and Handle Java Errors

It's common for amateur programmers to overlook exceptions in their code. Being able to examine, investigate, and handle mistakes can be very helpful prior to moving to the next step. Let’s handle the exception in Example 1 by using try and catch statements.

In the above code, we have used a try — catch block to catch the exception and then print a custom message to notify the user to enter a valid input.

When the code above is executed, we get the following output:

Enter value in Celsius to convert in fahrenheit: hero
Wrong input type entered. exiting the program

Process finished with exit code 0

With the help of the try and catch blocks, the code to be tested is placed in the try block and any exception thrown by the code is handled in the catch block.

This is the most commonly used method to handle exceptions in Java and thus avoid stack traces.

Track, Analyze and Manage Errors With Rollbar

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyse, and manage errors in real-time can help you proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Java errors easier than ever. Sign Up Today!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *