1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *
15 *  See the License for the specific language governing permissions and
16 *  limitations under the License.
17 */
18
19/**
20 * @author Anton V. Karnachuk
21 */
22
23/**
24 * Created on 11.04.2005
25 */
26package org.apache.harmony.jpda.tests.jdwp.Events;
27
28import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
29import org.apache.harmony.jpda.tests.share.SyncDebuggee;
30
31import java.lang.reflect.InvocationTargetException;
32import java.lang.reflect.Method;
33
34/**
35 * Debuggee for ExceptionCaughtTest unit test.
36 * Generates caught DebuggeeException exception.
37 */
38public class ExceptionCaughtDebuggee extends SyncDebuggee {
39    public static final String TEST_EXCEPTION_FROM_NATIVE_METHOD = "FROM_NATIVE";
40
41    public static void main(String[] args) {
42        runDebuggee(ExceptionCaughtDebuggee.class);
43    }
44
45    public void run() {
46        logWriter.println("-- ExceptionCatchDebuggee: STARTED");
47
48        // Cause loading of DebuggeeException so it is visible from the test.
49        new DebuggeeException("dummy exception");
50
51        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY);
52
53        logWriter.println("-- ExceptionCatchDebuggee: Wait for SGNL_CONTINUE...");
54        String message = synchronizer.receiveMessage();
55        logWriter.println("-- ExceptionCatchDebuggee: SGNL_CONTINUE has been received!");
56
57        if (message.equals(TEST_EXCEPTION_FROM_NATIVE_METHOD)) {
58            testThrowAndCatchExceptionFromNative();
59        } else {
60            testThrowAndCatchDebuggeeExceptionFromJava(true);
61        }
62
63        logWriter.println("-- ExceptionCatchDebuggee: FINISHing...");
64    }
65
66    void testThrowAndCatchDebuggeeExceptionFromJava(boolean nativeTransition) {
67        logWriter.println("testThrowAndCatchDebuggeeExceptionFromJava");
68        try {
69            throwAndCatchDebuggeeException(nativeTransition);
70        } catch (DebuggeeException e) {
71            logWriter.println("We caught our exception as expected");
72        } catch (Throwable e) {
73            logWriter.printError("Unexpected exception", e);
74        }
75    }
76
77    void throwAndCatchDebuggeeException(boolean nativeTransition) throws Throwable {
78        if (nativeTransition) {
79            throwDebuggeeExceptionWithTransition();
80        } else {
81            throwDebuggeeException();
82        }
83    }
84
85    private void throwDebuggeeExceptionWithTransition() throws Throwable {
86        // We use java reflection to invoke the method throwing the exception through native.
87        Method method = getClass().getDeclaredMethod("throwDebuggeeException");
88        try {
89            method.invoke(this);
90        } catch (InvocationTargetException e) {
91            if (e.getCause() instanceof DebuggeeException) {
92                // Rethrow our exception.
93                throw e.getCause();
94            } else {
95                throw e;
96            }
97        }
98    }
99
100    private void throwDebuggeeException() {
101        logWriter.println("throwDebuggeeException");
102        throw new DebuggeeException("Caught debuggee exception");
103    }
104
105    /**
106     * Catches a {@link NullPointerException} thrown from a native method.
107     */
108    private void testThrowAndCatchExceptionFromNative() {
109        logWriter.println("testThrowAndCatchExceptionFromNative");
110        try {
111            throwNullPointerExceptionFromNative();
112        } catch (NullPointerException e) {
113            System.out.println("Expected exeception");
114        }
115    }
116
117    /**
118     * Causes a {@link NullPointerException} to be thrown from native method
119     * {@link System#arraycopy(Object, int, Object, int, int)}.
120     */
121    private void throwNullPointerExceptionFromNative() {
122        System.arraycopy((Object) null, 0, (Object) null, 0, 0);
123    }
124}
125