-
Notifications
You must be signed in to change notification settings - Fork 9
/
faq.html
1004 lines (815 loc) · 68.6 KB
/
faq.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
Copyright (C) 2005, 2006 Joe Walnes.
Copyright (C) 2006, 2007, 2008, 2021 XStream committers.
All rights reserved.
The software in this package is published under the terms of the BSD
style license a copy of which has been included with this distribution in
the LICENSE.txt file.
Created on 29. January 2005 by Joe Walnes
-->
<head>
<title>XStream - Frequently Asked Questions</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
<!-- Google analytics -->
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-110973-2";
urchinTracker();
</script>
</head>
<body>
<div id="banner">
<a href="index.html"><img id="logo" src="logo.gif" alt="XStream"/></a>
</div>
<div id="center" class="Content2Column"> <!-- Content3Column for index -->
<div id="content">
<h1 class="FirstChild">Frequently Asked Questions</h1>
<ol>
<li><a href="#Compatibility">Compatibility</a></li>
<li><a href="#Serialization">Serialization</a></li>
<li><a href="#XML">XML specifics</a></li>
<li><a href="#JSON">JSON specifics</a></li>
<li><a href="#Security">Security aspects</a></li>
<li><a href="#Other_Products">Comparison to other products</a></li>
<li><a href="#Scalability">Scalability</a></li>
<li><a href="#Uses">Uses of XStream</a></li>
</ol>
<!-- ****************************************************** -->
<h1 id="Compatibility">Compatibility</h1>
<!-- ...................................................... -->
<h2 id="Compatibility_JRE">Which Java runtime is required to run XStream?</h2>
<p>XStream 1.4.x requires Java 1.4 or later. Note, that the XStream libraries contains class files targeting
different Java runtime versions or Java features. These classes are loaded by reflection and only used if XStream
is running on an appropriate runtime environment.</p>
<p>Environments that load all class files of a Java archive can fail with this approach, the
<a href="#Compatibility_Android">Android runtime</a> is such an example. You can build your own version of XStream
with a <a href="#Compatibility_JDK">lower JDK</a> then.</p>
<p>For Java 9 and later you will currently have to permit the now illegal access for XStream to operate.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_JDK">Which JDK is required to build XStream?</h2>
<p>XStream 1.4.x can be build still with JDK 1.4 (see BUILD.txt). However, to support the latest features it
requires currently a JDK of Java 8. Otherwise the resulting jar file will miss some class files not available on
earlier runtimes. Depending on the target environment this can be useful (e.g. for Android or GAE).</p>
<p>Note, that such Java archives will fail on higher Java runtimes then.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_Dependencies">Which dependencies are required to run XStream?</h2>
<p>All dependencies are optional, XStream uses since version 1.4.1 by default xpp3:xpp3_min and xmlpull:xmlpull.
However it depends on the use case. XStream will run without dependencies using the DOM driver on all Java runtimes
or the StAX driver in combination with Java 6 or greater. See the list of <a
href="download.html#optional-deps">optional dependencies</a>.</p>
<p>Note, that XStream's manifest contains OSGi entries that declare all dependencies as optional.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_JVMs">Does XStream behave differently across different JVMs?</h2>
<p>XStream has two modes of operation: <b>Pure Java</b> and <b>Enhanced</b>. In pure Java mode,
XStream behaves in the same way across different JVMs, however its features are limited to what
reflection allows, meaning it cannot serialize certain classes or fields. In <b>enhanced</b> mode,
XStream does not have these limitations, however this mode of operation is not available to all JVMs.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_enhanced_mode_jvm">Which JVMs allow XStream to operate in enhanced mode?</h2>
<p>XStream checks since version 1.4.5 automatically for a working enhanced mode - based on undocumented internal
Java runtime classes. This enhanced mode is known to be working on the Oracle/Sun, Apple, HP, IBM and Blackdown
1.4 JVMs and onwards, for IcedTea 6 and onwards, for Hitachi, SAP and Diablo from 1.5 and onwards, for BEA JRockit
starting with R25.1.0. Generally it works for all modern Java runtimes based on OpenJDK. Android basically supports
the enhanced mode as well as the Google Application Engine, but the latter's security model limits the types that
can be handled. Note, that an active SecurityManager might prevent the usage of the enhanced mode also.</p>
<p>Since Java 9 it is required to permit the now illegal access. For Java 17 see below.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_enhanced_mode_advantage">What are the advantages of using enhanced mode over pure Java mode?</h2>
<p>Currently it is not possible to recreate every instance of a type using the official Java API only. The enhanced
mode uses some undocumented, but wide-spread available functionality to recreate such instances nevertheless. However,
in a secured secured environment, older Java run times or a limited Java environment might prevent the usage of the
enhanced mode and XStream uses the plain Java API as fallback. This mode has some restrictions though:</p>
<table summary="Comparison of pure Java and enhanced mode">
<tr><th>Feature</th><th>Pure Java</th><th>Enhanced Mode</th></tr>
<tr><td>Public classes</td><td>Yes</td><td>Yes</td></tr>
<tr><td>Non public classes</td><td>No</td><td>Yes</td></tr>
<tr><td>Static inner classes</td><td>Yes</td><td>Yes</td></tr>
<tr><td>Non-static inner classes</td><td>No</td><td>Yes</td></tr>
<tr><td>Anonymous inner classes</td><td>No</td><td>Yes</td></tr>
<tr><td>With default constructor</td><td>Yes</td><td>Yes</td></tr>
<tr><td>Without default constructor</td><td>No</td><td>Yes</td></tr>
<tr><td>Private fields</td><td>Yes</td><td>Yes</td></tr>
<tr><td>Final fields</td><td>Yes >= JDK 1.5</td><td>Yes</td></tr>
</table>
<!-- ...................................................... -->
<h2 id="Compatibility_illegal_reflective_access">Java runtime warns me about an illegal reflective access by XStream!</h2>
<p>Yes, this is normal. A big part of XStream is reflection based and there is currently no replacement for the
complete required functionality. You will have to permit this access currently, otherwise XStream will not work.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_cannot_access_from_unnamed_module">XStream fails since Java 17, because types in modules cannot be accessed from the unnamed module!</h2>
<p>Again, this is normal. The reflection stuff is required to get all required information to recreate an instance of
a Java type at unmarshalling time. However, since Java 17 it is no longer possible to allow this access with a single
runtime option. You have to open all packages of the individual modules for the unnamed module with the option
<i>--add-opens</i>, where XStream requires access, e.g. <i>--add-opens java.base/java.util=ALL-UNNAMED</i></p>
<!-- ...................................................... -->
<h2 id="Compatibility_no_module">Why does XStream not even declare an automated module name?</h2>
<p>Such a declaration would move XStream automatically into the module class path. However, in this environment a
lot of functionality does no longer work. Therefore it is on purpose that XStream stays currently in the unnamed
module.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_JPMS">Will XStream support the Java Platform Module System (JPMS)?</h2>
<p>At some point definitely. However, you will have to accept a limited functionality only, comparable to the pure
Java mode. The access model is very restrictive and XStream will no longer be able to marshal all types of the Java
runtime like now.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_XPP">Why is my application not able to create a XmlPullParser with the XppDriver since XStream 1.4?</h2>
<p>The <a href="http://www.xmlpull.org/">XML Pull Parser API</a> defines an own mechanism to load the factory for
the available XPP implementation. XStream's XppDriver never used this lookup mechanism automatically before version
1.4, now it will. Therefore you will have to add a <a href="download.html#optional-deps">dependency to xmlpull</a>
if the XPP implementation does not deliver the classes on its own. This dependency is necessary for Xpp3 in
contrast to kXML2 that contains the classes. Use the Xpp3Driver or the KXml2Driver if you want to select one of the
directly supported XPP implementation on your own without using the XPP factory. Note, that the minimal version of
kXML2 does not support the XPP factory, but can be used by the KXml2Driver.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_Android">Can I use XStream in an Android application?</h2>
<p>XStream does work in Android 1.0, but is reported to have limited capabilities. Since XStream 1.4 Android is
treated at least as JDK 5 platform, but it e.g. does not include the java.beans package. Therefore you cannot use
the JavaBeanConverter. Note, that Android provides an XML Pull Parser, therefore XStream can work without
additional dependencies.</p>
<p>XStream contains class files targeting different Java runtime versions. Depending on the target version of
Android, it is not possible to use the original XStream library directly, because it tries to convert all classes
of XStream to the Dalvik runtime. You might have to build a custom version of XStream (see BUILD.txt) with a JDK
that is equivalent to the Java level supported by the target version of Android.</p>
<p>Since XStream 1.4.10 an additional artifact is deployed to the Central Maven Repository with <em>-java7</em>
appended to the version that explicitly does not contain any Java 8 related stuff. Note that this version will fail
on higher runtimes.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_GAE">Which limits exists for XStream in Google's Application Engine (GAE)?</h2>
<p>Starting with XStream 1.4.6 it is possible to instantiate an XStream instance in a GAE environment. Nevertheless
does GAE set some severe restrictions for XStream and therefore XStream will behave differently. Actually a
reflection-based converter cannot handle any type from the JDK itself. Nor is it possible to create an
ObjectInputStream or an ObjectOutputStream. It is not possible to define a field alias for any type within the JDK.
XStream will typically work as general rule, if you process your own objects.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_Harmony">Why does XStream fail on Apache Harmony?</h2>
<p>Since JDK 5 it is possible according the Java specification to write into final fields using reflection. This is not yet
supported by Harmony and therefore the PureJavaReflectionProvider fails. We have also already investigated into
enhanced mode in Harmony, but the Harmony JVM crashed running the unit tests. However, Harmony has been retired,
we will no longer make any efforts in this direction.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_unsupported_JVM">Are there plans to provide enhanced mode support to other JVMs?</h2>
<p>Yes. <a href="mailing-lists.html">Let us know</a> which JVM you would like supported.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_no_enhanced_mode">When should I use XStream not in enhanced mode?</h2>
<p>Running XStream in a secured environment can prevent XStream from running in enhanced mode. This is
especially true when running XStream in an applet. You may also try to use the JavaBeanConverter as alternative to
the ReflectionConverter running in enhanced or pure Java mode.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_SecurityManager">Which permissions does XStream need when running with an active SecurityManager?</h2>
<p>This depends on the mode XStream is running in. Refer to the
<a href="https://github.com/x-stream/xstream/blob/master/xstream/src/test/com/thoughtworks/acceptance/SecurityManagerTest.java">SecurityManagerTest</a>
for details. Actually XStream's converters try to check since version 1.4.6 any critical operation, before they
claim to be able to handle a type. As consequence XStream can behave differently running under a SecurityManager.
E.g. if the SecurityManager does not permit to create an instance for a derived class of ObjectOutputStream, the
SerializationConverter will not handle any type and the ReflectionConverter will take over (as long it has proper
rights for its own reflection-based operations).</p>
<!-- ...................................................... -->
<h2 id="Compatibility_XStream11">Why does XStream 1.2 no longer read XML generated with XStream 1.1.x?</h2>
<p>The architecture in XStream has slightly changed. Starting with XStream 1.2 the
<a href="javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">HierarchicalStreamDriver</a>
implementation is responsible to ensure that XML tags and attributes are valid names in XML, in XStream 1.1.x
this responsibility was part of the ClassMapper implementations. Under some rare circumstances this will result in
an unreadable XML due to the different processing order in the workflow of such problematic tag names.</p>
<p>You can run XStream in 1.1 compatibility mode though:</p>
<div class="Source Java"><pre>XStream xstream = new XStream(new XppDriver(new XStream11XmlFriendlyReplacer())) {
protected boolean useXStream11XmlFriendlyMapper() {
return true;
}
};</pre></div>
<!-- ...................................................... -->
<h2 id="Compatibility_ConverterAnnotations">XStream 1.3 ignores suddenly annotated converters (@XStreamConverter and @XStreamConverters)?</h2>
<p>XStream treats now all annotations the same and therefore it no longer auto-detects any annotation by
default. You can configure XStream to run in auto-detection mode, but be aware if the
<a href="annotations-tutorial.html#AutoDetect">implications</a>. As alternative you might register the
deprecated AnnotationReflectionConverter, that was used for XStream pre 1.3.x, but as drawback the functionality
to register a local converter with XStream.registerLocalConverter will no longer work.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_element_sequence">XStream 1.3 suddenly has a different field order?</h2>
<p>Yes. This was announced with the last 1.2.x release and was done to support the type inheritance of XML schemas. However, XStream is delivered with the
<a href="javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">XStream12FieldKeySorter</a> that can be used to
<a href="#Serialization_sort_fields">sort the fields</a> according XStream 1.2.2.</p>
<!-- ...................................................... -->
<h2 id="Compatibility_WebSphere_8">WebSphere 8 can no longer use XStream 1.4.x?</h2>
<p>XStream has a long history to support types from recent JDKs without dropping backward compatibility. Therefore it contains class files targeting different JDKs.
However, WebShpere scans by default all JAR files in its classpath for annotations to support CDI independent of the presence of a beans.xml file in META-INF. This
scanning fails for class files targeting a higher JDK runtime as currently used by WebSphere. Please, consult your WebSphere documentation, how to turn off the
scanning for individual files by providing an <a href="http://www-01.ibm.com/support/knowledgecenter/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/trun_app_reduce_annot.html?cp=SSAW57_8.0.0%2F1-8-12-0">amm.filter.proeprties</a>
file.</p>
<!-- ****************************************************** -->
<h1 id="Serialization">Serialization</h1>
<!-- ...................................................... -->
<h2 id="Serialization_types">Which class types can be serialized by XStream?</h2>
<p>In contrast to the JDK XStream is not tied to a marker interface to serialize a class. XStream ships with some specialized <a href="converters.html">converters</a>,
but will use reflection by default for "unknown" classes to examine, read and write the class' data. Therefore XStream can handle quite any class, especially
the ones referred as POJO (Plain Old Java Object).</p>
<p>However, some types of classes exist with typical characteristics, that cannot be handled - at least not out of the box:</p>
<ol>
<li>Objects that are based on threads or thread local data: Thread, Timer, ThreadLocal and so on. These classes keep different data for different threads and there's
no possibility to recreate a thread in a generic way nor recreating thread specific data. There might be special use cases, but this will always involve a custom converter
where threads can be recreated in a specific way tied to that use case.</li>
<li>Class types that are based on generated classes. Such types have often names that are unique to the current process and will have no meaning
in a different process. A custom converter might help to write the appropriate data into the serializing stream to be able to recreate a equivalent class at deserialization
time.</li>
<li>Types that keep and use system resources like file handles, sockets, pipes and so on. ClassLoader, FileInputStream, FileOutputStream, Socket and so on. To
deserialize such a class the converter must be able to claim the appropriate resource from the system again. With the help of a custom converter this might be
possible, but with the reflection converter the deserialized class might refer a system resource that is no longer valid or belongs to somebody else. Behavior is
undefined then.</li>
<li>A very special case of such allocated system resources are those classes that keep handles to system memory directly, because they are partly implemented native.
It is known to be true for the Linux version of Sun's JDK that the BufferedImage references some system specific types of the JDK that themselves have member fields
with such memory handles. While it is possible at first sight to serialize and deserialize a BufferedImage, the reflection converter will also duplicate the memory handle.
As a result the JVM might crash easily because of freeing unallocated memory or freeing the same memory twice. It might be possible to create a custom converter,
but the data structure is really complex in this area and nobody has been investigating so far to such an extent. However, <strong>do not use the reflection converter
for these types! You have been warned!</strong></li>
<li>Inner class types of the JDK can often vary in implementation details between JDK versions and vendors and are therefore only compatible for the same JDK. This
includes collection types returned by the methods of the Collections class that wrap another one (like unmodifiableList) or the collections that are returned by the
different Map implementations for the keySet(), entrySet() and values() methods.</li>
<li><a href="#Serialization_lambda_null">Non-serializable lambda expressions</a> cannot be deserialized at all and <a href="#Serialization_lambda_fails">serializable
lambda</a> expression contain compiler and vendor specific information that might cause deserialization to fail.</li>
</ol>
<!-- ...................................................... -->
<h2 id="Serialization_omit_field">How do I specify that a field should not be serialized?</h2>
<p>Make it <code>transient</code>, specify it with <code>XStream.omitField()</code> or
annotate it with @XStreamOmitField</p>
<!-- ...................................................... -->
<h2 id="Serialization_initialize_transient">How do I initialize a transient field at deserialization?</h2>
<p>XStream uses the same mechanism as the JDK serialization. Example:</p>
<div class="Source Java"><pre>class ThreadAwareComponent {
private transient ThreadLocal component;
// ...
private Object readResolve() {
component = new ThreadLocal();
return this;
}
}</pre></div>
<p>or in case your type implements java.io.Serializable, you have an alternative:</p>
<div class="Source Java"><pre>class ThreadAwareComponent implements Serializable{
private transient ThreadLocal component;
// ...
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
component = new ThreadLocal();
}
}</pre></div>
<p>Use the latter in class hierarchies, readResolve is not called for base classes.</p>
<!-- ...................................................... -->
<h2 id="Serialization_no_ctor_running">XStream is not calling the default constructor during deserialization.</h2>
<p>This is, in fact, the same case as above. XStream uses the same mechanism as the JDK serialization. When using
the enhanced mode with the optimized reflection API, it does not invoke the default constructor. The solution is to
implement the readResolve or readObject as demonstrated with the last question.</p>
<!-- ...................................................... -->
<h2 id="Serialization_collections">What do serialized collections look like?</h2>
<p>See example for the <a href="converters.html#java.util">CollectionConverter</a>.</p>
<p>Note, that it is possible to configure XStream to omit the container element <i>toys</i> using implicit collections.</p>
<!-- ...................................................... -->
<h2 id="Serialization_reflection_types">Why do serialized types, fields or methods do not use aliasing for the names?</h2>
<p>XStream normally has no to separate between a primitive and its boxed type. The complete reflection API works
always with the boxed types and converts to primitives types on the fly. However, for method and field type
signatures the difference is essential. Nevertheless it is possible to register derived versions of the converters
that are able to respect the aliasing with some minor effort. Following lines are taken from the AliasTest in the
acceptance tests:</p>
<div class="Source Java"><pre>XStream xstream = new XStream();
Mapper mapper = new MapperWrapper(xstream.getMapper().lookupMapperOfType(ArrayMapper.class)) {
public Class realClass(String elementName) {
Class primitiveType = Primitives.primitiveType(elementName);
return primitiveType != null ? primitiveType : super.realClass(elementName);
}
};
SingleValueConverter javaClassConverter = new JavaClassConverter(mapper) {};
xstream.registerConverter(javaClassConverter);
xstream.registerConverter(new JavaMethodConverter(javaClassConverter){});
xstream.registerConverter(new JavaFieldConverter(javaClassConverter, mapper){});</pre></div>
<!-- ...................................................... -->
<h2 id="Serialization_implicit_null">My implicit collection is suddenly null after deserialization instead of empty!</h2>
<p>By declaring a collection as implicit, the result will have no direct representation of the collection container
itself anymore. Therefore, if the collection was empty at serialization time, the serialized result does not
contain a trace of the collection anymore. At deserialization time it will therefore not know anything about the
collection and will not initialize it. XStream cannot decide anyway at deserialization time, if the collection was
empty or null.</p>
<!-- ...................................................... -->
<h2 id="Serialization_implicit_different_type">The type of my implicit collection is different after deserialization.</h2>
<p>By declaring a collection as implicit, the result will have no direct representation of the collection container
itself anymore. Therefore XStream cannot track the original type of the collection. At deserialization time it will
therefore look at the declaration type of the field that holds the collection and use this type's default
implementation, e.g. for a List this is by default an ArrayList.</p>
<p>Beware, that this also means that collections with additional information (e.g. a TreeSet with a Comparator)
cannot be restored, since the comparator was already omitted at serialization time.</p>
<!-- ...................................................... -->
<h2 id="Serialization_Serializable">Do my classes have to implement Serializable if XStream is to serialize them?</h2>
<p>No (except for lambda expressions), but XStream respects the Java serialization methods even for types not declared as Serializable.</p>
<!-- ...................................................... -->
<h2 id="Serialization_proxies">Can dynamic proxies be serialized?</h2>
<p>Yes.</p>
<!-- ...................................................... -->
<h2 id="Serialization_referencing_immutable_types">Can immutable types be referenced?</h2>
<p>Adding a type as immutable implies that a referencing marshaller strategy will write each occurrence of the same
instance separately into the stream without referencing it, i.e. instance of those types are normally never referenced
at deserialization time. Such referenced can exist though for persisted streams when a type is added as immutable in
later versions. In such cases the type can be added as immutable, but still referenceable.</p>
<p>Any immutable type could be dereferenced before version 1.4.9, but only at the cost of a large memory footprint.
Since version 1.4.9 this is only possible if the immutable type has been explicitly declared as referenceable too.
This should be done only if backward compatibility is required and a persisted stream may contain a reference of such
an instance at all. Any type that has been declared as immutable by XStream itself before version 1.4 will not be
referenceable now by default (all primitive types and their boxed counterparts, java.lang.Class, java.lang.String,
java.math.BigInteger, java.math.BigDecimal, java.io.File, java.net.URL, and java.awt.font.TextAttribute). All other
immutable types (java.util.Currency, java.util.UUID, java.net.URI, java.nio.charset.Charset and the empty collection
types) will currently still be referenceable at deserialization time for compatibility reasons. This support by
default will be dropped with the next major version of XStream. You can always overwrite the default by adding the same
type again as immutable with a different value for the referenceable flag.</p>
<!-- ...................................................... -->
<h2 id="Serialization_lambda_null">My lambda expression is serialized to null!</h2>
<p>Non-serializable lambda expressions to not contain any information at all to recreate the instance at a later time again. These instances are treated as temporary
objects and as such XStream has no other possibility as to serialize null instead.</p>
<!-- ...................................................... -->
<h2 id="Serialization_lambda_fails">Suddenly the deserialization of my (serializable) lambda expression fails!</h2>
<p>Serializable lambda expressions contain information that is specific for compiler and vendor. Even worse, the compiler is free to add information related to the location
of the lambda expression in the source i.e. you may not be able to deserialize a lambda expression after source code changes. XStream has no control over this information
and how it is used by native functionality in the JDK. Therefore Oracle strongly discourages the usage of serializable lambda expressions in the JDK documentation.</p>
<!-- ...................................................... -->
<h2 id="Serialization_CGLIB">Can CGLIB proxies be serialized?</h2>
<p>Only limitedly. A proxy generated with the CGLIB Enhancer is supported, if the proxy uses either a factory or
only one callback. Then it is possible to recreate the proxy instance at unmarshalling time. Starting with XStream 1.3.1
CGLIB support is no longer automatically installed because of possible classloader problems and side-effects,
because of incompatible ASM versions. You can enable CGLIB support with:</p>
<div class="Source Java"><pre>XStream xstream = new XStream() {
protected MapperWrapper wrapMapper(MapperWrapper next) {
return new CGLIBMapper(next);
}
};
xstream.registerConverter(new CGLIBEnhancedConverter(xstream.getMapper(), xstream.getReflectionProvider()));
</pre></div>
<!-- ...................................................... -->
<h2 id="Serialization_CGLIB_ExceptionInInitializerError">CGLIBEnhancedConverter fails at initialization with ExceptionInInitializerError</h2>
<p>This is not a problem of XStream. You have incompatible ASM versions in your classpath. CGLIB 2.1.x and below is based on
ASM 1.5.x which is incompatible to newer versions that are used by common packages like Hibernate, Groovy or Guice. Check
your dependencies and ensure that you are using either using cglib-nodep-2.x.jar instead of cglib-2.x.jar or update to
cglib-2.2.x that depends on ASM 3.1. However, the <em>nodep</em> version contains a copy of the ASM classes with private
packages and will therefore not raise class incompatibilities at all.</p>
<!-- ...................................................... -->
<h2 id="Serialization_CGLIB_2.0.1">Serialization fails with NoSuchMethodError: net.sf.cglib.proxy.Enhancer.isEnhanced(Ljava/lang/Class;)Z</h2>
<p>XStream uses this method to detect a CGLIB-enhanced proxy. Unfortunately the method is not available in the
cglib-2.0 version. Since this version is many years old and the method is available starting with cglib-2.0.1, please
consider an upgrade of the dependency, it works usually smoothly.</p>
<!-- ...................................................... -->
<h2 id="Serialization_Hibernate">How do I use XStream's Hibernate package to serialize my objects?</h2>
<p>Support of Hibernate enhanced collections and proxied types. To drop the internals of Hibernate when marshalling
such objects to XStream, all converters and the mapper has to be registered for the XStream instance:</p>
<div class="Source Java"><pre>final XStream xstream = new XStream() {
protected MapperWrapper wrapMapper(final MapperWrapper next) {
return new HibernateMapper(next);
}
};
xstream.registerConverter(new HibernateProxyConverter());
xstream.registerConverter(new HibernatePersistentCollectionConverter(xstream.getMapper()));
xstream.registerConverter(new HibernatePersistentMapConverter(xstream.getMapper()));
xstream.registerConverter(new HibernatePersistentSortedMapConverter(xstream.getMapper()));
xstream.registerConverter(new HibernatePersistentSortedSetConverter(xstream.getMapper()));
</pre></div>
<!-- ...................................................... -->
<h2 id="Serialization_Hibernate_Envers">Does XStream's Hibernate package support Envers?</h2>
<p>Yes. Hibernate Envers is an optional dependency for XStream and it is automatically supported by XStream's
Hibernate package when the proxy collection types of Envers are available on the classpath.</p>
<!-- ...................................................... -->
<h2 id="Serialization_system_attributes">My attributes are interpreted by XStream itself and cause unexpected behavior</h2>
<p>XStream's generic converters and the marshalling strategies use a number of attributes on their own. Especially the attributes named
<em>id</em>, <em>class</em> and <em>reference</em> are likely to cause such collisions. Main reason is XStream's history, because
originally user defined attributes were not supported and all attribute were system generated. Starting with XStream 1.3.1 you can redefine
those attributes to allow the names to be used for your own ones. The following snippet defines XStream to use different system attributes
for <em>id</em> and <em>class</em> while the field <em>id</em> of YourClass is written into the attribute <em>class</em>:</p>
<div class="Source Java"><pre>XStream xstream = new XStream() {
xstream.useAttributeFor(YourClass.class, "id");
xstream.aliasAttribute("class", "id");
xstream.aliasSystemAttribute("type", "class");
xstream.aliasSystemAttribute("refid", "id");
</pre></div>
<!-- ...................................................... -->
<h2 id="Serialization_sort_fields">Can I select the field order in which XStream serializes objects?</h2>
<p>Yes. XStream's ReflectionConverter uses the defined field order by default. You can override it by using an specific FieldKeySorter:</p>
<div class="Source Java"><pre>SortableFieldKeySorter sorter = new SortableFieldKeySorter();
sorter.registerFieldOrder(MyType.class, new String[] { "firstToSerialize", "secondToSerialize", "thirdToSerialize" });
xstream = new XStream(new Sun14ReflectionProvider(new FieldDictionary(sorter)));
</pre></div>
<!-- ...................................................... -->
<h2 id="Serialization_newer_class_versions">How does XStream deal with newer versions of classes?</h2>
<ul>
<li>If a new field is added to the class, deserializing an old version will leave the field uninitialized.</li>
<li>If a field is removed from the class, deserializing an old version that contains the field will cause an exception.
Leaving the field in place but declaring it as transient will avoid the exception, but XStream will not try to deserialize it.</li>
<li>If a class is renamed, aliases can be used to create an abstraction between the name used in XML and the real class name.</li>
<li>If a field is renamed, this should be treated as adding a field and removing a field.</li>
</ul>
<p>For more advanced class migrations, you may</p>
<ul>
<li>have to do custom pre-processing of the XML before sending it to XStream (for example, with XSLT or DOM manipulations)</li>
<li>declare new fields as transient</li>
<li>implement your own converter, that can handle the situation</li>
<li>add a readResolve() method to your class, that initializes the object accordingly</li>
<li>implement a custom mapper to ignore unknown fields automatically
(see acceptance test CustomMapperTest.testCanBeUsedToOmitUnexpectedElements())</li>
</ul>
<p>Future versions of XStream will include features to make these type of migrations easier.</p>
<!-- ...................................................... -->
<h2 id="Serialization_classloader">How does XStream cope with isolated class loaders?</h2>
<p>Serializing an object graph is never a problem, even if the classes of those objects have been loaded by
a different class loader. The situation changes completely at deserialization time. In this case you must set the
class loader to use with:</p>
<div class="Source Java"><pre>xstream.setClassLoader(yourClassLoader);</pre></div>
<p>Although XStream caches a lot of type related information to gain speed, it keeps those information in
tables with weak references that should be cleaned by the garbage collector when the class loader is freed.</p>
<p>Note, that this call should be made quite immediately after creating the XStream and before any other
configuration is done. Otherwise configuration based on special types might refer classes loaded with the wrong
classloader.</p>
<!-- ****************************************************** -->
<h1 id="XML">XML specifics</h1>
<!-- ...................................................... -->
<h2 id="XML_respect_encoding">Why does XStream not respect the encoding in the XML declaration?</h2>
<p>XStream architecture is based on IO Readers and Writers, while the XML declaration is the responsibility of XML
parsers. All <a href="javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">HierarchicalStreamDriver</a>
implementations respect the encoding since version 1.3, but only if you provide an
<a href="http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html">InputStream</a>. If XStream consumes a
<a href="http://docs.oracle.com/javase/7/docs/api/java/io/Reader.html">Reader</a> you have to initialize the reader with
the appropriate encoding yourself, since it is now the reader's task to perform the encoding and no XML parser can
change the encoding of a Reader and any encoding definition in the XML header will be ignored.</p>
<!-- ...................................................... -->
<h2 id="XML_write_XML_declaration">Why does XStream not write an XML declaration?</h2>
<p>XStream is designed to write XML snippets, so you can embed its output into an existing stream or string.
You can write the XML declaration yourself into the Writer before using it to call XStream.toXML(writer).</p>
<!-- ...................................................... -->
<h2 id="XML_write_UTF8">Why does XStream not write XML in UTF-8?</h2>
<p>XStream does no character encoding by itself, it relies on the configuration of the underlying XML writer.
By default it uses its own PrettyPrintWriter which writes into the default encoding of the current locale. To write
UTF-8 you have to provide a <a href="http://docs.oracle.com/javase/7/docs/api/java/io/Writer.html">Writer</a>
with the appropriate encoding yourself.</p>
<!-- ...................................................... -->
<h2 id="XML_double_underscores">Why do field names suddenly have double underscores in the generated XML?</h2>
<p>XStream maps Java class names and field names to XML tags or attributes. Unfortunately this mapping cannot
be 1:1, since some characters used for <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8">
identifiers in Java</a> are invalid in <a href="http://www.w3.org/TR/REC-xml/#dt-name">XML names</a>. Therefore
XStream uses an <a href="javadoc/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.html">XmlFriendlyNameCoder</a>
to replace these characters with a replacement. By default this
<a href="javadoc/com/thoughtworks/xstream/io/naming/NameCoder.html">NameCoder</a> uses an underscore as escape
character and has therefore to escape the underscore itself also. You may provide a different configured instance
of the XmlFriendlyNameCoder or a complete different implementation like the
<a href="javadoc/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.html">NoNameCoder</a> to prevent name coding
at all. However it is your responsibility then to ensure, that the resulting names are valid for XML.</p>
<!-- ...................................................... -->
<h2 id="XML_unmarshalling_fails">XStream fails to unmarshal my given XML and I do not know why?</h2>
<p>By default XStream is written for persistence i.e. it will read the XML it can write. If you have to transform
a given XML into an object graph, you should go the other way round. Use XStream to transfer your objects into XML.
If the written XML matches your schema, XStream is also able to read it. This way is much easier, since you can
spot the differences in the XML much more easy than to interpret the exceptions XStream will throw if it cannot
match the XML into your objects.</p>
<!-- ...................................................... -->
<h2 id="XML_null_char">My parser claims the &#x0; character to be invalid, but it was written with XStream!</h2>
<p>Your parser is basically right! A character of value 0 is not valid as part of XML according the XML specification (see
version <a href="http://www.w3.org/TR/2006/REC-xml-20060816/#charsets">1.0</a> or
<a href="http://www.w3.org/TR/2006/REC-xml11-20060816/#charsets">1.1</a>), neither directly nor as character
entity nor within CDATA. But not every parser respects this part of the specification (e.g. Xpp3 will ignore it and read
character entities). If you expect such characters in your strings and you do not use the Xpp3 parser, you should consider
to use a converter that writes the string as byte array in Base64 code. As alternative you may force the
<a href="javadoc/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.html">PrettyPrintWriter</a> or derived writers
to be XML 1.0 or 1.1. compliant, i.e. in this mode a StreamException is thrown.</p>
<!-- ...................................................... -->
<h2 id="XML_control_char">My parser claims a control character to be invalid, but it was written with XStream!</h2>
<p>Your parser is probably right! Control characters are only valid as part of XML 1.1. You should add an XML header
declaring this version or use a parser that does not care about this part of the specification (e.g. Xpp3 parser).</p>
<!-- ...................................................... -->
<h2 id="XML_attributes">Why is my element not written as XML attribute although I have configured it?</h2>
<p>You can only write types as attributes that are represented as a single String value and are handled therefore
by SingleValueConverter implementations. If your type is handled by a Converter implementation, the configuration
of XStream to write an attribute (using XStream.useAttributeFor() or @XStreamAsAttribute) is simply ignored.</p>
<!-- ...................................................... -->
<h2 id="XML_attribute_normalization">Why are whitespace characters wrong in my attribute values after deserialization?</h2>
<p>This is part of the XML specification and a required functionality for any XML parser called
<a href="http://www.w3.org/TR/2006/REC-xml-20060816/#AVNormalize">attribute value normalization</a>. It cannot
be influenced by XStream. A compliant XML parser will replace by default real tab, carriage return and line feed
characters with normal spaces. If you want to keep these characters you will have to encode them with entities.</p>
<!-- ...................................................... -->
<h2 id="XML_namespaces">Why does XStream not have any namespace support?</h2>
<p>Not every XML parser supports namespaces and not every XML parser that supports namespaces can be configured
within XStream to use those. Basically namespaces must be supported individually for the different XML parsers and the
only support for namespaces that has currently been implemented in XStream is for the StAX paser. Therefore use and
configure the StaxDriver of XStream to use namespaces.</p>
<!-- ...................................................... -->
<h2 id="XML_xpath_limits">My XML contains XPath expressions in the references, but they seem not to work?</h2>
<p>XStream generates only XPath compliant expressions. These have a very limited syntax and they are the only ones
that can be interpreted at deserialization again, since XStream does not use an XPath interpreter. Therefore there
is no support for attribute selectors, qualified element access with axis names or functions. For real XPath
support you will have to implement your own MarshallingStrategy.</p>
<!-- ...................................................... -->
<h2 id="XML_xpath_nodelist">The XPath expressions in the references do select a list, but not a single node!</h2>
<p>Yes, this is right. However, the result type of an
<a href="http://docs.oracle.com/javase/7/docs/api/javax/xml/xpath/XPathExpression.html">XPath expression</a>
evaluation can be defined. A node result from a node list is the lists first node, therefore the XPath of XStream
is compliant. Since XStream does not use a real XPath engine, you do not have to worry about memory consumption or
wasted evaluation time, XStream will always operate on a single node anyway. Since XStream 1.4 you can force
XStream to write XPath expressions that select explicit the single node by using the new modes
XStream.SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES or SINGLE_NODE_XPATH_RELATIVE_REFERENCES. Instead of generating a
path like "/doc/list/elem/field" XStream will then generate "/doc[1]/list[1]/elem[1]/field[1]". The two notations
are transparent at deserialization time.</p>
<!-- ...................................................... -->
<h2 id="XML_entities">Does XStream support entities?</h2>
<p>Entity support is completely dependent on the XML parser. XStream uses by default the Xpp3 parser that does not
support entities at all (like the kXML2 parser). Other parsers support entities, but they might have been turned
off to avoid <a href="#Security_XXEVulnerability">XXE vulnerability</a>. To enable the entities again, you have to
overload the individual method of the
<a href="javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">HierarchicalStreamDriver</a>
implementation that generated the parser factory.</p>
<!-- ****************************************************** -->
<h1 id="JSON">JSON specifics</h1>
<!-- ...................................................... -->
<h2 id="JSON_2_drivers">Why are there two JSON driver implementations?</h2>
<p>As always, first for historical reasons! Main difference is that the
<a href="javadoc/com/thoughtworks/xstream/io/json/JettisonMappedXmlDriver.html">JettisonMappedXmlDriver</a> is a
thin wrapper around <a href="https://github.com/jettison-json">Jettison</a> in combination with the
<a href="javadoc/com/thoughtworks/xstream/io/xml/StaxDriver.html">StaxDriver</a>, while the
<a href="javadoc/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamDriver.html">JsonHierarchicalStreamDriver</a>
uses an own more flexible implementation, but can only be used to generate JSON, deserialization is not implemented.</p>
<!-- ...................................................... -->
<h2 id="JSON_Jettison_version">Which versions of Jettison are supported?</h2>
<p>Users of Java 5 or higher can use Jettison 1.2, users of Java 1.4.2 have to use Jettison 1.0.1. Jettison 1.1
nor Jettison 1.3 or higher is supported.</p>
<!-- ...................................................... -->
<h2 id="JSON_deserialize_top_level_array">Why is it not possible to deserialize a JSON string starting with an array?</h2>
<p>XStream's implementation to deserialize JSON is based on Jettison and StAX. Jettison implements a XMLStreamReader
of StaX and transforms the processed JSON virtually into XML first. However, if the JSON string starts with an array it is not
possible for Jettison to create a valid root element, since it has no name.</p>
<!-- ...................................................... -->
<h2 id="JSON_unmarshalling_fails">XStream fails to unmarshal my JSON string and I do not know why?</h2>
<p>Deserialization of JSON is currently done by Jettison, that transforms the JSON string into a StAX stream.
XStream itself does nothing know about the JSON format here. If your JSON string reaches some kind of
complexity and you do not know how to design your Java objects and configure XStream to match those,
you should have a look at the intermediate XML that is processed by XStream in the end. This might help to
identify the problematic spots. Also consider then <a href="#XML_unmarshalling_fails">marshalling your Java
objects into XML first</a>. You can use following code to generate the XML:</p>
<div class="Source Java"><pre>String json = "{\"string\": \"foo\"}";
HierarchicalStreamDriver driver = new JettisonMappedXmlDriver();
StringReader reader = new StringReader(json);
HierarchicalStreamReader hsr = driver.createReader(reader);
StringWriter writer = new StringWriter();
new HierarchicalStreamCopier().copy(hsr, new PrettyPrintWriter(writer));
writer.close();
System.out.println(writer.toString());
</pre></div>
<!-- ...................................................... -->
<h2 id="JSON_limitations">What limitations has XStream's JSON support?</h2>
<p>JSON represents a very simple data model for easy data transfer. Especially it has no equivalent for XML
attributes. Those are written with a leading "@" character, but this is not always possible without
violating the syntax (e.g. for array types). Those may silently dropped (and makes it therefore difficult to
implement deserialization). References are another issue in the serialized object graph, since JSON has no
possibility to express such a construct. You should therefore always set the NO_REFERENCES mode of XStream.
Additionally you cannot use implicit collections, since the properties in a JSON object must have unique names.</p>
<!-- ...................................................... -->
<h2 id="JSON_JavaScript_Long">Why are my Long values incorrect in JavaScript?</h2>
<p>JavaScript does not know about integer values. All numbers are represented with double precition floats using
64 bits (IEEE 754). These types cannot represent technically the complete value range of 64-bit integers like
Java's Long. With the JsonWriter you have the possibility since XStream 1.4.5 to set
<a href="javadoc/com/thoughtworks/xstream/io/json/AbstractJsonWriter.html#IEEE_754_MODE">IEEE_754_MODE</a> to force
any long value that is not representable as JavaScript number to be written as string value in JSON. With the
Jettison-based JettisonMappedXmlDriver you may either set a different TypeConverter or force the default converter
to write integer values out of the range of 32-bit always as string setting the system property
<strong>jettison.mapped.typeconverter.enforce_32bit_integer</strong> to <strong>true</strong> (not available for
Jettison 1.0.1 and Java 1.4).</p>
<!-- ...................................................... -->
<h2 id="JSON_encoding">Why are there invalid characters in my JSON representation?</h2>
<p>The JSON spec requires any JSON string to be in UTF-8 encoding. However, XStream ensures this only if you
provide an InputStream or an OutputStream. If you provide a Reader or Writer you have to ensure this requirement
on your own.</p>
<!-- ...................................................... -->
<h2 id="JSON_dashes">The generated JSON is invalid, it contains a dash in the label!</h2>
<p>Well, no, the JSON is valid! Please check yourself with the <a href="http://www.jslint.com/">JSON syntax checker</a>.
However, some JavaScript libraries silently assume that the JSON labels are valid JavaScript identifiers, because JavaScript
supports a convenient way to address an element, <strong>if</strong> the label is a valid JavaScript identifier:</p>
<div class="Source JavaScript"><pre>var json = {"label": "foo", "label-with-dash": "bar"};
var fooVar = json.label; // works for labels that are JavaScript identifiers
var barVar = json["label-with-dash"]; // using an array index works always
</pre></div>
<p>As alternative you may wrap the JsonWriter and replace any dash with an underscore:</p>
<div class="Source Java"><pre>HierarchicalStreamDriver driver = new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new WriterWrapper(super.createWriter(out)) {
public void startNode(String name) {
startNode(name, null);
}
public void startNode(String name, Class clazz) {
wrapped.startNode(name.replace('-', '_'), clazz);
}
}
}
};
XStream xstream = new XStream(driver);
</pre></div>
<!-- ****************************************************** -->
<h1 id="Security">Security Aspects</h1>
<!-- ...................................................... -->
<h2 id="Security_EventHandler">Why does XStream not convert an java.beans.EventHandler?</h2>
<p>Since XStream version 1.4.7 it does no longer handle an
<a href="http://docs.oracle.com/javase/7/docs/api/java/beans/EventHandler.html">EventHandler</a> automatically.
Such an instance can be used to initiate calls on arbitrary instances at deserialization time e.g.
<a href="http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#start()">ProcessBuilder.start()</a>
You can register a ReflectionConverter instance explicitly for the EventHandler if you need support for such
instances.</p>
<!-- ...................................................... -->
<h2 id="Security_ArbitraryDeserialization">XStream deserializes arbitrary objects!</h2>
<p>Yes, XStream is designed to convert any object form Java to XML and back out of the box. In consequence it is
possible to adjust the processed XML manually to inject arbitrary objects into the deserialized object graph. To
avoid such a behavior, you have several options:</p>
<ul>
<li>Prevent the usage of the reflection-based converters. Register an own converter with priority LOW that claims
to handle any type and throw a ConversionException in the marshal and unmarshal methods.</li>
<li>Overload XStream.setupConverters() and register only converters for the types that are allowed in your object
graph.</li>
<li>Provide own implementations for ConverterLookup and ConverterRegistry constructing the XStream. Your
implementation can then select the appropriate converter at lookup time on its own or prevent the registration of
specific converters.</li>
<li>Since XStream 1.4.7 you have the possibility to <a href="security.html">setup rules</a> for the class types
that are allowed to be deserialized.</li>
</ul>
<!-- ...................................................... -->
<h2 id="Security_VulnerabilityWarning">XStream suddenly emits a vulnerability warning!</h2>
<p>If the security framework has not been initialized, XStream will emit such a warning since version 1.4.10. You
use the <a href="security.html">security rules</a> to setup a white list of class types that will be processed.</p>
<p>For XStream 1.4.x you may call the setupDefaultSecurity method to initialize a XStream instance in the same way
as it will be done for XStream 1.5.x. This means also a compatibility preparation for XStream 1.5.x.</p>
<!-- ...................................................... -->
<h2 id="Security_XXEVulnerability">Is XStream XXE vulnerable (CVE-2016-3674)?</h2>
<p>XStream does not contain an own XML parser, therefore it depends on the parser selected with the
<a href="javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">HierarchicalStreamDriver</a>
if the current XStream instance is <a href="https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing">
XXE vulnerable</a> at deserialization time. However, XStream tries to deactivate the processing of external
entities by default. Status for the different supported XML parsers:</p>
<table summary="Comparison of drivers regarding XEE vulnerability">
<tr><th>Driver</th><th>Vulnerable</th><th>Explanation</th></tr>
<tr><td>BEAStaxDriver</td><td>yes</td><td>Setting <code>XMLInputFactory.setProperty(
XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false)</code> is only respected for general entities, but not
for parameter entities.</td></tr>
<tr><td>Dom4JDriver</td><td>no</td><td>Driver turns off DOCTYPE processing to suppress handling of external
entities with SAX reader in use.</td></tr>
<tr><td>DomDriver</td><td>no, Java 6 or higher<br/>yes, Java 5</td><td>Driver turns off DOCTYPE processing with
Java 7 runtime or higher to suppress handling of external entities with SAX reader in use. Suppress external
entities only for Java 6 or lower, fails for parameterized entities.</td></tr>
<tr><td>JDomDriver</td><td>no</td><td>Driver turns off DOCTYPE processing to suppress handling of external
entities with SAX reader in use.</td></tr>
<tr><td>JDom2Driver</td><td>no</td><td>Driver turns off DOCTYPE processing to suppress handling of external
entities with SAX reader in use.</td></tr>
<tr><td>KXml2DomDriver</td><td>no</td><td>kXML2 parser does not support entities.</td></tr>
<tr><td>KXml2Driver</td><td>no</td><td>kXML2 parser does not support entities.</td></tr>
<tr><td>SjsxpDriver</td><td>no, Java 7 or higher<br/>yes, Java 6</td><td>Driver turns off support for external
entities for the internal StaX parser of the Sun JDK, but fails for parameter entities in a Java 6 runtime.</td></tr>
<tr><td>StandardStaxDriver</td><td>?</td><td>Driver tries to turn off support for external entities for
the internal StaX parser of the Java runtime. Save for Oracle JDK 7 or higher.</td></tr>
<tr><td>StaxDriver</td><td>?</td><td>Driver tries to turns off support for external entities for the
standard StaX parser. However, the finally used StAX implementation is defined externally (see JDK
documentation) and a test should be made on the target platform to ensure that the parser respects the setting.</td></tr>
<tr><td>WstxDriver</td><td>no</td><td>Driver turns off support for external entities for the Woodstox StAX
parser.</td></tr>
<tr><td>XomDriver</td><td>yes</td><td>XOM uses an internal list to test for available SAX parsers on the
classpath and will explicitly enable external entities, even if the SAXBuilder instance is provided manually.</td></tr>
</table>
<p class="highlight">Note: Only a HierarchicalStreamReader created with the HierarchicalStreamDriver is setup to
avoid the XXE vulnerability. If you create such driver instances on your own, it is also your task to setup the XML
parser instance properly.</p>
<!-- ****************************************************** -->
<h1 id="Other_Products">Comparison to other products</h1>
<!-- ...................................................... -->
<h2 id="Other_Products_XMLBeanEncoder">How does XStream compare to java.beans.XMLEncoder?</h2>
<p>XStream is designed for serializing <i>objects</i> using internal fields, whereas
<a href="http://docs.oracle.com/javase/7/docs/api/java/beans/XMLEncoder.html">XMLEncoder</a> is designed for
serializing <i>JavaBeans</i> using public API methods (typically in the form
of <code>getXXX()</code>, <code>setXXX()</code>, <code>addXXX()</code> and <code>removeXXX()</code> methods.</p>
<h2 id="Other_Products_JAXB">How does XStream compare to JAXB (Java API for XML Binding)?</h2>
<p>JAXB is a Java binding tool. It generates Java code from a schema and you are able to transform from those classes into
XML matching the processed schema and back. Note, that you cannot use your own objects, you have to use what is
generated.</p>
<!-- ****************************************************** -->
<h1 id="Scalability">Scalability</h1>
<!-- ...................................................... -->
<h2 id="Scalability_Thread_safety">Is XStream thread safe?</h2>
<p>Yes. Once the XStream instance has been created and configured, it may be shared across multiple threads
allowing objects to be serialized/deserialized concurrently (unless you enable the
<a href="annotations-tutorial.html#AutoDetect">auto-detection</a> to process annotations on-the-fly). Actually the
creation and initialization of XStream is quite expensive, therefore it is recommended to keep the XStream instance
itself. If you absolutely have to rely on annotation processing on the fly, you will have to use separate XStream
instances for each thread - either by using every time a new instance or by a shared pool.</p>
<!-- ...................................................... -->
<h2 id="Scalability_Memory">How much memory does XStream consume?</h2>
<p>This cannot be answered in general, but following topics have impact on the memory:</p>
<ol>
<li>XML parser technology in use: You should use a streaming parser like Xpp3 or StAX. DOM-based
parsers process the complete XML and create their document model in memory before the first converter of XStream
is called.</li>
<li>Your object model: Is it necessary to keep the complete object graph in memory at once? As alternative you might
use <a href="objectstream.html">object streams</a> or write custom converters that can load and save objects of your
object model on the fly without adding them to the object graph physically. As example see the implementation of the
<a href="javadoc/com/thoughtworks/xstream/persistence/XmlArrayList.html">XmlArrayList</a> in combination with the
<a href="javadoc/com/thoughtworks/xstream/persistence/FileStreamStrategy.html">FileStreamStrategy</a> from
XStream's persistence package to keep parts of the object graph separate.</li>
<li>References: By default XStream supports references to the same object in an object graph. This implies that XStream
keeps track of all serialized and deserialized objects internally. These references are kept with WeakReferences, so that the
memory can be freed as soon as nobody references these objects anymore.</li>
<li>XML values: Any tag and attribute value that is converted into a Java String in the object graph will use by default the
same String instance unless it exceeds 38 characters (length of a UUID string representation).</li>
<li>XStream caches: To increase performance XStream caches quite a lot like classes, converters to use, aliasing, tag names.
All those caches make usage of WeakReferences or will exist only while marshalling one object graph resp. unmarshalling one
input stream.</li>
</ol>
<!-- ...................................................... -->
<h2 id="Scalability_Performance">Can the performance of XStream be increased?</h2>
<p>XStream is a generalizing library, it inspects and handles your types on the fly. Therefore it will normally be slower than
a piece of optimized Java code generated out of a schema. However, it is possible to increase the performance anyway:</p>
<ul>
<li>Write custom converters for those of your types that occur very often in your XML.</li>
<li>Keep a configured XStream instance for multiple usage. Creation and initialization is quite expensive compared to the
overhead of XStream when calling marshall or unmarshal.</li>
<li>Use Xpp3 or StAX parsers.</li>
</ul>
<p>Note, you should never try to optimize code for performance simply because you <strong>believe</strong> that you
have detected a bottle neck. Always use proper tools like a profiler to verify where your hotspots are and whether your
optimization was really successful or not.</p>
<!-- ****************************************************** -->
<h1 id="Uses">Uses of XStream</h1>
<!-- ...................................................... -->
<h2 id="Uses_Data_Binding">Is XStream a data binding tool?</h2>
<p>No. It is a serialization tool.</p>
<!-- ...................................................... -->
<h2 id="Uses_Generate_Code">Can XStream generate classes from XSD?</h2>
<p>No. For this kind of work data binding tools such as JAXB or <a href="http://xmlbeans.apache.org">XMLBeans</a> are
appropriate.</p>
<!-- ...................................................... -->
<h2 id="Uses_No_SAX_Reader">Why is there no SaxReader?</h2>
<p>XStream works on a stream-based parser model, while SAX is event-based. The stream based model implies, that the
caller consumes the individual tokens from the XML parser on demand, while in an event-based model the parser
controls the application flow on its own and will use callbacks to support client processing. The different
architecture makes it therefore impossible for XStream to use an event-driven XML parser.</p>
<br/>
</div>
</div>
<div class="SidePanel" id="left">
<div class="MenuGroup">
<h1>Software</h1>
<ul>
<li><a href="index.html">About XStream</a></li>
<li><a href="news.html">News</a></li>
<li><a href="changes.html">Change History</a></li>
<li><a href="security.html">Security Aspects</a></li>
<li><a href="versioning.html">About Versioning</a></li>
</ul>
</div>
<div class="MenuGroup">
<h1>Evaluating XStream</h1>
<ul>
<li><a href="tutorial.html">Two Minute Tutorial</a></li>
<li><a href="license.html">License</a></li>
<li><a href="download.html">Download</a></li>
<li><a href="references.html">References</a></li>
<li><a href="benchmarks.html">Benchmarks</a></li>
<li><a href="https://www.openhub.net/p/xstream">Code Statistics</a></li>
</ul>
</div>
<div class="MenuGroup">
<h1>Using XStream</h1>
<ul>
<li><a href="architecture.html">Architecture Overview</a></li>
<li><a href="graphs.html">Object references</a></li>
<li><a href="manual-tweaking-output.html">Tweaking the Output</a></li>
<li><a href="converters.html">Converters</a></li>
<li class="currentLink">Frequently Asked Questions</li>
<li><a href="mailing-lists.html">Mailing Lists</a></li>
<li><a href="issues.html">Reporting Issues</a></li>
</ul>
</div>
<div class="MenuGroup">
<h1>Javadoc</h1>
<ul>
<li><a href="javadoc/index.html">XStream Core</a></li>
<li><a href="hibernate-javadoc/index.html">Hibernate Extensions</a></li>
<li><a href="jmh-javadoc/index.html">JMH Module</a></li>
</ul>
</div>
<div class="MenuGroup">
<h1>Tutorials</h1>
<ul>
<li><a href="tutorial.html">Two Minute Tutorial</a></li>
<li><a href="alias-tutorial.html">Alias Tutorial</a></li>
<li><a href="annotations-tutorial.html">Annotations Tutorial</a></li>
<li><a href="converter-tutorial.html">Converter Tutorial</a></li>
<li><a href="objectstream.html">Object Streams Tutorial</a></li>
<li><a href="persistence-tutorial.html">Persistence API Tutorial</a></li>
<li><a href="json-tutorial.html">JSON Tutorial</a></li>
<li><a href="http://www.studytrails.com/java/xml/xstream/xstream-introduction.jsp">StudyTrails</a></li>
</ul>
</div>
<div class="MenuGroup">
<h1>Developing XStream</h1>
<ul>
<li><a href="how-to-contribute.html">How to Contribute</a></li>
<li><a href="team.html">Development Team</a></li>
<li><a href="repository.html">Source Repository</a></li>
<li><a href="https://travis-ci.org/x-stream/xstream/branches">Continuous Integration</a></li>
</ul>
</div>