Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can an Exception be created/thrown with no stack trace? [duplicate]

I was trawling through some logs today and came across a strange error.

Here's how it appears in the log:

2014/09/11 15:23:52.801 [CC3A5FDD16035540B87F1B8C5E806588:<removed>] WARN a.b.c.Ddd - Main failure 
java.lang.NullPointerException: null
2014/09/11 15:23:52.801 [CC3A5FDD16035540B87F1B8C5E806588:<removed>] ...

and here's what the code looks like:

} catch (Exception e) {
    Ddd.log.warn("Main failure ", e);
    throw e;
}

The code is in a jsp if that is important. The same exception is repeated once more in the log (as you'd expect from the throw e).

I have no record of what the cause was - the previous line in the log shows execution of a query. This occurred just twice over a 4-day period and seems not to have caused any harm to the system.

Environment: Fairly busy web service running under Tomcat with Java 5.

I am not asking for tips on debugging the system - these errors are long-gone and may even never happen again. I was just stumped as to how any exception (especially an NPE) could be created without a stack trace?

Added

The logger being used is an slf4j driven Logback instance. I believe the warn method is here. Not sure what Logback method that resolves to but I am confident the Throwable parameter is treated specially and if there was an stack trace attached to the Throwable it would appear in the log.

LogBack.xml - as requested:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <property name="log.package" value="Package" />
  <property name="log.pattern" value="%date{yyyy/MM/dd HH:mm:ss.SSS} [%X{session}:%X{device}] %level %logger{25} - %msg%n"/> 
  <property name="log.consolePattern" value="%highlight(%-5level) %white(%logger{25}) - %msg%n"/> 
  <if condition='isDefined("catalina.home")'>
    <then>
      <property name="log.dir" value="${catalina.home}/logs" />
    </then>
    <else>
      <property name="log.dir" value="." />
    </else>
  </if>

  <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <level>DEBUG</level>
    </filter>
    <encoder>
      <Pattern>${log.consolePattern}</Pattern>
    </encoder>
  </appender>

  <appender name="rolling" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${log.dir}/${log.package}.log</file>
    <encoder>
      <Pattern>${log.pattern}</Pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${log.dir}/${log.package}.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
      <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <!-- or whenever the file size reaches 16MB. -->
        <maxFileSize>16MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
      <!-- Keep no more than 3 months data. -->
      <maxHistory>90</maxHistory>
      <cleanHistoryOnStart>true</cleanHistoryOnStart>
    </rollingPolicy>
  </appender>

  <!-- Default logging levels. -->
  <root level="INFO">
    <appender-ref ref="console"/>
    <appender-ref ref="rolling"/>
  </root>
  <!-- Specific logging levels. -->
  <!-- Generally set to INFO or ERROR but if you need more details, set to DEBUG. -->
  <logger name="org.apache" level="INFO"/>
  <logger name="net.sf.ehcache" level="ERROR"/>
  <logger name="com.zaxxer" level="ERROR"/>
  <logger name="ch.qos" level="ERROR"/>
</configuration>

I hand-edited out the values after the session ID in the log to remove customer data.

like image 529
OldCurmudgeon Avatar asked Sep 15 '14 08:09

OldCurmudgeon


People also ask

What is a stack trace and how does it relate to an exception?

Simply put, a stack trace is a representation of a call stack at a certain point in time, with each element representing a method invocation. The stack trace contains all invocations from the start of a thread until the point it's generated. This is usually a position at which an exception takes place.

What is stack trace exception?

A trace of the method calls is called a stack trace. The stack trace listing provides a way to follow the call stack to the line number in the method where the exception occurs. The StackTrace property returns the frames of the call stack that originate at the location where the exception was thrown.

How do I disable stack trace?

If you wish to disable this feature, simply append /? showtrace=0 to the URL, and the stack trace should disappear after reloading your browser.

Can exception stack trace null?

Yes. If you create a new Exception() and don't throw it, every property except Data and Message will be null.


2 Answers

Sometimes, especially when it comes to NullPointers (in my experience), the jvm can optimize the creation and casting of exceptions, and the stack trace is lost (or more correctly, never created). I suspect that your issue is not related to certain java libs, but rather the jvm itself.

If you add this argument when starting your jvm-process you will get your stack traces back, if my suspicion is correct.

-XX:-OmitStackTraceInFastThrow

This has been asked before, look here for more details:

  • NullPointerException in Java with no StackTrace
  • Recurring Exception without a stack trace - how to reset?

Note, that this applies sun/oracle jvm

like image 90
emanciperingsivraren Avatar answered Oct 14 '22 01:10

emanciperingsivraren


  1. Maybe the log does not log also the stack trace?
  2. Here is an example on how an exception does not have stack trace:

    try {
      throw new Exception() {
        @Override
        public synchronized Throwable fillInStackTrace() {
          return null;
        }
      };
    } catch (Exception e) {
      e.printStackTrace();
    }
    

So maybe that particular exception is a custom one with #fillInStackTrace() overridden, but is strange anyway.

like image 40
Cristian Sulea Avatar answered Oct 14 '22 02:10

Cristian Sulea