RedefineClassesTests.java revision 12973:2e63fa2efdb1
1/*
2 * Copyright (c) 2003, 2015, 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 4882798 5067523
27 * @summary insure redefine is supported. exercise a class, then redefine it and do it again
28 * @author Gabriel Adauto, Wily Technology
29 *
30 * @run build RedefineClassesTests
31 * @run shell RedefineSetUp.sh
32 * @run shell MakeJAR.sh redefineAgent
33 * @run main/othervm -javaagent:redefineAgent.jar RedefineClassesTests RedefineClassesTests
34 */
35
36import java.io.*;
37import java.lang.instrument.*;
38import java.lang.reflect.*;
39public class
40RedefineClassesTests
41    extends ASimpleInstrumentationTestCase
42{
43
44    /**
45     * Constructor for RedefineClassesTests.
46     * @param name
47     */
48    public RedefineClassesTests(String name)
49    {
50        super(name);
51    }
52
53    public static void
54    main (String[] args)
55        throws Throwable {
56        ATestCaseScaffold   test = new RedefineClassesTests(args[0]);
57        test.runTest();
58    }
59
60    protected final void
61    doRunTest()
62        throws Throwable {
63        testIsRedefineClassesSupported();
64        testSimpleRedefineClasses();
65        testUnmodifiableClassException();
66    }
67
68
69    public void
70    testIsRedefineClassesSupported()
71    {
72        boolean canRedef = fInst.isRedefineClassesSupported();
73        assertTrue("Cannot redefine classes", canRedef);
74    }
75
76    public void
77    testSimpleRedefineClasses()
78        throws Throwable
79    {
80        // first load the class and prove that it is the right one
81        ExampleRedefine ex = new ExampleRedefine();
82
83        // with this version of the class, doSomething is a nop
84        int firstGet = ex.get();
85        ex.doSomething();
86        int secondGet = ex.get();
87
88        assertEquals(firstGet, secondGet);
89
90        // now redefine the class. This will change doSomething to be an increment
91
92        // this class is stored in a different place (scratch directory) to avoid collisions
93        File f = new File("Different_ExampleRedefine.class");
94        System.out.println("Reading test class from " + f);
95        InputStream redefineStream = new FileInputStream(f);
96
97        byte[] redefineBuffer = NamedBuffer.loadBufferFromStream(redefineStream);
98
99        ClassDefinition redefineParamBlock = new ClassDefinition(   ExampleRedefine.class,
100                                                                    redefineBuffer);
101
102        fInst.redefineClasses(new ClassDefinition[] {redefineParamBlock});
103
104        int thirdGet = ex.get();
105        ex.doSomething();
106        int fourthGet = ex.get();
107        assertEquals(thirdGet + 1, fourthGet);
108    }
109
110    public void
111    testUnmodifiableClassException()
112        throws Throwable
113    {
114        System.out.println("Testing UnmodifiableClassException");
115
116        // Load any class
117        File f = new File("Different_ExampleRedefine.class");
118        InputStream redefineStream = new FileInputStream(f);
119        byte[] redefineBuffer = NamedBuffer.loadBufferFromStream(redefineStream);
120
121        System.out.println("Try to redefine class for primitive type");
122        try {
123            ClassDefinition redefineParamBlock =
124                new ClassDefinition( byte.class, redefineBuffer );
125            fInst.redefineClasses(new ClassDefinition[] {redefineParamBlock});
126            fail();
127        } catch (UnmodifiableClassException x) {
128        }
129
130        System.out.println("Try to redefine class for array type");
131        try {
132            ClassDefinition redefineParamBlock =
133                new ClassDefinition( byte[].class, redefineBuffer );
134            fInst.redefineClasses(new ClassDefinition[] {redefineParamBlock});
135            fail();
136        } catch (UnmodifiableClassException x) {
137        }
138
139    }
140
141}
142