Skip to content

Commit 028182c

Browse files
committed
change sun.misc.Unsafe to jdk.internal.misc.Unsafe
1 parent d656845 commit 028182c

File tree

5 files changed

+39
-12
lines changed

5 files changed

+39
-12
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@
721721
<artifactId>maven-compiler-plugin</artifactId>
722722
<version>${version.plugin.maven.compiler}</version>
723723
<configuration>
724-
<release>${version.java.target}</release>
724+
<target>${version.java.target}</target>
725725
</configuration>
726726
</plugin>
727727
<plugin>

xstream/pom.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@
296296
<execution>
297297
<id>compile-jdk16</id>
298298
<configuration>
299-
<release>16</release>
299+
<target>16</target>
300300
<testExcludes combine.self="override" />
301301
<testIncludes>
302302
<include>**/Record**</include>
@@ -330,7 +330,7 @@
330330
<execution>
331331
<id>compile-jdk15</id>
332332
<configuration>
333-
<release>15</release>
333+
<target>15</target>
334334
<testExcludes combine.self="override" />
335335
<testIncludes>
336336
<include>**/Record**</include>
@@ -383,6 +383,8 @@
383383
<configuration>
384384
<compilerArgs>
385385
<arg>-XDignore.symbol.file</arg>
386+
<arg>--add-exports</arg>
387+
<arg>java.base/jdk.internal.misc=ALL-UNNAMED</arg>
386388
</compilerArgs>
387389
</configuration>
388390
</plugin>
@@ -468,6 +470,7 @@
468470
--add-opens java.xml/com.sun.xml.internal.stream=ALL-UNNAMED
469471
--add-opens java.xml/com.sun.org.apache.xerces.internal.parsers=ALL-UNNAMED
470472
--add-opens java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED
473+
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED
471474
</surefire.argline>
472475
<surefire.preview.arg/>
473476
</properties>

xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
import com.thoughtworks.xstream.converters.ConversionException;
1313
import com.thoughtworks.xstream.converters.ErrorWritingException;
1414

15-
import sun.misc.Unsafe;
16-
15+
import jdk.internal.misc.Unsafe;
1716

1817
/**
1918
* Instantiates a new object bypassing the constructor using undocumented internal JDK features.
2019
* <p>
2120
* The code in the constructor will never be executed and parameters do not have to be known. This is the same method
22-
* used by the internals of standard Java serialization, but relies on internal code (sun.misc.Unsafe) that may not be
23-
* present on all JVMs.
21+
* used by the internals of standard Java serialization, but relies on internal code (jdk.internal.misc.Unsafe).
2422
* <p>
2523
* <p>
2624
* The implementation will use standard Java functionality to write any fields. This requires Java 5 as minimum runtime

xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,19 @@
1111
*/
1212
package com.thoughtworks.xstream.converters.reflection;
1313

14+
import com.thoughtworks.xstream.core.JVM;
15+
1416
import java.lang.reflect.Field;
17+
import java.lang.reflect.InvocationTargetException;
18+
import java.lang.reflect.Method;
1519
import java.util.concurrent.ConcurrentHashMap;
1620
import java.util.concurrent.ConcurrentMap;
1721

18-
1922
/**
2023
* Instantiates a new object bypassing the constructor using undocumented internal JDK features.
2124
* <p>
2225
* The code in the constructor will never be executed and parameters do not have to be known. This is the same method
23-
* used by the internals of standard Java serialization, but relies on internal code (sun.misc.Unsafe) that may not be
24-
* present on all JVMs.
26+
* used by the internals of standard Java serialization, but relies on internal code (jdk.internal.misc.Unsafe).
2527
* <p>
2628
* <p>
2729
* The implementation will use the same internals to write into fields. This is a lot faster and was additionally the
@@ -38,6 +40,7 @@ public class SunUnsafeReflectionProvider extends SunLimitedUnsafeReflectionProvi
3840
// references to the Field key are kept in the FieldDictionary
3941
private transient ConcurrentMap<Field, Long> fieldOffsetCache;
4042

43+
private static final Method PUT_REFERENCE_UNSAFE_METHOD = getPutReferenceMethod();
4144
/**
4245
* @since 1.4.7
4346
*/
@@ -91,7 +94,7 @@ private void write(final Field field, final Object object, final Object value) {
9194
throw ex;
9295
}
9396
} else {
94-
unsafe.putObject(object, offset, value);
97+
putReferenceUnsafe(object, field, offset, value);
9598
}
9699

97100
} catch (final IllegalArgumentException e) {
@@ -116,6 +119,29 @@ private Object readResolve() {
116119
return this;
117120
}
118121

122+
private static Method getPutReferenceMethod() {
123+
Class<?> unsafeClass = unsafe.getClass();
124+
String methodName = "putObject";
125+
if(JVM.isVersion(12)) {
126+
methodName = "putReference";
127+
}
128+
try {
129+
return unsafeClass.getDeclaredMethod(methodName, Object.class, long.class, Object.class);
130+
} catch (NoSuchMethodException e) {
131+
throw new RuntimeException(e);
132+
}
133+
}
134+
135+
private void putReferenceUnsafe(Object object, Field field, long offset, Object value) {
136+
try {
137+
PUT_REFERENCE_UNSAFE_METHOD.invoke(unsafe, object, offset, value);
138+
} catch (IllegalAccessException | InvocationTargetException e) {
139+
final ObjectAccessException ex = new ObjectAccessException("Cannot set field", e);
140+
ex.add("field", object.getClass() + "." + field.getName());
141+
throw ex;
142+
}
143+
}
144+
119145
@Override
120146
protected void init() {
121147
super.init();

xstream/src/java/com/thoughtworks/xstream/core/JVM.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static class Test {
9595
boolean test = true;
9696
Object unsafe = null;
9797
try {
98-
final Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
98+
final Class<?> unsafeClass = Class.forName("jdk.internal.misc.Unsafe");
9999
final Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
100100
unsafeField.setAccessible(true);
101101
unsafe = unsafeField.get(null);

0 commit comments

Comments
 (0)