@@ -47,6 +47,7 @@ public final class Signatures implements Constants {
47
47
private static final String BUNDLED_PREFIX = "@includeBundled " ;
48
48
private static final String DEFAULT_MESSAGE_PREFIX = "@defaultMessage " ;
49
49
private static final String IGNORE_UNRESOLVABLE_LINE = "@ignoreUnresolvable" ;
50
+ private static final String IGNORE_MISSING_CLASSES_LINE = "@ignoreMissingClasses" ;
50
51
51
52
private static enum UnresolvableReporting {
52
53
FAIL (true ) {
@@ -78,7 +79,7 @@ private UnresolvableReporting(boolean reportClassNotFound) {
78
79
79
80
private final RelatedClassLookup lookup ;
80
81
private final Logger logger ;
81
- private final boolean failOnUnresolvableSignatures ;
82
+ private final boolean failOnUnresolvableSignatures , ignoreSignaturesOfMissingClasses ;
82
83
83
84
/** Key is used to lookup forbidden signature in following formats. Keys are generated by the corresponding
84
85
* {@link #getKey(String)} (classes), {@link #getKey(String, Method)} (methods),
@@ -91,14 +92,18 @@ private UnresolvableReporting(boolean reportClassNotFound) {
91
92
92
93
/** if enabled, the bundled signature to enable heuristics for detection of non-portable runtime calls is used */
93
94
private boolean forbidNonPortableRuntime = false ;
95
+
96
+ /** number of files that were interpreted as signatures file. If 0, no (bundled) signatures files were added at all */
97
+ private int numberOfFiles = 0 ;
94
98
95
99
public Signatures (Checker checker ) {
96
- this (checker , checker .logger , checker .options .contains (Option .FAIL_ON_UNRESOLVABLE_SIGNATURES ));
100
+ this (checker , checker .logger , checker .options .contains (Option .IGNORE_SIGNATURES_OF_MISSING_CLASSES ), checker . options . contains ( Option . FAIL_ON_UNRESOLVABLE_SIGNATURES ));
97
101
}
98
102
99
- public Signatures (RelatedClassLookup lookup , Logger logger , boolean failOnUnresolvableSignatures ) {
103
+ public Signatures (RelatedClassLookup lookup , Logger logger , boolean ignoreSignaturesOfMissingClasses , boolean failOnUnresolvableSignatures ) {
100
104
this .lookup = lookup ;
101
105
this .logger = logger ;
106
+ this .ignoreSignaturesOfMissingClasses = ignoreSignaturesOfMissingClasses ;
102
107
this .failOnUnresolvableSignatures = failOnUnresolvableSignatures ;
103
108
}
104
109
@@ -115,7 +120,8 @@ static String getKey(String internalClassName, Method method) {
115
120
}
116
121
117
122
/** Adds the method signature to the list of disallowed methods. The Signature is checked against the given ClassLoader. */
118
- private void addSignature (final String line , final String defaultMessage , final UnresolvableReporting report , final Set <String > missingClasses ) throws ParseException ,IOException {
123
+ private void addSignature (final String line , final String defaultMessage , final UnresolvableReporting report ,
124
+ final boolean localIgnoreMissingClasses , final Set <String > missingClasses ) throws ParseException ,IOException {
119
125
final String clazz , field , signature ;
120
126
String message = null ;
121
127
final Method method ;
@@ -171,6 +177,9 @@ private void addSignature(final String line, final String defaultMessage, final
171
177
try {
172
178
c = lookup .getClassFromClassLoader (clazz );
173
179
} catch (ClassNotFoundException cnfe ) {
180
+ if (this .ignoreSignaturesOfMissingClasses || localIgnoreMissingClasses ) {
181
+ return ;
182
+ }
174
183
if (report .reportClassNotFound ) {
175
184
report .parseFailed (logger , String .format (Locale .ENGLISH , "Class '%s' not found on classpath" , cnfe .getMessage ()), signature );
176
185
} else {
@@ -235,6 +244,7 @@ private void addBundledSignatures(String name, String jdkTargetVersion, boolean
235
244
}
236
245
if (BS_JDK_NONPORTABLE .equals (name )) {
237
246
if (logging ) logger .info ("Reading bundled API signatures: " + name );
247
+ numberOfFiles ++;
238
248
forbidNonPortableRuntime = true ;
239
249
return ;
240
250
}
@@ -254,14 +264,16 @@ private void addBundledSignatures(String name, String jdkTargetVersion, boolean
254
264
parseSignaturesStream (in , true , missingClasses );
255
265
}
256
266
257
- private void parseSignaturesStream (InputStream in , boolean allowBundled , Set <String > missingClasses ) throws IOException ,ParseException {
258
- parseSignaturesFile (new InputStreamReader (in , StandardCharsets .UTF_8 ), allowBundled , missingClasses );
267
+ private void parseSignaturesStream (InputStream in , boolean isBundled , Set <String > missingClasses ) throws IOException ,ParseException {
268
+ parseSignaturesFile (new InputStreamReader (in , StandardCharsets .UTF_8 ), isBundled , missingClasses );
259
269
}
260
270
261
271
private void parseSignaturesFile (Reader reader , boolean isBundled , Set <String > missingClasses ) throws IOException ,ParseException {
272
+ numberOfFiles ++;
262
273
try (final BufferedReader r = new BufferedReader (reader )) {
263
274
String line , defaultMessage = null ;
264
275
UnresolvableReporting reporter = failOnUnresolvableSignatures ? UnresolvableReporting .FAIL : UnresolvableReporting .WARNING ;
276
+ boolean localIgnoreMissingClasses = false ;
265
277
while ((line = r .readLine ()) != null ) {
266
278
line = line .trim ();
267
279
if (line .length () == 0 || line .startsWith ("#" ))
@@ -274,12 +286,20 @@ private void parseSignaturesFile(Reader reader, boolean isBundled, Set<String> m
274
286
defaultMessage = line .substring (DEFAULT_MESSAGE_PREFIX .length ()).trim ();
275
287
if (defaultMessage .length () == 0 ) defaultMessage = null ;
276
288
} else if (line .equals (IGNORE_UNRESOLVABLE_LINE )) {
277
- reporter = isBundled ? UnresolvableReporting .SILENT : UnresolvableReporting .WARNING ;
289
+ if (isBundled ) {
290
+ reporter = UnresolvableReporting .SILENT ;
291
+ } else {
292
+ logger .warn (String .format (Locale .ENGLISH , "'%s' inside signatures files is deprecated, prefer using '%s' to ignore signatures where the class is missing." ,
293
+ IGNORE_UNRESOLVABLE_LINE , IGNORE_MISSING_CLASSES_LINE ));
294
+ reporter = UnresolvableReporting .WARNING ;
295
+ }
296
+ } else if (line .equals (IGNORE_MISSING_CLASSES_LINE )) {
297
+ localIgnoreMissingClasses = true ;
278
298
} else {
279
299
throw new ParseException ("Invalid line in signature file: " + line );
280
300
}
281
301
} else {
282
- addSignature (line , defaultMessage , reporter , missingClasses );
302
+ addSignature (line , defaultMessage , reporter , localIgnoreMissingClasses , missingClasses );
283
303
}
284
304
}
285
305
}
@@ -315,6 +335,11 @@ public boolean hasNoSignatures() {
315
335
(forbidNonPortableRuntime ? 1 : 0 );
316
336
}
317
337
338
+ /** Returns if no signatures files / inline signatures were parsed */
339
+ public boolean noSignaturesFilesParsed () {
340
+ return numberOfFiles == 0 ;
341
+ }
342
+
318
343
/** Returns if bundled signature to enable heuristics for detection of non-portable runtime calls is used */
319
344
public boolean isNonPortableRuntimeForbidden () {
320
345
return this .forbidNonPortableRuntime ;
0 commit comments