28
28
import java .lang .invoke .MethodHandles ;
29
29
import java .lang .invoke .MethodType ;
30
30
import java .lang .reflect .Field ;
31
+ import java .lang .reflect .InvocationTargetException ;
31
32
import java .lang .reflect .Method ;
32
33
import java .nio .ByteBuffer ;
33
34
import java .nio .MappedByteBuffer ;
@@ -388,21 +389,18 @@ public Object run() throws Exception {
388
389
}
389
390
}
390
391
391
- // <=JDK8 class DirectByteBuffer { sun.misc.Cleaner cleaner(Buffer buf) }
392
- // then call sun.misc.Cleaner.clean
393
- try {
394
- if (buffer .getClass ().getSimpleName ().equals ("MappedByteBufferAdapter" )) {
395
- if (!Constants .ANDROID )
396
- throw new RuntimeException ("MappedByteBufferAdapter only supported for Android at the moment" );
397
-
398
- // Regarding MappedByteBufferAdapter on Android 4.1, see #914
399
- final Class <?> directByteBufferClass = Class .forName ("java.nio.MappedByteBufferAdapter" );
400
- final Method dbbFreeMethod = directByteBufferClass .getMethod ("free" );
401
- dbbFreeMethod .setAccessible (true );
402
- // call: ((MappedByteBufferAdapter)buffer).free()
403
- dbbFreeMethod .invoke (buffer );
404
- } else {
405
- final Class <?> directByteBufferClass = Class .forName ("java.nio.DirectByteBuffer" );
392
+ if (buffer .getClass ().getSimpleName ().equals ("MappedByteBufferAdapter" )) {
393
+ if (!Constants .ANDROID )
394
+ throw new RuntimeException ("MappedByteBufferAdapter only supported for Android at the moment" );
395
+
396
+ // For Android 4.1 call ((MappedByteBufferAdapter)buffer).free() see #914
397
+ Class <?> directByteBufferClass = Class .forName ("java.nio.MappedByteBufferAdapter" );
398
+ callBufferFree (buffer , directByteBufferClass );
399
+ } else {
400
+ // <=JDK8 class DirectByteBuffer { sun.misc.Cleaner cleaner(Buffer buf) }
401
+ // then call sun.misc.Cleaner.clean
402
+ final Class <?> directByteBufferClass = Class .forName ("java.nio.DirectByteBuffer" );
403
+ try {
406
404
final Method dbbCleanerMethod = directByteBufferClass .getMethod ("cleaner" );
407
405
dbbCleanerMethod .setAccessible (true );
408
406
// call: cleaner = ((DirectByteBuffer)buffer).cleaner()
@@ -414,11 +412,16 @@ public Object run() throws Exception {
414
412
// call: ((sun.misc.Cleaner)cleaner).clean()
415
413
cleanMethod .invoke (cleaner );
416
414
}
415
+ } catch (NoSuchMethodException ex2 ) {
416
+ if (Constants .ANDROID )
417
+ // For Android 5.1.1 call ((DirectByteBuffer)buffer).free() see #933
418
+ callBufferFree (buffer , directByteBufferClass );
419
+ else
420
+ // ignore if method cleaner or clean is not available
421
+ LOGGER .warn ("NoSuchMethodException | " + Constants .JAVA_VERSION , ex2 );
417
422
}
418
- } catch (NoSuchMethodException ex2 ) {
419
- // ignore if method cleaner or clean is not available
420
- LOGGER .warn ("NoSuchMethodException | " + Constants .JAVA_VERSION , ex2 );
421
423
}
424
+
422
425
return null ;
423
426
}
424
427
});
@@ -427,6 +430,17 @@ public Object run() throws Exception {
427
430
}
428
431
}
429
432
433
+ private static void callBufferFree (ByteBuffer buffer , Class <?> directByteBufferClass )
434
+ throws InvocationTargetException , IllegalAccessException {
435
+ try {
436
+ final Method dbbFreeMethod = directByteBufferClass .getMethod ("free" );
437
+ dbbFreeMethod .setAccessible (true );
438
+ dbbFreeMethod .invoke (buffer );
439
+ } catch (NoSuchMethodException ex2 ) {
440
+ LOGGER .warn ("NoSuchMethodException | " + Constants .JAVA_VERSION , ex2 );
441
+ }
442
+ }
443
+
430
444
/**
431
445
* Trying to force the release of the mapped ByteBuffer. See
432
446
* http://stackoverflow.com/q/2972986/194609 and use only if you know what you are doing.
0 commit comments