Today, the SLF4J is logger in a synchronous package. The main purpose is to facilitate the replacement of the log implementation system later.
Problem encountered: Use Thread.CurrentThread (). Getstacktrace () [1].getclassname () gets the current class instead of the calling class. See the following code:
Private Org.slf4j.Logger Logger = null;/** * Construction method */public Logger () {//Get the current class Loggerlogger = Loggerfactory.getlogger (Thread.CurrentThread (). Getstacktrace () [1].getclassname ());
So when you print the log, you don't get the information about the class that the log really belongs to.
Then I carried out a set of tests:
Test A:
public class ThreadTest {public static void TestString () {stacktraceelement[] arr = new Exception (). Getstacktrace (); for ( int i=0;i<=arr.length-1;i++) {System.out.println (Arr[i].getclassname () + ";" +arr[i].getmethodname () + ";" +arr[i].getfilename ());}}}
public class App {public static void Main (string[] args) { threadtest.teststring ();} }
The result is:
Test. ThreadTest; teststring; Threadtest.java (current method and Class)
Test. App;main; App.java (Methods and classes that call the method)
Test B:
public class ThreadTest {public static void TestString () {stacktraceelement[] arr = Thread.CurrentThread (). Getstacktrace (); for (int i=0;i<=arr.length-1;i++) {System.out.println (Arr[i].getclassname () + ";" +arr[i].getmethodname () + ";" +arr[i].getfilename ());}}}
The app is similar. The resulting results are:
Java.lang.thread;getstacktrace; Thread.java (thread's information)
Test. ThreadTest; teststring; Threadtest.java (current method and Class)
Test. App;main; App.java (Methods and classes that call the method)
What rice situation??? Is it because the thread of the Getstacktrace than Throwable (exception of the parent class) of the Getstacktrace more hit a section of the thread class information???
Because I'm not sure if this is really the case, the deceased looked at the source code for the next JDK (it's a purely X-ray, no fantasy).
The first is the Getstacktrace method of the Throwable, the code such as the following:
Public stacktraceelement[] Getstacktrace () { return Getourstacktrace (). Clone (); Private synchronized stacktraceelement[] Getourstacktrace () { //Initialize stack trace field with information from
//BackTrace If this is the first call to this method if (stackTrace = = Unassigned_stack | | (StackTrace = = NULL && backtrace! = null)/* Out of protocol state */) { int depth = getstacktracedepth ();
stacktrace = new Stacktraceelement[depth]; for (int i=0; i < depth; i++) stacktrace[i] = getstacktraceelement (i); } else if (stackTrace = = null) { return unassigned_stack; } return stackTrace; }
There seems to be nothing wrong with the place Ha, among
int depth = getstacktracedepth ();
Stacktrace[i] = getstacktraceelement (i);
Two methods are native, not to delve into. No problem is found here. Went to see the next thread of the Getstacktrace method, code such as the following:
Public stacktraceelement[] Getstacktrace () {if (This! = Thread.CurrentThread ()) {//Check for Getstack Trace permission SecurityManager security = System.getsecuritymanager (); if (Security! = null) {security.checkpermission (securityconstants.get_stack_trace_perm Ission); }//Optimization so we don't call to the the VM for threads that//has not yet started or has ter minated if (!isalive ()) {return empty_stack_trace; } stacktraceelement[][] Stacktracearray = dumpthreads (new thread[] {this}); stacktraceelement[] StackTrace = stacktracearray[0]; A thread that is alive during the previous isAlive call May has//since terminated, therefore not had A stacktrace. if (StackTrace = = null) {stackTrace = Empty_stack_trace; } return stackTrace; } else {//Don ' t need JVM help for current thread return (new Exception ()). Getstacktrace (); } }
At first glance there is nothing wrong AH ~ ~ ~ Not right, suddenly follow the logic to walk. Inside the IF statement because
This! = Thread.CurrentThread () is true. So the method runs the statement inside the else, what's inside.!!
!
Return (new Exception ()). Getstacktrace ();
All right!
This is the place where the JVM goes to run the new Exception (). Getstacktrace (); It is this sentence that makes use of Thread Getstacktrace method is possible to print a sentence java.lang.Thread; Getstacktrace; Thread.java out. That's why you use
Logger = Loggerfactory.getlogger (Thread.CurrentThread (). Getstacktrace () [1].getclassname ()];
Can not get the correct log information for the reason.
That's the way it should be. In order to verify that I was wrong, I wrote an example of a test pass, such as the following code:
public class TestException {public static stacktraceelement[] Getstacktrace () {return new Exception (). Getstacktrace ();}}
public class ThreadTest {public static void TestString () {stacktraceelement[] arr = Testexception.getstacktrace (); int i=0;i<=arr.length-1;i++) {System.out.println (Arr[i].getclassname () + ";" +arr[i].getmethodname () + ";" +arr[i].getfilename ());}}}
public class App {public static void Main (string[] args) { threadtest.teststring ();} }
The result after the run is:
Test. Testexception;getstacktrace; Testexception.java
Test. ThreadTest; teststring; Threadtest.java
Test. App;main; App.java
The red line proves that my idea is correct!
All the validations are over. The final solution to this problem is very easy, either using the new Exception (). Getstacktrace () [1]; either use Thread.CurrentThread (). Getstacktrace () [2].
Although this problem is very small, it is very basic. But I'm still very excited. After all, glue on the source code, immediately forcing lattice rise a lot ~ ~ ~
Novice on the road. Master Mercy ~!
A tangle of two ways to get current stack information (thread and Throwable)