33
33
import java .io .UnsupportedEncodingException ;
34
34
import java .security .AccessController ;
35
35
import java .security .PrivilegedAction ;
36
+ import org .jspecify .annotations .NullMarked ;
37
+ import org .jspecify .annotations .Nullable ;
36
38
37
39
/**
38
40
* A {@code Handler} object takes log messages from a {@code Logger} and
53
55
*/
54
56
55
57
@ AnnotatedFor ({"interning" })
58
+ @ NullMarked
56
59
public abstract @ UsesObjectEquals class Handler {
57
60
private static final int offValue = Level .OFF .intValue ();
58
61
private final LogManager manager = LogManager .getLogManager ();
@@ -137,7 +140,7 @@ public Void run() {
137
140
* @param record description of the log event. A null record is
138
141
* silently ignored and is not published
139
142
*/
140
- public abstract void publish (LogRecord record );
143
+ public abstract void publish (@ Nullable LogRecord record );
141
144
142
145
/**
143
146
* Flush any buffered output.
@@ -177,7 +180,7 @@ public synchronized void setFormatter(Formatter newFormatter) throws SecurityExc
177
180
* Return the {@code Formatter} for this {@code Handler}.
178
181
* @return the {@code Formatter} (may be null).
179
182
*/
180
- public Formatter getFormatter () {
183
+ public @ Nullable Formatter getFormatter () {
181
184
return formatter ;
182
185
}
183
186
@@ -194,7 +197,7 @@ public Formatter getFormatter() {
194
197
* @exception UnsupportedEncodingException if the named encoding is
195
198
* not supported.
196
199
*/
197
- public synchronized void setEncoding (String encoding )
200
+ public synchronized void setEncoding (@ Nullable String encoding )
198
201
throws SecurityException , java .io .UnsupportedEncodingException {
199
202
checkPermission ();
200
203
if (encoding != null ) {
@@ -215,7 +218,7 @@ public synchronized void setEncoding(String encoding)
215
218
* @return The encoding name. May be null, which indicates the
216
219
* default encoding should be used.
217
220
*/
218
- public String getEncoding () {
221
+ public @ Nullable String getEncoding () {
219
222
return encoding ;
220
223
}
221
224
@@ -230,7 +233,7 @@ public String getEncoding() {
230
233
* @exception SecurityException if a security manager exists and if
231
234
* the caller does not have {@code LoggingPermission("control")}.
232
235
*/
233
- public synchronized void setFilter (Filter newFilter ) throws SecurityException {
236
+ public synchronized void setFilter (@ Nullable Filter newFilter ) throws SecurityException {
234
237
checkPermission ();
235
238
filter = newFilter ;
236
239
}
@@ -240,7 +243,7 @@ public synchronized void setFilter(Filter newFilter) throws SecurityException {
240
243
*
241
244
* @return a {@code Filter} object (may be null)
242
245
*/
243
- public Filter getFilter () {
246
+ public @ Nullable Filter getFilter () {
244
247
return filter ;
245
248
}
246
249
@@ -284,7 +287,7 @@ public ErrorManager getErrorManager() {
284
287
* @param ex an exception (may be null)
285
288
* @param code an error code defined in ErrorManager
286
289
*/
287
- protected void reportError (String msg , Exception ex , int code ) {
290
+ protected void reportError (@ Nullable String msg , @ Nullable Exception ex , int code ) {
288
291
try {
289
292
errorManager .error (msg , ex , code );
290
293
} catch (Exception ex2 ) {
@@ -337,7 +340,8 @@ public Level getLevel() {
337
340
* @return true if the {@code LogRecord} would be logged.
338
341
*
339
342
*/
340
- public boolean isLoggable (LogRecord record ) {
343
+ // JDK11 has a bug which makes null records cause NPE, despite the spec. Later versions fix it.
344
+ public boolean isLoggable (@ Nullable LogRecord record ) {
341
345
final int levelValue = getLevel ().intValue ();
342
346
if (record .getLevel ().intValue () < levelValue || levelValue == offValue ) {
343
347
return false ;
0 commit comments