1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3;
18
19 import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
24 import static org.junit.jupiter.api.Assertions.assertNotNull;
25 import static org.junit.jupiter.api.Assertions.assertNotSame;
26 import static org.junit.jupiter.api.Assertions.assertNull;
27 import static org.junit.jupiter.api.Assertions.assertSame;
28 import static org.junit.jupiter.api.Assertions.assertThrows;
29 import static org.junit.jupiter.api.Assertions.assertTrue;
30
31 import java.io.ByteArrayInputStream;
32 import java.io.ByteArrayOutputStream;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.ObjectInputStream;
36 import java.io.ObjectOutputStream;
37 import java.io.OutputStream;
38 import java.io.Serializable;
39 import java.lang.reflect.Constructor;
40 import java.lang.reflect.Modifier;
41 import java.util.HashMap;
42 import java.util.function.Supplier;
43
44 import org.junit.jupiter.api.BeforeEach;
45 import org.junit.jupiter.api.Test;
46
47 final class ClassNotFoundSerialization implements Serializable {
48
49 private static final long serialVersionUID = 1L;
50
51 private void readObject(final ObjectInputStream in) throws ClassNotFoundException {
52 throw new ClassNotFoundException(SerializationUtilsTest.CLASS_NOT_FOUND_MESSAGE);
53 }
54 }
55
56 interface SerializableSupplier<T> extends Supplier<T>, Serializable {
57
58 }
59
60
61
62
63 class SerializationUtilsTest extends AbstractLangTest {
64
65 static final String CLASS_NOT_FOUND_MESSAGE = "ClassNotFoundSerialization.readObject fake exception";
66 protected static final String SERIALIZE_IO_EXCEPTION_MESSAGE = "Anonymous OutputStream I/O exception";
67
68 private String iString;
69 private Integer iInteger;
70 private HashMap<Object, Object> iMap;
71
72 @BeforeEach
73 public void setUp() {
74 iString = "foo";
75 iInteger = Integer.valueOf(7);
76 iMap = new HashMap<>();
77 iMap.put("FOO", iString);
78 iMap.put("BAR", iInteger);
79 }
80
81 @Test
82 void testClone() {
83 final Object test = SerializationUtils.clone(iMap);
84 assertNotNull(test);
85 assertInstanceOf(HashMap.class, test);
86 assertNotSame(test, iMap);
87 final HashMap<?, ?> testMap = (HashMap<?, ?>) test;
88 assertEquals(iString, testMap.get("FOO"));
89 assertNotSame(iString, testMap.get("FOO"));
90 assertEquals(iInteger, testMap.get("BAR"));
91 assertNotSame(iInteger, testMap.get("BAR"));
92 assertEquals(iMap, testMap);
93 }
94
95 @Test
96 void testCloneNull() {
97 final Object test = SerializationUtils.clone(null);
98 assertNull(test);
99 }
100
101 @Test
102 void testCloneSerializableSupplier() {
103 final SerializableSupplier<String> supplier = () -> "test";
104 assertEquals("test", supplier.get());
105 final SerializableSupplier<String> clone = SerializationUtils.clone(supplier);
106 assertEquals("test", clone.get());
107 }
108
109 @Test
110 void testCloneUnserializable() {
111 iMap.put(new Object(), new Object());
112 assertThrows(SerializationException.class, () -> SerializationUtils.clone(iMap));
113 }
114
115 @Test
116 void testConstructor() {
117 assertNotNull(new SerializationUtils());
118 final Constructor<?>[] cons = SerializationUtils.class.getDeclaredConstructors();
119 assertEquals(1, cons.length);
120 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
121 assertTrue(Modifier.isPublic(SerializationUtils.class.getModifiers()));
122 assertFalse(Modifier.isFinal(SerializationUtils.class.getModifiers()));
123 }
124
125 @Test
126 void testDeserializeBytes() throws Exception {
127 final ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
128 try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) {
129 oos.writeObject(iMap);
130 oos.flush();
131 }
132
133 final Object test = SerializationUtils.deserialize(streamReal.toByteArray());
134 assertNotNull(test);
135 assertInstanceOf(HashMap.class, test);
136 assertNotSame(test, iMap);
137 final HashMap<?, ?> testMap = (HashMap<?, ?>) test;
138 assertEquals(iString, testMap.get("FOO"));
139 assertNotSame(iString, testMap.get("FOO"));
140 assertEquals(iInteger, testMap.get("BAR"));
141 assertNotSame(iInteger, testMap.get("BAR"));
142 assertEquals(iMap, testMap);
143 }
144
145 @Test
146 void testDeserializeBytesBadStream() {
147 assertThrows(SerializationException.class, () -> SerializationUtils.deserialize(new byte[0]));
148 }
149
150 @Test
151 void testDeserializeBytesNull() {
152 assertNullPointerException(() -> SerializationUtils.deserialize((byte[]) null));
153 }
154
155 @Test
156 void testDeserializeBytesOfNull() throws Exception {
157 final ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
158 try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) {
159 oos.writeObject(null);
160 oos.flush();
161 }
162
163 final Object test = SerializationUtils.deserialize(streamReal.toByteArray());
164 assertNull(test);
165 }
166
167 @Test
168 void testDeserializeClassCastException() {
169 final String value = "Hello";
170 final byte[] serialized = SerializationUtils.serialize(value);
171 assertEquals(value, SerializationUtils.deserialize(serialized));
172 assertThrows(ClassCastException.class, () -> {
173
174 @SuppressWarnings("unused")
175 final Integer i = SerializationUtils.deserialize(serialized);
176 });
177 }
178
179 @Test
180 void testDeserializeStream() throws Exception {
181 final ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
182 try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) {
183 oos.writeObject(iMap);
184 oos.flush();
185 }
186
187 final ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray());
188 final Object test = SerializationUtils.deserialize(inTest);
189 assertNotNull(test);
190 assertInstanceOf(HashMap.class, test);
191 assertNotSame(test, iMap);
192 final HashMap<?, ?> testMap = (HashMap<?, ?>) test;
193 assertEquals(iString, testMap.get("FOO"));
194 assertNotSame(iString, testMap.get("FOO"));
195 assertEquals(iInteger, testMap.get("BAR"));
196 assertNotSame(iInteger, testMap.get("BAR"));
197 assertEquals(iMap, testMap);
198 }
199
200 @Test
201 void testDeserializeStreamBadStream() {
202 assertThrows(SerializationException.class, () -> SerializationUtils.deserialize(new ByteArrayInputStream(new byte[0])));
203 }
204
205 @Test
206 void testDeserializeStreamClassNotFound() throws Exception {
207 final ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
208 try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) {
209 oos.writeObject(new ClassNotFoundSerialization());
210 oos.flush();
211 }
212
213 final ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray());
214 final SerializationException se = assertThrows(SerializationException.class, () -> SerializationUtils.deserialize(inTest));
215 assertEquals("java.lang.ClassNotFoundException: " + CLASS_NOT_FOUND_MESSAGE, se.getMessage());
216 }
217
218 @Test
219 void testDeserializeStreamNull() {
220 assertNullPointerException(() -> SerializationUtils.deserialize((InputStream) null));
221 }
222
223 @Test
224 void testDeserializeStreamOfNull() throws Exception {
225 final ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
226 try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) {
227 oos.writeObject(null);
228 oos.flush();
229 }
230
231 final ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray());
232 final Object test = SerializationUtils.deserialize(inTest);
233 assertNull(test);
234 }
235
236 @Test
237 void testException() {
238 SerializationException serEx;
239 final Exception ex = new Exception();
240
241 serEx = new SerializationException();
242 assertSame(null, serEx.getMessage());
243 assertSame(null, serEx.getCause());
244
245 serEx = new SerializationException("Message");
246 assertSame("Message", serEx.getMessage());
247 assertSame(null, serEx.getCause());
248
249 serEx = new SerializationException(ex);
250 assertEquals("java.lang.Exception", serEx.getMessage());
251 assertSame(ex, serEx.getCause());
252
253 serEx = new SerializationException("Message", ex);
254 assertSame("Message", serEx.getMessage());
255 assertSame(ex, serEx.getCause());
256 }
257
258 @Test
259 void testNegativeByteArray() {
260 final byte[] byteArray = {
261 (byte) -84, (byte) -19, (byte) 0, (byte) 5, (byte) 125, (byte) -19, (byte) 0,
262 (byte) 5, (byte) 115, (byte) 114, (byte) -1, (byte) 97, (byte) 122, (byte) -48, (byte) -65
263 };
264
265 assertThrows(SerializationException.class, () -> SerializationUtils.deserialize(new ByteArrayInputStream(byteArray)));
266 }
267
268 @Test
269 void testPrimitiveTypeClassSerialization() {
270 final Class<?>[] primitiveTypes = { byte.class, short.class, int.class, long.class, float.class, double.class,
271 boolean.class, char.class, void.class };
272
273 for (final Class<?> primitiveType : primitiveTypes) {
274 final Class<?> clone = SerializationUtils.clone(primitiveType);
275 assertEquals(primitiveType, clone);
276 }
277 }
278
279 @Test
280 void testRoundtrip() {
281 final HashMap<Object, Object> newMap = SerializationUtils.roundtrip(iMap);
282 assertEquals(iMap, newMap);
283 }
284
285 @Test
286 void testSerializeBytes() throws Exception {
287 final byte[] testBytes = SerializationUtils.serialize(iMap);
288
289 final ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
290 try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) {
291 oos.writeObject(iMap);
292 oos.flush();
293 }
294
295 final byte[] realBytes = streamReal.toByteArray();
296 assertEquals(testBytes.length, realBytes.length);
297 assertArrayEquals(realBytes, testBytes);
298 }
299
300 @Test
301 void testSerializeBytesNull() throws Exception {
302 final byte[] testBytes = SerializationUtils.serialize(null);
303
304 final ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
305 try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) {
306 oos.writeObject(null);
307 oos.flush();
308 }
309
310 final byte[] realBytes = streamReal.toByteArray();
311 assertEquals(testBytes.length, realBytes.length);
312 assertArrayEquals(realBytes, testBytes);
313 }
314
315 @Test
316 void testSerializeBytesUnserializable() {
317 iMap.put(new Object(), new Object());
318 assertThrows(SerializationException.class, () -> SerializationUtils.serialize(iMap));
319 }
320
321 @Test
322 void testSerializeIOException() {
323
324
325 final OutputStream streamTest = new OutputStream() {
326 @Override
327 public void write(final int arg0) throws IOException {
328 throw new IOException(SERIALIZE_IO_EXCEPTION_MESSAGE);
329 }
330 };
331 final SerializationException e =
332 assertThrows(SerializationException.class, () -> SerializationUtils.serialize(iMap, streamTest));
333 assertEquals("java.io.IOException: " + SERIALIZE_IO_EXCEPTION_MESSAGE, e.getMessage());
334 }
335
336 @Test
337 void testSerializeStream() throws Exception {
338 final ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
339 SerializationUtils.serialize(iMap, streamTest);
340
341 final ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
342 try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) {
343 oos.writeObject(iMap);
344 oos.flush();
345 }
346
347 final byte[] testBytes = streamTest.toByteArray();
348 final byte[] realBytes = streamReal.toByteArray();
349 assertEquals(testBytes.length, realBytes.length);
350 assertArrayEquals(realBytes, testBytes);
351 }
352
353 @Test
354 void testSerializeStreamNullNull() {
355 assertNullPointerException(() -> SerializationUtils.serialize(null, null));
356 }
357
358 @Test
359 void testSerializeStreamNullObj() throws Exception {
360 final ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
361 SerializationUtils.serialize(null, streamTest);
362
363 final ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
364 try (ObjectOutputStream oos = new ObjectOutputStream(streamReal)) {
365 oos.writeObject(null);
366 oos.flush();
367 }
368
369 final byte[] testBytes = streamTest.toByteArray();
370 final byte[] realBytes = streamReal.toByteArray();
371 assertEquals(testBytes.length, realBytes.length);
372 assertArrayEquals(realBytes, testBytes);
373 }
374
375 @Test
376 void testSerializeStreamObjNull() {
377 assertNullPointerException(() -> SerializationUtils.serialize(iMap, null));
378 }
379
380 @Test
381 void testSerializeStreamUnserializable() {
382 final ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
383 iMap.put(new Object(), new Object());
384 assertThrows(SerializationException.class, () -> SerializationUtils.serialize(iMap, streamTest));
385 }
386 }