StackTraceElement Example

0

When a Java virtual machine runs a program, it needs memory to store many things. The memory is organized based on the following need:

  1. Loading classes – Extracts information from class files and stores them in method area.
  2. Creating Objects – As the program runs, JVM creates new objects and places them onto the heap area
  3. Calling Methods – As each new thread comes into existence, it gets its own program counter (pc) and Java stack. The value of the pc register indicates the next instruction to execute. If the thread is executing a Java method, the thread’s Java stack stores the method’s local variables, the parameters with which it was invoked, its return value (if any), and intermediate calculations. All this is put onto the stack

In this article we will see an example of extracting the stack trace elements but before that let’s see Java Stack’s composition and what happens to it when a method is invoked and after it is complete.

Java Stack

The Java stack is composed of stack frames where each frame contains the state of one Java method invocation. When a thread invokes a method, the JVM pushes a new frame onto that thread’s Java stack. When the method completes, the JVM pops and discards the frame for that method.

StackTraceElement Structure

Each stack frame is represented by StackTraceElement. The frame at the top of the stack at the zeroth element represents the execution point at which the stack trace was generated. The last element of the array represents the bottom of the stack, which is the first method invocation in the sequence. Throwable.getStackTrace() provides programmatic access to the stack trace information.
In this example we will use the StackTraceElement array to deduce the main method in the stack trace.

SomeApplication:

package com.javarticles.concurrency;

import java.util.Arrays;

public class SomeApplication {
    private Class<?> mainClass;
    public SomeApplication(Object... sources) {
        initialize(sources);
    }
    
    private void initialize(Object[] sources) {
        mainClass = deriveMainClass(); 
        System.out.println("Initialize application, main class: " + mainClass);
    }

    public static void launch(Object source, String... args) {
       new SomeApplication(new Object[]{source}).run(args);    
    }

    private void run(String[] args) {
        System.out.println("Run application with args [" + args + "]");
    }
    
    private Class<?> deriveMainClass() {
        try {
            StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
            System.out.println("Stack Trace");
            for (Object stack : Arrays.asList(stackTrace)) {
                System.out.println(stack);
            }
            for (StackTraceElement stackTraceElement : stackTrace) {
                if ("main".equals(stackTraceElement.getMethodName())) {
                    return Class.forName(stackTraceElement.getClassName());
                }
            }
        }
        catch (ClassNotFoundException ex) {
        }
        return null;
    }
}

Output:

Stack Trace
com.javarticles.concurrency.SomeApplication.deriveMainClass(SomeApplication.java:26)
com.javarticles.concurrency.SomeApplication.initialize(SomeApplication.java:12)
com.javarticles.concurrency.SomeApplication.(SomeApplication.java:8)
com.javarticles.concurrency.SomeApplication.launch(SomeApplication.java:17)
com.javarticles.concurrency.StackTraceElementExample.main(StackTraceElementExample.java:6)
Initialize application, main class: class com.javarticles.concurrency.StackTraceElementExample
Run application with args [[Ljava.lang.String;@15db9742]

Download the source code

This was an example about Java StackTraceElement.

You can download the source code here: javaStacktraceElementExample.zip
Share.

Comments are closed.