Skip to content

Commit 3514901

Browse files
Add check if sun.misc.Unsafe is present but throws on use, to use the preexisting no-Unsafe paths if it does.
JavaProto is already robust in the absence of sun.misc.Unsafe, and checks for its existence via reflection to use as a performance optimization. As part of the planned removal of sun.misc.Unsafe, a future JDK will have Unsafe available but most of the methods will throw by default, which would break JavaProto. This creates an odd situation that if it was removed we wouldn't break, but the intermediate turndown state does break us. By adding a usage of one method to see if it throws an UnsupportedOperationException, we avoid breaking users if they use Protobuf in this intermediate turndown state of the API (which will become the default state in a future JDK release). It is still TBD whether a future release of Protobuf may stop using sun.misc.Unsafe always, or if we may keep this code alive for users running old JDKs; that detail is still TBD depending on performance implications. #20760 PiperOrigin-RevId: 836715451
1 parent 363da84 commit 3514901

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

java/core/src/main/java/com/google/protobuf/UnsafeUtil.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,30 @@ public sun.misc.Unsafe run() throws Exception {
284284
// Catching Throwable here due to the fact that Google AppEngine raises NoClassDefFoundError
285285
// for Unsafe.
286286
}
287-
return unsafe;
287+
288+
if (unsafe == null) {
289+
return null;
290+
}
291+
292+
// Unsafe is terminally deprecated and will be removed in a future version. Our runtime is
293+
// anyway compatible with environments where Unsafe is not available, but as part of the removal
294+
// some environments will have Unsafe available but throw on use, which would break us. To check
295+
// if the JDK is in this state, simply try using a method and see if it does throw.
296+
try {
297+
int unused = unsafe.arrayBaseOffset(byte[].class);
298+
return unsafe;
299+
} catch (Exception unused) {
300+
Logger.getLogger(UnsafeUtil.class.getName())
301+
.log(
302+
Level.WARNING,
303+
"As part of the planned removal, sun.misc.Unsafe is available in the current"
304+
+ " environment but configured to throw on use. Protobuf will continue without"
305+
+ " using it, but with slightly reduced performance."
306+
+ " --sun-misc-unsafe-memory-access=allow is likely available to opt back in if"
307+
+ " desired. A later Protobuf version release will stop using sun.misc.Unsafe"
308+
+ " entirely.");
309+
return null;
310+
}
288311
}
289312

290313
/** Get a {@link MemoryAccessor} appropriate for the platform, or null if not supported. */

0 commit comments

Comments
 (0)