author | psandoz |
Fri, 20 Dec 2013 13:38:13 +0100 | |
changeset 22078 | bdec5d53e98c |
parent 18565 | 5025d43d3731 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
18565 | 2 |
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package java.util.logging; |
|
27 |
import java.util.*; |
|
2632
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
28 |
import java.util.concurrent.atomic.AtomicInteger; |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
29 |
import java.util.concurrent.atomic.AtomicLong; |
2 | 30 |
import java.io.*; |
31 |
||
2947
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
32 |
import sun.misc.JavaLangAccess; |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
33 |
import sun.misc.SharedSecrets; |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
34 |
|
2 | 35 |
/** |
36 |
* LogRecord objects are used to pass logging requests between |
|
37 |
* the logging framework and individual log Handlers. |
|
38 |
* <p> |
|
39 |
* When a LogRecord is passed into the logging framework it |
|
40 |
* logically belongs to the framework and should no longer be |
|
41 |
* used or updated by the client application. |
|
42 |
* <p> |
|
43 |
* Note that if the client application has not specified an |
|
44 |
* explicit source method name and source class name, then the |
|
45 |
* LogRecord class will infer them automatically when they are |
|
46 |
* first accessed (due to a call on getSourceMethodName or |
|
47 |
* getSourceClassName) by analyzing the call stack. Therefore, |
|
48 |
* if a logging Handler wants to pass off a LogRecord to another |
|
49 |
* thread, or to transmit it over RMI, and if it wishes to subsequently |
|
50 |
* obtain method name or class name information it should call |
|
51 |
* one of getSourceClassName or getSourceMethodName to force |
|
52 |
* the values to be filled in. |
|
53 |
* <p> |
|
54 |
* <b> Serialization notes:</b> |
|
55 |
* <ul> |
|
56 |
* <li>The LogRecord class is serializable. |
|
57 |
* |
|
58 |
* <li> Because objects in the parameters array may not be serializable, |
|
59 |
* during serialization all objects in the parameters array are |
|
60 |
* written as the corresponding Strings (using Object.toString). |
|
61 |
* |
|
62 |
* <li> The ResourceBundle is not transmitted as part of the serialized |
|
63 |
* form, but the resource bundle name is, and the recipient object's |
|
64 |
* readObject method will attempt to locate a suitable resource bundle. |
|
65 |
* |
|
66 |
* </ul> |
|
67 |
* |
|
68 |
* @since 1.4 |
|
69 |
*/ |
|
70 |
||
71 |
public class LogRecord implements java.io.Serializable { |
|
2632
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
72 |
private static final AtomicLong globalSequenceNumber |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
73 |
= new AtomicLong(0); |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
74 |
|
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
75 |
/** |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
76 |
* The default value of threadID will be the current thread's |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
77 |
* thread id, for ease of correlation, unless it is greater than |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
78 |
* MIN_SEQUENTIAL_THREAD_ID, in which case we try harder to keep |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
79 |
* our promise to keep threadIDs unique by avoiding collisions due |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
80 |
* to 32-bit wraparound. Unfortunately, LogRecord.getThreadID() |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
81 |
* returns int, while Thread.getId() returns long. |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
82 |
*/ |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
83 |
private static final int MIN_SEQUENTIAL_THREAD_ID = Integer.MAX_VALUE / 2; |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
84 |
|
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
85 |
private static final AtomicInteger nextThreadId |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
86 |
= new AtomicInteger(MIN_SEQUENTIAL_THREAD_ID); |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
87 |
|
7803
56bc97d69d93
6880112: Project Coin: Port JDK core library code to use diamond operator
smarks
parents:
7026
diff
changeset
|
88 |
private static final ThreadLocal<Integer> threadIds = new ThreadLocal<>(); |
2 | 89 |
|
90 |
/** |
|
91 |
* @serial Logging message level |
|
92 |
*/ |
|
93 |
private Level level; |
|
94 |
||
95 |
/** |
|
96 |
* @serial Sequence number |
|
97 |
*/ |
|
98 |
private long sequenceNumber; |
|
99 |
||
100 |
/** |
|
101 |
* @serial Class that issued logging call |
|
102 |
*/ |
|
103 |
private String sourceClassName; |
|
104 |
||
105 |
/** |
|
106 |
* @serial Method that issued logging call |
|
107 |
*/ |
|
108 |
private String sourceMethodName; |
|
109 |
||
110 |
/** |
|
111 |
* @serial Non-localized raw message text |
|
112 |
*/ |
|
113 |
private String message; |
|
114 |
||
115 |
/** |
|
116 |
* @serial Thread ID for thread that issued logging call. |
|
117 |
*/ |
|
118 |
private int threadID; |
|
119 |
||
120 |
/** |
|
121 |
* @serial Event time in milliseconds since 1970 |
|
122 |
*/ |
|
123 |
private long millis; |
|
124 |
||
125 |
/** |
|
126 |
* @serial The Throwable (if any) associated with log message |
|
127 |
*/ |
|
128 |
private Throwable thrown; |
|
129 |
||
130 |
/** |
|
131 |
* @serial Name of the source Logger. |
|
132 |
*/ |
|
133 |
private String loggerName; |
|
134 |
||
135 |
/** |
|
136 |
* @serial Resource bundle name to localized log message. |
|
137 |
*/ |
|
138 |
private String resourceBundleName; |
|
139 |
||
140 |
private transient boolean needToInferCaller; |
|
141 |
private transient Object parameters[]; |
|
142 |
private transient ResourceBundle resourceBundle; |
|
143 |
||
144 |
/** |
|
2632
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
145 |
* Returns the default value for a new LogRecord's threadID. |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
146 |
*/ |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
147 |
private int defaultThreadID() { |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
148 |
long tid = Thread.currentThread().getId(); |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
149 |
if (tid < MIN_SEQUENTIAL_THREAD_ID) { |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
150 |
return (int) tid; |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
151 |
} else { |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
152 |
Integer id = threadIds.get(); |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
153 |
if (id == null) { |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
154 |
id = nextThreadId.getAndIncrement(); |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
155 |
threadIds.set(id); |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
156 |
} |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
157 |
return id; |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
158 |
} |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
159 |
} |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
160 |
|
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
161 |
/** |
2 | 162 |
* Construct a LogRecord with the given level and message values. |
163 |
* <p> |
|
164 |
* The sequence property will be initialized with a new unique value. |
|
165 |
* These sequence values are allocated in increasing order within a VM. |
|
166 |
* <p> |
|
167 |
* The millis property will be initialized to the current time. |
|
168 |
* <p> |
|
169 |
* The thread ID property will be initialized with a unique ID for |
|
170 |
* the current thread. |
|
171 |
* <p> |
|
172 |
* All other properties will be initialized to "null". |
|
173 |
* |
|
174 |
* @param level a logging level value |
|
175 |
* @param msg the raw non-localized logging message (may be null) |
|
176 |
*/ |
|
177 |
public LogRecord(Level level, String msg) { |
|
178 |
// Make sure level isn't null, by calling random method. |
|
179 |
level.getClass(); |
|
180 |
this.level = level; |
|
181 |
message = msg; |
|
182 |
// Assign a thread ID and a unique sequence number. |
|
2632
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
183 |
sequenceNumber = globalSequenceNumber.getAndIncrement(); |
9779b9cbae42
6278014: java.util.logging.LogRecord.getThreadID() should provide real thread id
martin
parents:
2
diff
changeset
|
184 |
threadID = defaultThreadID(); |
2 | 185 |
millis = System.currentTimeMillis(); |
186 |
needToInferCaller = true; |
|
187 |
} |
|
188 |
||
189 |
/** |
|
3853 | 190 |
* Get the source Logger's name. |
2 | 191 |
* |
192 |
* @return source logger name (may be null) |
|
193 |
*/ |
|
194 |
public String getLoggerName() { |
|
195 |
return loggerName; |
|
196 |
} |
|
197 |
||
198 |
/** |
|
3853 | 199 |
* Set the source Logger's name. |
2 | 200 |
* |
201 |
* @param name the source logger name (may be null) |
|
202 |
*/ |
|
203 |
public void setLoggerName(String name) { |
|
204 |
loggerName = name; |
|
205 |
} |
|
206 |
||
207 |
/** |
|
208 |
* Get the localization resource bundle |
|
209 |
* <p> |
|
210 |
* This is the ResourceBundle that should be used to localize |
|
211 |
* the message string before formatting it. The result may |
|
212 |
* be null if the message is not localizable, or if no suitable |
|
213 |
* ResourceBundle is available. |
|
18565 | 214 |
* @return the localization resource bundle |
2 | 215 |
*/ |
216 |
public ResourceBundle getResourceBundle() { |
|
217 |
return resourceBundle; |
|
218 |
} |
|
219 |
||
220 |
/** |
|
221 |
* Set the localization resource bundle. |
|
222 |
* |
|
223 |
* @param bundle localization bundle (may be null) |
|
224 |
*/ |
|
225 |
public void setResourceBundle(ResourceBundle bundle) { |
|
226 |
resourceBundle = bundle; |
|
227 |
} |
|
228 |
||
229 |
/** |
|
230 |
* Get the localization resource bundle name |
|
231 |
* <p> |
|
232 |
* This is the name for the ResourceBundle that should be |
|
233 |
* used to localize the message string before formatting it. |
|
234 |
* The result may be null if the message is not localizable. |
|
18565 | 235 |
* @return the localization resource bundle name |
2 | 236 |
*/ |
237 |
public String getResourceBundleName() { |
|
238 |
return resourceBundleName; |
|
239 |
} |
|
240 |
||
241 |
/** |
|
242 |
* Set the localization resource bundle name. |
|
243 |
* |
|
244 |
* @param name localization bundle name (may be null) |
|
245 |
*/ |
|
246 |
public void setResourceBundleName(String name) { |
|
247 |
resourceBundleName = name; |
|
248 |
} |
|
249 |
||
250 |
/** |
|
251 |
* Get the logging message level, for example Level.SEVERE. |
|
252 |
* @return the logging message level |
|
253 |
*/ |
|
254 |
public Level getLevel() { |
|
255 |
return level; |
|
256 |
} |
|
257 |
||
258 |
/** |
|
259 |
* Set the logging message level, for example Level.SEVERE. |
|
260 |
* @param level the logging message level |
|
261 |
*/ |
|
262 |
public void setLevel(Level level) { |
|
263 |
if (level == null) { |
|
264 |
throw new NullPointerException(); |
|
265 |
} |
|
266 |
this.level = level; |
|
267 |
} |
|
268 |
||
269 |
/** |
|
270 |
* Get the sequence number. |
|
271 |
* <p> |
|
272 |
* Sequence numbers are normally assigned in the LogRecord |
|
273 |
* constructor, which assigns unique sequence numbers to |
|
274 |
* each new LogRecord in increasing order. |
|
275 |
* @return the sequence number |
|
276 |
*/ |
|
277 |
public long getSequenceNumber() { |
|
278 |
return sequenceNumber; |
|
279 |
} |
|
280 |
||
281 |
/** |
|
282 |
* Set the sequence number. |
|
283 |
* <p> |
|
284 |
* Sequence numbers are normally assigned in the LogRecord constructor, |
|
285 |
* so it should not normally be necessary to use this method. |
|
18565 | 286 |
* @param seq the sequence number |
2 | 287 |
*/ |
288 |
public void setSequenceNumber(long seq) { |
|
289 |
sequenceNumber = seq; |
|
290 |
} |
|
291 |
||
292 |
/** |
|
293 |
* Get the name of the class that (allegedly) issued the logging request. |
|
294 |
* <p> |
|
295 |
* Note that this sourceClassName is not verified and may be spoofed. |
|
296 |
* This information may either have been provided as part of the |
|
297 |
* logging call, or it may have been inferred automatically by the |
|
298 |
* logging framework. In the latter case, the information may only |
|
299 |
* be approximate and may in fact describe an earlier call on the |
|
300 |
* stack frame. |
|
301 |
* <p> |
|
302 |
* May be null if no information could be obtained. |
|
303 |
* |
|
304 |
* @return the source class name |
|
305 |
*/ |
|
306 |
public String getSourceClassName() { |
|
307 |
if (needToInferCaller) { |
|
308 |
inferCaller(); |
|
309 |
} |
|
310 |
return sourceClassName; |
|
311 |
} |
|
312 |
||
313 |
/** |
|
314 |
* Set the name of the class that (allegedly) issued the logging request. |
|
315 |
* |
|
316 |
* @param sourceClassName the source class name (may be null) |
|
317 |
*/ |
|
318 |
public void setSourceClassName(String sourceClassName) { |
|
319 |
this.sourceClassName = sourceClassName; |
|
320 |
needToInferCaller = false; |
|
321 |
} |
|
322 |
||
323 |
/** |
|
324 |
* Get the name of the method that (allegedly) issued the logging request. |
|
325 |
* <p> |
|
326 |
* Note that this sourceMethodName is not verified and may be spoofed. |
|
327 |
* This information may either have been provided as part of the |
|
328 |
* logging call, or it may have been inferred automatically by the |
|
329 |
* logging framework. In the latter case, the information may only |
|
330 |
* be approximate and may in fact describe an earlier call on the |
|
331 |
* stack frame. |
|
332 |
* <p> |
|
333 |
* May be null if no information could be obtained. |
|
334 |
* |
|
335 |
* @return the source method name |
|
336 |
*/ |
|
337 |
public String getSourceMethodName() { |
|
338 |
if (needToInferCaller) { |
|
339 |
inferCaller(); |
|
340 |
} |
|
341 |
return sourceMethodName; |
|
342 |
} |
|
343 |
||
344 |
/** |
|
345 |
* Set the name of the method that (allegedly) issued the logging request. |
|
346 |
* |
|
347 |
* @param sourceMethodName the source method name (may be null) |
|
348 |
*/ |
|
349 |
public void setSourceMethodName(String sourceMethodName) { |
|
350 |
this.sourceMethodName = sourceMethodName; |
|
351 |
needToInferCaller = false; |
|
352 |
} |
|
353 |
||
354 |
/** |
|
355 |
* Get the "raw" log message, before localization or formatting. |
|
356 |
* <p> |
|
357 |
* May be null, which is equivalent to the empty string "". |
|
358 |
* <p> |
|
359 |
* This message may be either the final text or a localization key. |
|
360 |
* <p> |
|
361 |
* During formatting, if the source logger has a localization |
|
362 |
* ResourceBundle and if that ResourceBundle has an entry for |
|
363 |
* this message string, then the message string is replaced |
|
364 |
* with the localized value. |
|
365 |
* |
|
366 |
* @return the raw message string |
|
367 |
*/ |
|
368 |
public String getMessage() { |
|
369 |
return message; |
|
370 |
} |
|
371 |
||
372 |
/** |
|
373 |
* Set the "raw" log message, before localization or formatting. |
|
374 |
* |
|
375 |
* @param message the raw message string (may be null) |
|
376 |
*/ |
|
377 |
public void setMessage(String message) { |
|
378 |
this.message = message; |
|
379 |
} |
|
380 |
||
381 |
/** |
|
382 |
* Get the parameters to the log message. |
|
383 |
* |
|
384 |
* @return the log message parameters. May be null if |
|
385 |
* there are no parameters. |
|
386 |
*/ |
|
387 |
public Object[] getParameters() { |
|
388 |
return parameters; |
|
389 |
} |
|
390 |
||
391 |
/** |
|
392 |
* Set the parameters to the log message. |
|
393 |
* |
|
394 |
* @param parameters the log message parameters. (may be null) |
|
395 |
*/ |
|
396 |
public void setParameters(Object parameters[]) { |
|
397 |
this.parameters = parameters; |
|
398 |
} |
|
399 |
||
400 |
/** |
|
401 |
* Get an identifier for the thread where the message originated. |
|
402 |
* <p> |
|
403 |
* This is a thread identifier within the Java VM and may or |
|
404 |
* may not map to any operating system ID. |
|
405 |
* |
|
406 |
* @return thread ID |
|
407 |
*/ |
|
408 |
public int getThreadID() { |
|
409 |
return threadID; |
|
410 |
} |
|
411 |
||
412 |
/** |
|
413 |
* Set an identifier for the thread where the message originated. |
|
414 |
* @param threadID the thread ID |
|
415 |
*/ |
|
416 |
public void setThreadID(int threadID) { |
|
417 |
this.threadID = threadID; |
|
418 |
} |
|
419 |
||
420 |
/** |
|
421 |
* Get event time in milliseconds since 1970. |
|
422 |
* |
|
423 |
* @return event time in millis since 1970 |
|
424 |
*/ |
|
425 |
public long getMillis() { |
|
426 |
return millis; |
|
427 |
} |
|
428 |
||
429 |
/** |
|
430 |
* Set event time. |
|
431 |
* |
|
432 |
* @param millis event time in millis since 1970 |
|
433 |
*/ |
|
434 |
public void setMillis(long millis) { |
|
435 |
this.millis = millis; |
|
436 |
} |
|
437 |
||
438 |
/** |
|
439 |
* Get any throwable associated with the log record. |
|
440 |
* <p> |
|
441 |
* If the event involved an exception, this will be the |
|
442 |
* exception object. Otherwise null. |
|
443 |
* |
|
444 |
* @return a throwable |
|
445 |
*/ |
|
446 |
public Throwable getThrown() { |
|
447 |
return thrown; |
|
448 |
} |
|
449 |
||
450 |
/** |
|
451 |
* Set a throwable associated with the log event. |
|
452 |
* |
|
453 |
* @param thrown a throwable (may be null) |
|
454 |
*/ |
|
455 |
public void setThrown(Throwable thrown) { |
|
456 |
this.thrown = thrown; |
|
457 |
} |
|
458 |
||
459 |
private static final long serialVersionUID = 5372048053134512534L; |
|
460 |
||
461 |
/** |
|
462 |
* @serialData Default fields, followed by a two byte version number |
|
463 |
* (major byte, followed by minor byte), followed by information on |
|
464 |
* the log record parameter array. If there is no parameter array, |
|
465 |
* then -1 is written. If there is a parameter array (possible of zero |
|
466 |
* length) then the array length is written as an integer, followed |
|
467 |
* by String values for each parameter. If a parameter is null, then |
|
468 |
* a null String is written. Otherwise the output of Object.toString() |
|
469 |
* is written. |
|
470 |
*/ |
|
471 |
private void writeObject(ObjectOutputStream out) throws IOException { |
|
472 |
// We have to call defaultWriteObject first. |
|
473 |
out.defaultWriteObject(); |
|
474 |
||
475 |
// Write our version number. |
|
476 |
out.writeByte(1); |
|
477 |
out.writeByte(0); |
|
478 |
if (parameters == null) { |
|
479 |
out.writeInt(-1); |
|
480 |
return; |
|
481 |
} |
|
482 |
out.writeInt(parameters.length); |
|
483 |
// Write string values for the parameters. |
|
22078
bdec5d53e98c
8030851: Update code in java.util to use newer language features
psandoz
parents:
18565
diff
changeset
|
484 |
for (Object parameter : parameters) { |
bdec5d53e98c
8030851: Update code in java.util to use newer language features
psandoz
parents:
18565
diff
changeset
|
485 |
out.writeObject(Objects.toString(parameter, null)); |
2 | 486 |
} |
487 |
} |
|
488 |
||
489 |
private void readObject(ObjectInputStream in) |
|
490 |
throws IOException, ClassNotFoundException { |
|
491 |
// We have to call defaultReadObject first. |
|
492 |
in.defaultReadObject(); |
|
493 |
||
494 |
// Read version number. |
|
495 |
byte major = in.readByte(); |
|
496 |
byte minor = in.readByte(); |
|
497 |
if (major != 1) { |
|
498 |
throw new IOException("LogRecord: bad version: " + major + "." + minor); |
|
499 |
} |
|
500 |
int len = in.readInt(); |
|
501 |
if (len == -1) { |
|
502 |
parameters = null; |
|
503 |
} else { |
|
504 |
parameters = new Object[len]; |
|
505 |
for (int i = 0; i < parameters.length; i++) { |
|
506 |
parameters[i] = in.readObject(); |
|
507 |
} |
|
508 |
} |
|
509 |
// If necessary, try to regenerate the resource bundle. |
|
510 |
if (resourceBundleName != null) { |
|
511 |
try { |
|
512 |
resourceBundle = ResourceBundle.getBundle(resourceBundleName); |
|
513 |
} catch (MissingResourceException ex) { |
|
514 |
// This is not a good place to throw an exception, |
|
515 |
// so we simply leave the resourceBundle null. |
|
516 |
resourceBundle = null; |
|
517 |
} |
|
518 |
} |
|
519 |
||
520 |
needToInferCaller = false; |
|
521 |
} |
|
522 |
||
523 |
// Private method to infer the caller's class and method names |
|
524 |
private void inferCaller() { |
|
525 |
needToInferCaller = false; |
|
2947
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
526 |
JavaLangAccess access = SharedSecrets.getJavaLangAccess(); |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
527 |
Throwable throwable = new Throwable(); |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
528 |
int depth = access.getStackTraceDepth(throwable); |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
529 |
|
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
530 |
boolean lookingForLogger = true; |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
531 |
for (int ix = 0; ix < depth; ix++) { |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
532 |
// Calling getStackTraceElement directly prevents the VM |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
533 |
// from paying the cost of building the entire stack frame. |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
534 |
StackTraceElement frame = |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
535 |
access.getStackTraceElement(throwable, ix); |
2 | 536 |
String cname = frame.getClassName(); |
7026
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
537 |
boolean isLoggerImpl = isLoggerImplFrame(cname); |
2947
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
538 |
if (lookingForLogger) { |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
539 |
// Skip all frames until we have found the first logger frame. |
7026
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
540 |
if (isLoggerImpl) { |
2947
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
541 |
lookingForLogger = false; |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
542 |
} |
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
543 |
} else { |
7026
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
544 |
if (!isLoggerImpl) { |
3861
a98a057ec335
6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents:
3853
diff
changeset
|
545 |
// skip reflection call |
a98a057ec335
6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents:
3853
diff
changeset
|
546 |
if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) { |
a98a057ec335
6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents:
3853
diff
changeset
|
547 |
// We've found the relevant frame. |
a98a057ec335
6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents:
3853
diff
changeset
|
548 |
setSourceClassName(cname); |
a98a057ec335
6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents:
3853
diff
changeset
|
549 |
setSourceMethodName(frame.getMethodName()); |
a98a057ec335
6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents:
3853
diff
changeset
|
550 |
return; |
a98a057ec335
6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents:
3853
diff
changeset
|
551 |
} |
2947
b0135c99348e
6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
martin
parents:
2632
diff
changeset
|
552 |
} |
2 | 553 |
} |
554 |
} |
|
555 |
// We haven't found a suitable frame, so just punt. This is |
|
556 |
// OK as we are only committed to making a "best effort" here. |
|
557 |
} |
|
7026
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
558 |
|
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
559 |
private boolean isLoggerImplFrame(String cname) { |
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
560 |
// the log record could be created for a platform logger |
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
561 |
return (cname.equals("java.util.logging.Logger") || |
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
562 |
cname.startsWith("java.util.logging.LoggingProxyImpl") || |
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
563 |
cname.startsWith("sun.util.logging.")); |
9f2ec5fad124
6985460: PlatformLogger throws ArrayStoreException when j.u.logging is initialized
mchung
parents:
5506
diff
changeset
|
564 |
} |
2 | 565 |
} |