Skip to content

Commit ff61ca6

Browse files
author
Vincent Potucek
committed
Fix deprecated method in sun.misc.Unsafe has been called #2808
1 parent 284bb6e commit ff61ca6

File tree

1 file changed

+22
-32
lines changed

1 file changed

+22
-32
lines changed

lib/src/main/java/com/diffplug/spotless/java/ModuleHelper.java

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2025 DiffPlug
2+
* Copyright 2016-2026 DiffPlug
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,9 +15,10 @@
1515
*/
1616
package com.diffplug.spotless.java;
1717

18-
import java.lang.invoke.MethodHandle;
18+
import static java.lang.Class.forName;
19+
import static java.lang.invoke.MethodHandles.privateLookupIn;
20+
1921
import java.lang.invoke.MethodHandles;
20-
import java.lang.reflect.Field;
2122
import java.lang.reflect.Method;
2223
import java.lang.reflect.Modifier;
2324
import java.util.ArrayList;
@@ -26,15 +27,12 @@
2627
import java.util.List;
2728
import java.util.Map;
2829

29-
import javax.annotation.Nullable;
30-
3130
import org.slf4j.Logger;
3231
import org.slf4j.LoggerFactory;
3332

3433
import com.diffplug.spotless.Jvm;
3534

3635
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
37-
import sun.misc.Unsafe;
3836

3937
final class ModuleHelper {
4038
private static final Logger LOGGER = LoggerFactory.getLogger(ModuleHelper.class);
@@ -86,7 +84,7 @@ private static List<String> unavailableRequiredPackages() {
8684
final String key = e.getKey();
8785
final String value = e.getValue();
8886
try {
89-
final Class<?> clazz = Class.forName(key + "." + value);
87+
final Class<?> clazz = forName(key + "." + value);
9088
if (clazz.isEnum()) {
9189
clazz.getMethod("values").invoke(null);
9290
} else {
@@ -103,42 +101,34 @@ private static List<String> unavailableRequiredPackages() {
103101

104102
@SuppressWarnings("unchecked")
105103
private static void openPackages(Collection<String> packagesToOpen) throws Throwable {
106-
final Collection<?> modules = allModules();
107-
if (modules == null) {
108-
return;
109-
}
110-
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
111-
unsafeField.setAccessible(true);
112-
final Unsafe unsafe = (Unsafe) unsafeField.get(null);
113-
final Field implLookupField = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
114-
final MethodHandles.Lookup lookup = (MethodHandles.Lookup) unsafe.getObject(
115-
unsafe.staticFieldBase(implLookupField),
116-
unsafe.staticFieldOffset(implLookupField));
117-
final MethodHandle modifiers = lookup.findSetter(Method.class, "modifiers", Integer.TYPE);
118-
final Method exportMethod = Class.forName("java.lang.Module").getDeclaredMethod("implAddOpens", String.class);
119-
modifiers.invokeExact(exportMethod, Modifier.PUBLIC);
120-
for (Object module : modules) {
121-
final Collection<String> packages = (Collection<String>) module.getClass().getMethod("getPackages").invoke(module);
122-
for (String name : packages) {
104+
// Use MethodHandles.privateLookupIn for accessing private fields in JDK 9+
105+
// Get the IMPL_LOOKUP field using MethodHandles
106+
MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP").setAccessible(true);
107+
// Use MethodHandles to modify method accessibility
108+
var exportMethod = forName("java.lang.Module").getDeclaredMethod("implAddOpens", String.class);
109+
// Set method to public using MethodHandle
110+
privateLookupIn(MethodHandles.Lookup.class, MethodHandles.lookup())
111+
.findSetter(Method.class, "modifiers", int.class)
112+
.invokeExact(exportMethod, Modifier.PUBLIC);
113+
for (var module : allModules()) {
114+
for (var name : (Collection<String>) module.getClass().getMethod("getPackages").invoke(module)) {
123115
if (packagesToOpen.contains(name)) {
124116
exportMethod.invoke(module, name);
125117
}
126118
}
127119
}
128120
}
129121

130-
@Nullable @SuppressFBWarnings("REC_CATCH_EXCEPTION") // workaround JDK11
122+
@SuppressFBWarnings("REC_CATCH_EXCEPTION") // workaround JDK11
131123
private static Collection<?> allModules() {
132124
// calling ModuleLayer.boot().modules() by reflection
133125
try {
134-
final Object boot = Class.forName("java.lang.ModuleLayer").getMethod("boot").invoke(null);
135-
if (boot == null) {
136-
return null;
137-
}
138-
final Object modules = boot.getClass().getMethod("modules").invoke(boot);
139-
return (Collection<?>) modules;
126+
var boot = forName("java.lang.ModuleLayer").getMethod("boot").invoke(null);
127+
return boot != null
128+
? (Collection<?>) boot.getClass().getMethod("modules").invoke(boot)
129+
: List.of();
140130
} catch (Exception ignore) {
141-
return null;
131+
return List.of();
142132
}
143133
}
144134
}

0 commit comments

Comments
 (0)