Keywords: Enterprise application
Just see the discussion about log. Think of a problem that was previously investigated. Sorted out, hope to be helpful to everyone.
Sun JDK source code Download http://wwws.sun.com/software/communitysource/
Register and log in to the "Sun Community Source Licensing" and download J2SE (several 10 megabytes) or Java EE (hundreds of trillion).
Log can print the code run time, class name, method name, and information.
An intuitive example, each time you start Tomcat (the default configuration). You can usually see
June 9, 11:22:29 AM org.apache.struts.util.PropertyMessageResources <init>
info:initializing, config= ' org.apache.webapp.admin.ApplicationResources ', returnnull=true
June 9, 11:22:41 AM org.apache.coyote.http11.Http11Protocol start
Info:starting Coyote http/1.1 on port 8080
Time, class name, method name, information are printed out.
So how does log get this class and the method name that calls itself.
The code given below is the source code for the JDK1.4, and the source code of the log4j. Explain its realization principle.
Getting the calling class, and the method name, is the need to get the structure of the current running stack.
The new Throwable (). Getstacktrace () returns the hierarchy of the current run stack.
Using this principle, we can get the call relationship of the whole stack.
The JDK1.4 java.util.logging package is implemented by the Throwable.getstacktrace () method.
Get the stack trace.
Stacktraceelement stack[] = (new Throwable ()). Getstacktrace ();
The complete code in the JDK1.4 source, Java.util.logging.LogRecord class Infercaller method.
Code
1.//Private method to infer the caller's class and method names
2. private void Infercaller () {
3. Needtoinfercaller = false;
4.//Get the stack trace.
5. Stacktraceelement stack[] = (new Throwable ()). Getstacktrace ();
6.//In the Logger class.
7. int IX = 0;
8. While (ix < stack.length) {
9. Stacktraceelement frame = Stack[ix];
String cname = Frame.getclassname ();
One. if (Cname.equals ("Java.util.logging.Logger")) {
break;
13.}
ix++;
15.}
//Now search for the "before" "Logger" class.
while (ix < stack.length) {
Stacktraceelement frame = Stack[ix];
String cname = Frame.getclassname ();
if (!cname.equals ("Java.util.logging.Logger")) {
//We ' ve found the relevant frame.
Setsourceclassname (CNAME);
Setsourcemethodname (Frame.getmethodname ());
return;
25.}
ix++;
27.}
//We haven ' t found a suitable frame, so just punt. This is
I//OK as we are only commited to making a "best effort" here.
30.}
Log4j has a similar beauty.
Org.apache.log4j.spi.LocationInfo class.
First, use the Throwable.printstacktrace () method to print the exception information into a string.
Then parse the string by line. Extracts the calling class and method. See the constructor for the Locationinfo class.
Code
1./**
2. Instantiate location information based on a throwable. We
3. Expect the throwable <code>t</code>
4.
5. <pre>
6. java.lang.Throwable
7...
8. At Org.apache.log4j.PatternLayout.format (patternlayout.java:413)
9. At Org.apache.log4j.FileAppender.doAppend (fileappender.java:183)
At Org.apache.log4j.Category.callAppenders (category.java:131)
At Org.apache.log4j.Category.log (category.java:512)
At Callers.fully.qualified.className.methodName (filename.java:74)
13...
</pre>
15.
<p>however, we can also deal with JIT compilers "lose" the
Location information, especially between the parentheses.
18.
19. */
Public Locationinfo (Throwable T, String Fqnofcallingclass)
E.printstacktrace () to the exception occurred at the time of the entire run stack structure to expand, print out.
LOG4J is to analyze this print result and get all the call levels.
About the method of getting the calling class name directly.
Let's look at the description of Sun.reflect.Reflection's Getcallerclass () method.
Code
1./** Returns The class of the method <code>realFramesToSkip</code>
2. Frames up the stack (zero-based), ignoring frames associated
3. With Java.lang.reflect.Method.invoke () and its implementation.
4. The ' the ' associated with this method
5. <code>getcallerclass (0) </code> returns the Class object for
6. Sun.reflect.Reflection. Frames associated with
7. Java.lang.reflect.Method.invoke () and its implementation are
8. Completely ignored and do not count toward the number of ' real '
9. Frames skipped. */
public static native Class getcallerclass (int realframestoskip);
This is a native method. The principle is also based on StackFrame (run stack) to get the corresponding class information.
This method directly returns a class name, which is directly valid. Parameter Realframestoskip used to
Select the stack hierarchy you need, so you can use this method to get the calling class name at any level.
Throwable.getstacktrace () is also a native method. The principle is also based on StackFrame
(run stack) to get information about the corresponding class. Returns a stacktraceelement[].
The Stacktraceelement class is inside the JDK1.4 's Java.lang bag. It contains a wealth of information and is ideal for debug.
The Stacktraceelement class has the following methods:
GetFileName (), Getlinenumber (), GetClassName (), Getmethodname ().
18:36 | Permanent link | browse (3445) | Comments (3) | my Blog | Enter Forum |
Permanent link
http://buaawhl.javaeye.com/blog/6450
Total 3 Reviews
Agilejava 2004-07-27 10:05
Very good:)
Lllyq 2004-07-27 10:51
When I used to do unit test, I also wrote a similar, mostly Gettruemethod () method,
Which also includes the jdk1.3 method
can be used directly. Methodtrace methodtrace = new Methodtrace () as soon as the class is initialized;
, and then Methodtrace.gettruemethod () in the method
Code
1./*
2. * Created on FEB 2003 12:00:04 PM
3. *
4. */
5. Package com.bba96.util;
6.
7. Import Java.io.PrintWriter;
8. Import Java.io.StringWriter;
9.
10./**
@author Leon.
12. */
public class Methodtrace {
/For JDK 1.4
Private Stacktraceelement elements[];
16.
StringWriter SW = new StringWriter ();
PrintWriter out = new PrintWriter (SW);
Private String truemethodname = null;
Private String methodname = null;
Private String methodnameextest = null;
Private String e = null;
private int a[] = new INT[2];
private int B;
Private String cutstr = "Test";
private int cutlength = Cutstr.length ();
Private char[] line = null;
Private StringBuffer buf = new StringBuffer ();
Public Methodtrace () {
30.}
private string Cutteststr (String str) {
if (str = null) {
return null;
34.}
String strlowercase = Str.tolowercase ();
int i = Strlowercase.indexof (CUTSTR);
Panax Notoginseng. Int J;
if (I!=-1) {
line = Str.tochararray ();
Buf.setlength (Str.length ());
Buf.append (line, 0, I);
i + = cutlength;
J. J = i;
i = Strlowercase.indexof (cutstr, i);
while (I!=-1) {
Buf.append (Line, J, I-j);
i + + cutlength;
K. j = i;
i = Strlowercase.indexof (cutstr, i);
50.}
Buf.append (Line, J, Line.length-j);
str = buf.tostring ();
Buf.setlength (0);
54.}
return str;
56.}
Public String Gettruemethod () {
Truemethodname = null;
try {
b = a[4];
Aioobe catch (arrayindexoutofboundsexception) {
/JDK 1.3
63./*
Aioobe.printstacktrace (out);
Out.flush ();
E = sw.tostring ();
A. try {
Out.close ();
Sw.close ();
The catch (IOException e) {
Should not happen as it's stringwriter.
72.}
The. Out = null;
A. SW = null;
Boolean logerror = false;
A. int pos = E.indexof ("at");
for (int i = 0; i < 3; i++) {
(pos = 1) {
Logerror = true;
The break;
81.}
E = e.substring (pos + 3, E.length ());
pos = E.indexof ("at");
84.}
if (logerror) {
Truemethodname = "Unknownclass.unknownmethod ()";
.} else {
Truemethodname = e.substring (0, E.indexof ('));
89.}
90. */
91.
MB//For JDK 1.4
93.
elements = Aioobe.getstacktrace ();
if (Elements.length < 3) {
Return "Unknownclass.unknownmethod ()";
97.}
Truemethodname = Elements[2].getclassname () + "." + Elements[2].getmethodname ();
99.
100.}
Truemethodname return;
102.}
GetMethod public String () {
Return methodname;
105.}
A. Public String getmethodextest () {
Methodnameextest = Cutteststr (Gettruemethod ());
108. int index = Methodnameextest.lastindexof ('. ');
109. Methodnameextest =
Methodnameextest.substring (0, index + 1)
+ methodnameextest.substring (index + 1, index + 2). toLowerCase ()
112. + methodnameextest.substring (index + 2, methodnameextest.length ());
113. return methodnameextest;
114.}
115.}
BUAAWHL 2004-07-27 11:48
Lllyq wrote
When I used to do unit test, I also wrote a similar, mostly Gettruemethod () method, which included the jdk1.3 method.
can be used directly. Methodtrace methodtrace = new Methodtrace () as long as the class is initialized;
Then Methodtrace.gettruemethod () in the method
Very good code.
For the jdk1.3 part, and log4j the same idea. In this respect, you have a ratio with master log4j.
The for jdk1.4 part is also the same as the JDK 1.4 log implementation method.
I had no idea how log4j was achieved. Only read the source code to understand.
JDK1.4 later joined the stacktraceelement to support log.
JDK1.3, it is true that you can only use the parse Throwable StackTrace string method.