1/*
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 8009579
27 * @summary The initCause() incorrectly initialise the cause in
28 * XPathException class when used with XPathException(String)
29 * constructor.
30 * @run main XPathExceptionInitCause
31 * @author aleksej.efimov@oracle.com
32 */
33
34import javax.xml.xpath.XPathException;
35import java.io.ByteArrayOutputStream;
36import java.io.ByteArrayInputStream;
37import java.io.ObjectOutputStream;
38import java.io.ObjectInputStream;
39import java.io.IOException;
40import java.io.InvalidClassException;
41
42
43public class XPathExceptionInitCause {
44
45    /* This is a serial form of XPathException with two causes serialized
46     * by JDK7 code:
47     *
48     *  ByteArrayOutputStream fser = new ByteArrayOutputStream();
49     *  ObjectOutputStream oos = new ObjectOutputStream(fser);
50     *  oos.writeObject(new XPathException(new Exception()).initCause(null));
51     *  oos.close();
52     */
53    static final byte [] TWOCAUSES = {-84,-19,0,5,115,114,0,30,106,97,118,97,120,46,120,
54        109,108,46,120,112,97,116,104,46,88,80,97,116,104,69,120,99,101,112,116,
55        105,111,110,-26,-127,97,60,-120,119,127,28,2,0,1,76,0,5,99,97,117,115,101,
56        116,0,21,76,106,97,118,97,47,108,97,110,103,47,84,104,114,111,119,97,98,
57        108,101,59,120,114,0,19,106,97,118,97,46,108,97,110,103,46,69,120,99,101,
58        112,116,105,111,110,-48,-3,31,62,26,59,28,-60,2,0,0,120,114,0,19,106,97,
59        118,97,46,108,97,110,103,46,84,104,114,111,119,97,98,108,101,-43,-58,53,
60        39,57,119,-72,-53,3,0,4,76,0,5,99,97,117,115,101,113,0,126,0,1,76,0,13,
61        100,101,116,97,105,108,77,101,115,115,97,103,101,116,0,18,76,106,97,118,
62        97,47,108,97,110,103,47,83,116,114,105,110,103,59,91,0,10,115,116,97,99,
63        107,84,114,97,99,101,116,0,30,91,76,106,97,118,97,47,108,97,110,103,47,83,
64        116,97,99,107,84,114,97,99,101,69,108,101,109,101,110,116,59,76,0,20,115,
65        117,112,112,114,101,115,115,101,100,69,120,99,101,112,116,105,111,110,115,
66        116,0,16,76,106,97,118,97,47,117,116,105,108,47,76,105,115,116,59,120,112,
67        112,112,117,114,0,30,91,76,106,97,118,97,46,108,97,110,103,46,83,116,97,99,
68        107,84,114,97,99,101,69,108,101,109,101,110,116,59,2,70,42,60,60,-3,34,57,
69        2,0,0,120,112,0,0,0,1,115,114,0,27,106,97,118,97,46,108,97,110,103,46,83,
70        116,97,99,107,84,114,97,99,101,69,108,101,109,101,110,116,97,9,-59,-102,
71        38,54,-35,-123,2,0,4,73,0,10,108,105,110,101,78,117,109,98,101,114,76,0,
72        14,100,101,99,108,97,114,105,110,103,67,108,97,115,115,113,0,126,0,4,76,
73        0,8,102,105,108,101,78,97,109,101,113,0,126,0,4,76,0,10,109,101,116,104,
74        111,100,78,97,109,101,113,0,126,0,4,120,112,0,0,0,31,116,0,23,88,80,97,116,
75        104,69,120,99,101,112,116,105,111,110,83,101,114,105,97,108,105,122,101,
76        116,0,28,88,80,97,116,104,69,120,99,101,112,116,105,111,110,83,101,114,105,
77        97,108,105,122,101,46,106,97,118,97,116,0,4,109,97,105,110,115,114,0,38,
78        106,97,118,97,46,117,116,105,108,46,67,111,108,108,101,99,116,105,111,110,
79        115,36,85,110,109,111,100,105,102,105,97,98,108,101,76,105,115,116,-4,15,
80        37,49,-75,-20,-114,16,2,0,1,76,0,4,108,105,115,116,113,0,126,0,6,120,114,
81        0,44,106,97,118,97,46,117,116,105,108,46,67,111,108,108,101,99,116,105,111,
82        110,115,36,85,110,109,111,100,105,102,105,97,98,108,101,67,111,108,108,101,
83        99,116,105,111,110,25,66,0,-128,-53,94,-9,30,2,0,1,76,0,1,99,116,0,22,76,
84        106,97,118,97,47,117,116,105,108,47,67,111,108,108,101,99,116,105,111,110,
85        59,120,112,115,114,0,19,106,97,118,97,46,117,116,105,108,46,65,114,114,97,
86        121,76,105,115,116,120,-127,-46,29,-103,-57,97,-99,3,0,1,73,0,4,115,105,
87        122,101,120,112,0,0,0,0,119,4,0,0,0,0,120,113,0,126,0,20,120,115,113,0,126,
88        0,2,113,0,126,0,21,112,117,113,0,126,0,8,0,0,0,1,115,113,0,126,0,10,0,0,0,
89        31,113,0,126,0,12,113,0,126,0,13,113,0,126,0,14,113,0,126,0,18,120
90    };
91
92    /* This is a serial form of ordinary XPathException serialized by JDK7 code:
93     *
94     *  Throwable cause = new Throwable( "message 1" );
95     *  XPathException xpathexcep = new XPathException( "message 2" );
96     *  xpathexcep.initCause( cause );
97     *  ByteArrayOutputStream fser = new ByteArrayOutputStream();
98     *  ObjectOutputStream oos = new ObjectOutputStream(fser);
99     *  oos.writeObject(xpathexcep);
100     *  oos.close();
101     */
102    static final byte [] NORMALJDK7SER = {-84,-19,0,5,115,114,0,30,106,97,118,97,120,
103        46,120,109,108,46,120,112,97,116,104,46,88,80,97,116,104,69,120,99,101,112,
104        116,105,111,110,-26,-127,97,60,-120,119,127,28,2,0,1,76,0,5,99,97,117,115,
105        101,116,0,21,76,106,97,118,97,47,108,97,110,103,47,84,104,114,111,119,97,
106        98,108,101,59,120,114,0,19,106,97,118,97,46,108,97,110,103,46,69,120,99,
107        101,112,116,105,111,110,-48,-3,31,62,26,59,28,-60,2,0,0,120,114,0,19,106,
108        97,118,97,46,108,97,110,103,46,84,104,114,111,119,97,98,108,101,-43,-58,
109        53,39,57,119,-72,-53,3,0,4,76,0,5,99,97,117,115,101,113,0,126,0,1,76,0,13,
110        100,101,116,97,105,108,77,101,115,115,97,103,101,116,0,18,76,106,97,118,
111        97,47,108,97,110,103,47,83,116,114,105,110,103,59,91,0,10,115,116,97,99,
112        107,84,114,97,99,101,116,0,30,91,76,106,97,118,97,47,108,97,110,103,47,83,
113        116,97,99,107,84,114,97,99,101,69,108,101,109,101,110,116,59,76,0,20,115,
114        117,112,112,114,101,115,115,101,100,69,120,99,101,112,116,105,111,110,115,
115        116,0,16,76,106,97,118,97,47,117,116,105,108,47,76,105,115,116,59,120,112,
116        115,113,0,126,0,3,113,0,126,0,8,116,0,9,109,101,115,115,97,103,101,32,49,
117        117,114,0,30,91,76,106,97,118,97,46,108,97,110,103,46,83,116,97,99,107,84,
118        114,97,99,101,69,108,101,109,101,110,116,59,2,70,42,60,60,-3,34,57,2,0,0,
119        120,112,0,0,0,1,115,114,0,27,106,97,118,97,46,108,97,110,103,46,83,116,97,
120        99,107,84,114,97,99,101,69,108,101,109,101,110,116,97,9,-59,-102,38,54,-35,
121        -123,2,0,4,73,0,10,108,105,110,101,78,117,109,98,101,114,76,0,14,100,101,
122        99,108,97,114,105,110,103,67,108,97,115,115,113,0,126,0,4,76,0,8,102,105,
123        108,101,78,97,109,101,113,0,126,0,4,76,0,10,109,101,116,104,111,100,78,97,
124        109,101,113,0,126,0,4,120,112,0,0,0,19,116,0,23,88,80,97,116,104,69,120,
125        99,101,112,116,105,111,110,83,101,114,105,97,108,105,122,101,116,0,28,88,
126        80,97,116,104,69,120,99,101,112,116,105,111,110,83,101,114,105,97,108,105,
127        122,101,46,106,97,118,97,116,0,4,109,97,105,110,115,114,0,38,106,97,118,
128        97,46,117,116,105,108,46,67,111,108,108,101,99,116,105,111,110,115,36,85,
129        110,109,111,100,105,102,105,97,98,108,101,76,105,115,116,-4,15,37,49,-75,
130        -20,-114,16,2,0,1,76,0,4,108,105,115,116,113,0,126,0,6,120,114,0,44,106,
131        97,118,97,46,117,116,105,108,46,67,111,108,108,101,99,116,105,111,110,115,
132        36,85,110,109,111,100,105,102,105,97,98,108,101,67,111,108,108,101,99,116,
133        105,111,110,25,66,0,-128,-53,94,-9,30,2,0,1,76,0,1,99,116,0,22,76,106,97,
134        118,97,47,117,116,105,108,47,67,111,108,108,101,99,116,105,111,110,59,120,
135        112,115,114,0,19,106,97,118,97,46,117,116,105,108,46,65,114,114,97,121,76,
136        105,115,116,120,-127,-46,29,-103,-57,97,-99,3,0,1,73,0,4,115,105,122,101,
137        120,112,0,0,0,0,119,4,0,0,0,0,120,113,0,126,0,22,120,116,0,9,109,101,115,
138        115,97,103,101,32,50,117,113,0,126,0,10,0,0,0,1,115,113,0,126,0,12,0,0,0,
139        20,113,0,126,0,14,113,0,126,0,15,113,0,126,0,16,113,0,126,0,20,120,112
140    };
141
142    //Serialize XPathException
143    static byte [] pickleXPE(XPathException xpe) throws IOException {
144        ByteArrayOutputStream bos =  new ByteArrayOutputStream();
145        ObjectOutputStream xpeos = new ObjectOutputStream(bos);
146        xpeos.writeObject(xpe);
147        xpeos.close();
148        return bos.toByteArray();
149    }
150
151    //Deserialize XPathException with byte array as serial data source
152    static XPathException unpickleXPE(byte [] ser)
153            throws IOException, ClassNotFoundException {
154        XPathException xpe;
155        ByteArrayInputStream bis = new ByteArrayInputStream(ser);
156        ObjectInputStream xpeis = new ObjectInputStream(bis);
157        xpe = (XPathException) xpeis.readObject();
158        xpeis.close();
159        return xpe;
160    }
161
162    public static void main(String[] args) throws Exception {
163        Throwable cause = new Throwable("message 1");
164        XPathException xpathexcep = new XPathException("message 2");
165
166        //Test XPE initCause() method
167        xpathexcep.initCause(cause);
168        System.out.println("getCause() result: '" + xpathexcep.getCause()
169                + "' Cause itself: '" + cause + "'");
170        if (!xpathexcep.getCause().toString().equals(cause.toString())) {
171            throw new Exception("Incorrect cause is set by initCause()");
172        }
173
174        //Test serialization/deserialization of initialized XPE
175        byte [] xpeserial;
176        XPathException xpedeser;
177        xpeserial = pickleXPE(xpathexcep);
178        xpedeser = unpickleXPE(xpeserial);
179        System.out.println("Serialized XPE: message='" + xpathexcep.getMessage()
180                + "' cause='" + xpathexcep.getCause().toString() + "'");
181        System.out.println("Deserialized XPE: message='" + xpedeser.getMessage()
182                + "' cause='" + xpedeser.getCause().toString()+"'");
183        if(xpedeser.getCause() == null ||
184                !xpedeser.getCause().toString().equals(cause.toString()) ||
185                !xpedeser.getMessage().toString().equals("message 2") )
186            throw new Exception("XPathException incorrectly serialized/deserialized");
187
188        //Test serialization/deserialization of uninitialized cause in XPE
189        XPathException xpeuninit = new XPathException("uninitialized cause");
190        xpeserial = pickleXPE(xpeuninit);
191        xpedeser = unpickleXPE(xpeserial);
192        System.out.println("Serialized XPE: message='" + xpeuninit.getMessage()
193                + "' cause='" + xpeuninit.getCause()+"'");
194        System.out.println("Deserialized XPE: message='" + xpedeser.getMessage()
195                + "' cause='" + xpedeser.getCause()+"'");
196        if(xpedeser.getCause() != null ||
197                !xpedeser.getMessage().toString().equals("uninitialized cause") )
198            throw new Exception("XPathException incorrectly serialized/deserialized");
199
200        //Test deserialization of normal XPathException serialized by JDK7
201        XPathException xpejdk7 = unpickleXPE(NORMALJDK7SER);
202        if(xpejdk7 == null || xpejdk7.getCause() == null ||
203                !xpejdk7.getMessage().equals("message 2") ||
204                !xpejdk7.getCause().getMessage().equals("message 1"))
205            throw new Exception("XpathException serialized by JDK7 was "
206                    + "incorrectly deserialized.");
207
208        //Test deserialization of XPathException with two causes from JDK7.
209        //The serialization are done for the following XPathException object:
210        // new XPathException(new Exception()).initCause(null)
211        try {
212            xpejdk7 = unpickleXPE(TWOCAUSES);
213            throw new Exception("Expected InvalidClassException but it wasn't"
214                    + " observed");
215        } catch(InvalidClassException e) {
216            System.out.println("InvalidClassException caught as expected.");
217        }
218
219    }
220}
221