From fbb1432e8e545e4e739352a26e2886870146a7d7 Mon Sep 17 00:00:00 2001 From: Johan Rask Date: Thu, 19 Jan 2012 16:14:00 +0100 Subject: [PATCH] UnsafeDetectUtil also checks that the Unsafe class has the field theUnsafe to make it work on Android platform. --- .../java/io/netty/util/UnsafeDetectUtil.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/io/netty/util/UnsafeDetectUtil.java b/common/src/main/java/io/netty/util/UnsafeDetectUtil.java index 1feebaf549..5a7edd58d4 100644 --- a/common/src/main/java/io/netty/util/UnsafeDetectUtil.java +++ b/common/src/main/java/io/netty/util/UnsafeDetectUtil.java @@ -15,26 +15,44 @@ */ package io.netty.util; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.concurrent.atomic.AtomicInteger; /** * Utility which checks if {@value #UNSAFE} class can be found in the classpath + * and that it can be accessed using "theUnsafe" field which is not true for all platforms, i.e Android + * where it is called "THE_ONE". */ public final class UnsafeDetectUtil { + private static final String THE_UNSAFE = "theUnsafe"; private static final String UNSAFE = "sun.misc.Unsafe"; private static final boolean UNSAFE_FOUND = isUnsafeFound(AtomicInteger.class.getClassLoader()); public static boolean isUnsafeFound(ClassLoader loader) { try { - Class.forName(UNSAFE, true, loader); - return true; + Class unsafeClazz = Class.forName(UNSAFE, true, loader); + return hasUnsafeField(unsafeClazz); } catch (ClassNotFoundException e) { return false; - } + } catch (SecurityException e) { + return false; + } catch (PrivilegedActionException e) { + return false; + } } - + + private static boolean hasUnsafeField(final Class unsafeClass) throws PrivilegedActionException { + return AccessController.doPrivileged (new PrivilegedExceptionAction() { + public Boolean run() throws Exception { + unsafeClass.getDeclaredField(THE_UNSAFE); + return true; + }}); + } + public static boolean isUnsafeFound() { return UNSAFE_FOUND; }