Sun JDK source code download http://wwws.sun.com/software/communitysource/
Register and log on to "Sun community source licensing", and then download j2se (dozens of megabytes) or J2EE (hundreds of megabytes ).
Log can print out the code running time, class name, method name, and information.
An intuitive example: each time Tomcat is started (default configuration. Generally, you can see
Jul 9, 2004 11:22:29 am org. Apache. Struts. util. propertymessageresources <init>
Info: initializing, Config = 'org. Apache. webapp. admin. applicationresources', returnnull = true
Jul 9, 2004 11:22:41 am org. Apache. Coyote. http11.http11protocol start
Info: Starting coyote HTTP/1.1 on port 8080
Time, class name, method name, and information are printed.
So how does log obtain the class that calls itself and the method name?
The code below is the source code of jdk1.4 and the source code of log4j. Describe its implementation principles.
To obtain the call class and method name is to obtain the structure of the current running stack.
New throwable (). getstacktrace () returns the structural hierarchy of the current running stack.
Using this principle, you can obtain the call relationship of the entire running stack.
The Java. util. Logging package of jdk1.4 is implemented through the throwable. getstacktrace () method.
// Get the stack trace.
Stacktraceelement stack [] = (New throwable (). getstacktrace ();
The complete code is in the source code of jdk1.4, And the infercaller method of the Java. util. Logging. logrecord class is used.
Java code
// Private method to infer the caller's class and method names <br/> private void infercaller () {<br/> needtoinfercaller = false; <br/> // get the stack trace. <br/> stacktraceelement stack [] = (New throwable ()). getstacktrace (); <br/> // first, search back to a method in the logger class. <br/> int IX = 0; <br/> while (IX <stack. length) {<br/> stacktraceelement frame = stack [ix]; <br/> string cname = FRA Me. getclassname (); <br/> If (cname. equals ("Java. util. logging. logger ") {<br/> break; <br/>}< br/> IX ++; <br/>}< br/> // now search for the first frame before the "logger" class. <br/> while (IX <stack. length) {<br/> stacktraceelement frame = stack [ix]; <br/> string cname = frame. getclassname (); <br/> If (! Cname. equals ("Java. util. logging. logger ") {<br/> // we 've found the relevant frame. <br/> setsourceclassname (cname); <br/> setsourcemethodname (frame. getmethodname (); <br/> return; <br/>}< br/> IX ++; <br/>}< br/> // We haven'tfound a suitable frame, so just punt. this is <br/> // OK as we are only commited to making a "best effort" here. <br/>}</P> <p> // Private method to infer the caller's class and me Thod names <br/> private void infercaller () {<br/> needtoinfercaller = false; <br/> // get the stack trace. <br/> stacktraceelement stack [] = (New throwable ()). getstacktrace (); <br/> // first, search back to a method in the logger class. <br/> int IX = 0; <br/> while (IX <stack. length) {<br/> stacktraceelement frame = stack [ix]; <br/> string cname = frame. getclassname (); <br/> If (cname. equals ("Java. util. Logging. logger ") {<br/> break; <br/>}< br/> IX ++; <br/>}< br/> // now search for the first frame before the "logger" class. <br/> while (IX <stack. length) {<br/> stacktraceelement frame = stack [ix]; <br/> string cname = frame. getclassname (); <br/> If (! Cname. equals ("Java. util. logging. logger ") {<br/> // we 've found the relevant frame. <br/> setsourceclassname (cname); <br/> setsourcemethodname (frame. getmethodname (); <br/> return; <br/>}< br/> IX ++; <br/>}< br/> // We haven'tfound a suitable frame, so just punt. this is <br/> // OK as we are only commited to making a "best effort" here. <br/>}< br/>
Log4j is similar.
Org. Apache. log4j. SPI. locationinfo class.
Use the throwable. printstacktrace () method to print the exception information to a string.
Then analyze the string by line. Extract call classes and methods. See the constructor of the locationinfo class.
Java code
/** <Br/> instantiate location information based on a throwable. we <br/> CT the throwable <code> T </code>, to be in the format </P> <p> <PRE> <br/> JAVA. lang. throwable <br/>... <br/> at Org. apache. log4j. patternlayout. format (patternlayout. java: 413) <br/> at Org. apache. log4j. fileappender. doappend (fileappender. java: 183) <br/> at Org. apache. log4j. category. callappenders (category. java: 131) <br/> at Org. apache. log4j. category. log (category. java: 512) <br/> at callers. fully. qualified. classname. methodname (filename. java: 74) <br/>... <br/> </PRE> </P> <p> however, we can also deal with JIT compilers that "lose" The <br/> location information, especially between the parentheses. </P> <p> */<br/> Public locationinfo (throwable T, string fqnofcallingclass) </P> <p>/** <br/> instantiate location information based on a throwable. we <br/> CT the throwable <code> T </code>, to be in the format </P> <p> <PRE> <br/> JAVA. lang. throwable <br/>... <br/> at Org. apache. log4j. patternlayout. format (patternlayout. java: 413) <br/> at Org. apache. log4j. fileappender. doappend (fileappender. java: 183) <br/> at Org. apache. log4j. category. callappenders (category. java: 131) <br/> at Org. apache. log4j. category. log (category. java: 512) <br/> at callers. fully. qualified. classname. methodname (filename. java: 74) <br/>... <br/> </PRE> </P> <p> however, we can also deal with JIT compilers that "lose" The <br/> location information, especially between the parentheses. </P> <p> */<br/> Public locationinfo (throwable T, string fqnofcallingclass) <br/>
E. printstacktrace () expands and prints out the entire runtime stack structure when exception occurs.
Log4j analyzes the print result and obtains all the call levels.
Obtain the method of calling class name directly.
Let's take a look at the description of sun. Reflect. Reflection's getcallerclass () method.
Java code
/** Returns the class of the method <code> realframestoskip </code> <br/> frames up the stack (zero-based ), ignoring frames associated <br/> with Java. lang. reflect. method. invoke () and its implementation. <br/> the first frame is that associated with this method, so <br/> <code> getcallerclass (0) </code> returns the Class Object for <br/> sun. reflect. reflection. frames associated with <br/> JAVA. lang. reflect. method. invoke () and its implementation are <br/> completely ignored and do not count toward the number of "real" <br/> frames skipped. */<br/> Public static native class getcallerclass (INT realframestoskip ); </P> <p>/** returns the class of the method <code> realframestoskip </code> <br/> frames up the stack (zero-based ), ignoring frames associated <br/> with Java. lang. reflect. method. invoke () and its implementation. <br/> the first frame is that associated with this method, so <br/> <code> getcallerclass (0) </code> returns the Class Object for <br/> sun. reflect. reflection. frames associated with <br/> JAVA. lang. reflect. method. invoke () and its implementation are <br/> completely ignored and do not count toward the number of "real" <br/> frames skipped. */<br/> Public static native class getcallerclass (INT realframestoskip); <br/>
This is a native method. The principle is to obtain information about the corresponding class based on stackframe (running stack. This method directly returns a class name, which is effective directly. The realframestoskip parameter is used to select the stack level you need. Therefore, you can use this method to obtain the call class name at any level.
Throwable. getstacktrace () is also a native method. The principle is to obtain information about the corresponding class based on stackframe (running stack. Returns a stacktraceelement [].
The stacktraceelement class is included in the Java. lang Package of jdk1.4. It contains rich information and is suitable for debugging.
The stacktraceelement class has the following methods:
Getfilename (), getlinenumber (), getclassname (), getmethodname ().