1package org.apache.harmony.tests.java.lang.reflect;
2
3import dalvik.annotation.AndroidOnly;
4import dalvik.system.DexFile;
5
6import junit.framework.TestCase;
7
8import java.io.File;
9import java.io.FileOutputStream;
10import java.io.IOException;
11import java.io.InputStream;
12import java.io.OutputStream;
13import java.lang.reflect.GenericSignatureFormatError;
14import java.lang.reflect.TypeVariable;
15
16import tests.support.Support_ClassLoader;
17
18public class GenericSignatureFormatErrorTest extends TestCase{
19
20    public void test_Constructor() {
21        assertNotNull(new GenericSignatureFormatError());
22    }
23
24    public void test_readResource() throws Exception {
25        File tf = File.createTempFile("classes", ".dex");
26        // System.out.println("GenericSignatureFormatErrorTest:"
27        //         +tf.getAbsolutePath()+", canRead: "+tf.canRead()
28        //         +", canWrite: "+tf.canWrite());
29        InputStream is = this.getClass().getResourceAsStream("/resources/dex1.bytes");
30        assertNotNull(is);
31    }
32
33
34    @AndroidOnly("Uses Android specific class dalvik.system.DexFile " +
35            "for loading classes.")
36    // SideEffect: strange issue (exception: 'could not open dex file',
37    //  dalvikvm: 'waitpid failed' log msg  - only occurs when @SideEffect is removed
38    // and this test is run via running tests.luni.AllTestsLang TestSuite
39    public void test_signatureFormatError() throws Exception {
40        /*
41         * dex1.bytes is a jar file with a classes.dex in it.
42         * the classes.dex was javac'ed, dx'ed and patched
43         * with the following java file:
44         *
45         * package demo;
46         *  public class HelloWorld<U> {
47         *      public HelloWorld(U t) {}
48         *  }
49         *
50         * patch:
51         * the string constant (class generics signature string)
52         *  "<U:" was changed to "<<:"
53         *
54         */
55
56        File tf = File.createTempFile("classes", ".dex");
57        // System.out.println("GenericSignatureFormatErrorTest:" +
58        //         tf.getAbsolutePath() + ", canRead: " + tf.canRead() +
59        //         ", canWrite: "+tf.canWrite());
60        InputStream is = this.getClass().getResourceAsStream("/resources/dex1.bytes");
61        assertNotNull(is);
62        OutputStream fos = new FileOutputStream(tf);
63        copy(is, fos);
64        fos.flush();
65        fos.close();
66
67
68        // class signature string "<U:" was changed to "<<:"
69        //System.out.println("file length:"+tf.length());
70        try {
71            // Was:
72            // DexFile df = new DexFile(tf);
73            // Class clazz = df.loadClass("demo/HelloWorld", this.getClass().getClassLoader());
74
75            ClassLoader cl = Support_ClassLoader.getInstance(tf.toURL(),
76                    getClass().getClassLoader());
77
78            Class clazz = cl.loadClass("demo/HelloWorld");
79            TypeVariable[] tvs = clazz.getTypeParameters();
80            fail("expecting a GenericSignatureFormatError");
81            // for (TypeVariable tv : tvs) {
82            //     System.out.println("tv:"+tv.toString());
83            // }
84        } catch (GenericSignatureFormatError gsfe) {
85            // expected
86        }
87    }
88
89    private void copy(InputStream is, OutputStream os) {
90        try {
91            int b;
92            while ((b = is.read()) != -1) {
93                os.write(b);
94            }
95            is.close();
96        } catch (IOException ex) {
97            throw new RuntimeException("io error", ex);
98        }
99    }
100}
101