Skip to content

Commit 5c18440

Browse files
committed
pilot
1 parent 8654450 commit 5c18440

2 files changed

Lines changed: 63 additions & 34 deletions

File tree

src/main/java/software/amazon/awssdk/crt/CRT.java

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,49 +30,74 @@ public final class CRT {
3030

3131
public static final String CRT_LIB_NAME = "aws-crt-jni";
3232
public static final int AWS_CRT_SUCCESS = 0;
33-
private static final CrtPlatform s_platform;
33+
private static CrtPlatform s_platform;
34+
private static final Throwable s_loadFailure;
3435

3536
static {
36-
// Scan for and invoke any platform specific initialization
37-
s_platform = findPlatformImpl();
38-
jvmInit();
37+
// The static initializer must never throw. If native load or init fails, capture
38+
// the cause into s_loadFailure so callers (via checkLoaded()) can surface it as a
39+
// catchable CrtRuntimeException, instead of triggering ExceptionInInitializerError
40+
// and subsequent NoClassDefFoundError for every CRT type the customer touches.
41+
Throwable loadFailure = null;
3942
try {
40-
// If the lib is already present/loaded or is in java.library.path, just use it
41-
System.loadLibrary(CRT_LIB_NAME);
42-
} catch (UnsatisfiedLinkError e) {
43-
String graalVMImageCode = System.getProperty("org.graalvm.nativeimage.imagecode");
44-
if (graalVMImageCode != null && graalVMImageCode == "runtime") {
45-
throw new CrtRuntimeException(
46-
"Failed to load '" + System.mapLibraryName(CRT_LIB_NAME) +
47-
"'. Make sure this file is in the same directory as the GraalVM native image. ");
48-
} else {
49-
// otherwise, load from the jar this class is in
50-
loadLibraryFromJar();
43+
// Scan for and invoke any platform specific initialization
44+
s_platform = findPlatformImpl();
45+
jvmInit();
46+
try {
47+
// If the lib is already present/loaded or is in java.library.path, just use it
48+
System.loadLibrary(CRT_LIB_NAME);
49+
} catch (UnsatisfiedLinkError e) {
50+
String graalVMImageCode = System.getProperty("org.graalvm.nativeimage.imagecode");
51+
if (graalVMImageCode != null && graalVMImageCode == "runtime") {
52+
throw new CrtRuntimeException(
53+
"Failed to load '" + System.mapLibraryName(CRT_LIB_NAME) +
54+
"'. Make sure this file is in the same directory as the GraalVM native image. ");
55+
} else {
56+
// otherwise, load from the jar this class is in
57+
loadLibraryFromJar();
58+
}
5159
}
52-
}
5360

54-
// Initialize the CRT
55-
int memoryTracingLevel = 0;
56-
try {
57-
memoryTracingLevel = Integer.parseInt(System.getProperty("aws.crt.memory.tracing"));
58-
} catch (Exception ex) {
59-
}
60-
boolean debugWait = System.getProperty("aws.crt.debugwait") != null;
61-
boolean strictShutdown = System.getProperty("aws.crt.strictshutdown") != null;
62-
awsCrtInit(memoryTracingLevel, debugWait, strictShutdown);
61+
// Initialize the CRT
62+
int memoryTracingLevel = 0;
63+
try {
64+
memoryTracingLevel = Integer.parseInt(System.getProperty("aws.crt.memory.tracing"));
65+
} catch (Exception ex) {
66+
}
67+
boolean debugWait = System.getProperty("aws.crt.debugwait") != null;
68+
boolean strictShutdown = System.getProperty("aws.crt.strictshutdown") != null;
69+
awsCrtInit(memoryTracingLevel, debugWait, strictShutdown);
6370

64-
Runtime.getRuntime().addShutdownHook(new Thread()
65-
{
66-
public void run()
71+
Runtime.getRuntime().addShutdownHook(new Thread()
6772
{
68-
CRT.releaseShutdownRef();
73+
public void run()
74+
{
75+
CRT.releaseShutdownRef();
76+
}
77+
});
78+
79+
try {
80+
Log.initLoggingFromSystemProperties();
81+
} catch (IllegalArgumentException e) {
82+
;
6983
}
70-
});
84+
} catch (Throwable t) {
85+
loadFailure = t;
86+
}
87+
s_loadFailure = loadFailure;
88+
}
7189

72-
try {
73-
Log.initLoggingFromSystemProperties();
74-
} catch (IllegalArgumentException e) {
75-
;
90+
/**
91+
* Throws a {@link CrtRuntimeException} if the CRT native library failed to load or initialize.
92+
* Otherwise returns normally. Customers can call this directly to probe availability, or rely on
93+
* {@link CrtResource} subclasses (e.g. {@code S3Client}, {@code EventLoopGroup}) to invoke it
94+
* during construction.
95+
*/
96+
public static void checkLoaded() {
97+
if (s_loadFailure != null) {
98+
CrtRuntimeException ex = new CrtRuntimeException("Failed to load AWS CRT native library");
99+
ex.initCause(s_loadFailure);
100+
throw ex;
76101
}
77102
}
78103

src/main/java/software/amazon/awssdk/crt/CrtResource.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ public String toString() {
108108
* Default constructor
109109
*/
110110
public CrtResource() {
111+
// If the native lib failed to load, surface a single, catchable CrtRuntimeException
112+
// before any subclass touches a native method (which would throw UnsatisfiedLinkError).
113+
CRT.checkLoaded();
114+
111115
if (debugNativeObjects) {
112116
String canonicalName = this.getClass().getCanonicalName();
113117

0 commit comments

Comments
 (0)