PlatformDependent static initialization ExceptionInInitializerError

Motivation:
PlatformDependent allows some exceptions to escape during static initialization. If an exception escapes it will be translated into a java.lang.ExceptionInInitializerError and render the application unable to run.

Modifications:
- Make sure to catch Throwable during static initialization.

Result:
PlatformDependent static initialization doesn't result in java.lang.ExceptionInInitializerError.
This commit is contained in:
Scott Mitchell 2016-01-19 14:53:55 -08:00
parent 391a411264
commit 7494e84208
2 changed files with 30 additions and 24 deletions

View File

@ -657,7 +657,7 @@ public final class PlatformDependent {
try { try {
Class.forName("android.app.Application", false, getSystemClassLoader()); Class.forName("android.app.Application", false, getSystemClassLoader());
android = true; android = true;
} catch (Exception e) { } catch (Throwable ignored) {
// Failed to load the class uniquely available in Android. // Failed to load the class uniquely available in Android.
android = false; android = false;
} }
@ -704,7 +704,7 @@ public final class PlatformDependent {
// Ignore // Ignore
} }
} }
} catch (Exception e) { } catch (Throwable ignored) {
// Failed to run the command. // Failed to run the command.
uid = null; uid = null;
} finally { } finally {
@ -785,7 +785,7 @@ public final class PlatformDependent {
Class.forName("java.time.Clock", false, getClassLoader(Object.class)); Class.forName("java.time.Clock", false, getClassLoader(Object.class));
javaVersion = 8; javaVersion = 8;
break; break;
} catch (Exception e) { } catch (Throwable ignored) {
// Ignore // Ignore
} }
@ -793,7 +793,7 @@ public final class PlatformDependent {
Class.forName("java.util.concurrent.LinkedTransferQueue", false, getClassLoader(BlockingQueue.class)); Class.forName("java.util.concurrent.LinkedTransferQueue", false, getClassLoader(BlockingQueue.class));
javaVersion = 7; javaVersion = 7;
break; break;
} catch (Exception e) { } catch (Throwable ignored) {
// Ignore // Ignore
} }
@ -838,7 +838,7 @@ public final class PlatformDependent {
boolean hasUnsafe = PlatformDependent0.hasUnsafe(); boolean hasUnsafe = PlatformDependent0.hasUnsafe();
logger.debug("sun.misc.Unsafe: {}", hasUnsafe ? "available" : "unavailable"); logger.debug("sun.misc.Unsafe: {}", hasUnsafe ? "available" : "unavailable");
return hasUnsafe; return hasUnsafe;
} catch (Throwable t) { } catch (Throwable ignored) {
// Probably failed to initialize PlatformDependent0. // Probably failed to initialize PlatformDependent0.
return false; return false;
} }
@ -851,7 +851,7 @@ public final class PlatformDependent {
Class<?> vmClass = Class.forName("sun.misc.VM", true, getSystemClassLoader()); Class<?> vmClass = Class.forName("sun.misc.VM", true, getSystemClassLoader());
Method m = vmClass.getDeclaredMethod("maxDirectMemory"); Method m = vmClass.getDeclaredMethod("maxDirectMemory");
maxDirectMemory = ((Number) m.invoke(null)).longValue(); maxDirectMemory = ((Number) m.invoke(null)).longValue();
} catch (Throwable t) { } catch (Throwable ignored) {
// Ignore // Ignore
} }
@ -891,7 +891,7 @@ public final class PlatformDependent {
} }
break; break;
} }
} catch (Throwable t) { } catch (Throwable ignored) {
// Ignore // Ignore
} }
@ -976,7 +976,7 @@ public final class PlatformDependent {
return f; return f;
} }
} }
} catch (Exception ignored) { } catch (Throwable ignored) {
// Environment variable inaccessible // Environment variable inaccessible
} }

View File

@ -136,23 +136,29 @@ final class PlatformDependent0 {
UNALIGNED = unaligned; UNALIGNED = unaligned;
logger.debug("java.nio.Bits.unaligned: {}", UNALIGNED); logger.debug("java.nio.Bits.unaligned: {}", UNALIGNED);
Field stringValueField = AccessController.doPrivileged(new PrivilegedAction<Field>() { Field stringValueField = null;
@Override try {
public Field run() { stringValueField = AccessController.doPrivileged(new PrivilegedAction<Field>() {
try { @Override
Field f = String.class.getDeclaredField("value"); public Field run() {
f.setAccessible(true); try {
return f; Field f = String.class.getDeclaredField("value");
} catch (NoSuchFieldException e) { f.setAccessible(true);
logger.warn("Failed to find String value array." + return f;
"String hash code optimizations are disabled.", e); } catch (NoSuchFieldException e) {
} catch (SecurityException e) { logger.info("Failed to find String value array (please report an issue)." +
logger.info("No permissions to get String value array." + "String hash code optimizations are disabled.", e);
"String hash code optimizations are disabled.", e); } catch (SecurityException e) {
logger.debug("No permissions to get String value array." +
"String hash code optimizations are disabled.", e);
}
return null;
} }
return null; });
} } catch (Throwable t) {
}); logger.debug("AccessController.doPrivileged failed to get String value array." +
"String hash code optimizations are disabled.", t);
}
STRING_VALUE_FIELD_OFFSET = stringValueField == null ? STRING_VALUE_FIELD_OFFSET = stringValueField == null ?
-1 : UNSAFE.objectFieldOffset(stringValueField); -1 : UNSAFE.objectFieldOffset(stringValueField);
} }