| /* |
| * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /* @test |
| * @bug 8164086 |
| * @summary regression tests for 8164086, verify correct warning from checked JNI |
| * @library /test/lib |
| * @modules java.management |
| * @run main/native TestCheckedJniExceptionCheck launch |
| */ |
| |
| import java.util.List; |
| import jdk.test.lib.process.ProcessTools; |
| import jdk.test.lib.process.OutputAnalyzer; |
| |
| public class TestCheckedJniExceptionCheck { |
| |
| static { |
| System.loadLibrary("TestCheckedJniExceptionCheck"); |
| } |
| |
| int callableMethodInvokeCount = 0; |
| |
| static final String TEST_START = "TEST STARTED"; |
| static final String EXPECT_WARNING_START = "EXPECT_WARNING_START"; |
| static final String EXPECT_WARNING_END = "EXPECT_WARNING_END"; |
| |
| static final String JNI_CHECK_EXCEPTION = "WARNING in native method: JNI call made without checking exceptions when required to from"; |
| |
| static void printExpectWarningStart(int count) { |
| System.out.println(EXPECT_WARNING_START + " " + count); |
| } |
| |
| static void printExpectWarningEnd() { |
| System.out.println(EXPECT_WARNING_END); |
| } |
| |
| public TestCheckedJniExceptionCheck() { |
| initMethodIds("callableMethod", "()V", |
| "callableNestedMethod", "(IZ)V"); |
| System.out.println(TEST_START); |
| } |
| |
| public void test() { |
| testSingleCallNoCheck(); |
| testSingleCallCheck(); |
| testSingleCallNoCheckMultipleTimes(); |
| |
| testMultipleCallsNoCheck(); |
| testMultipleCallsCheck(); |
| |
| testNestedSingleCallsNoCheck(); |
| testNestedSingleCallsCheck(); |
| testNestedMultipleCallsNoCheck(); |
| testNestedMultipleCallsCheck(); |
| } |
| |
| public void testSingleCallNoCheck() { |
| System.out.println("testSingleCallNoCheck start"); |
| callJavaFromNative(1, false); |
| System.out.println("testSingleCallNoCheck end"); |
| } |
| |
| public void testSingleCallCheck() { |
| System.out.println("testSingleCallCheck start"); |
| callJavaFromNative(1, true); |
| System.out.println("testSingleCallCheck end"); |
| } |
| |
| public void testSingleCallNoCheckMultipleTimes() { |
| System.out.println("testSingleCallNoCheckMultipleTimes start"); |
| callJavaFromNative(1, false); |
| callJavaFromNative(1, false); |
| System.out.println("testSingleCallNoCheckMultipleTimes end"); |
| } |
| |
| public void testMultipleCallsNoCheck() { |
| System.out.println("testMultipleCallsNoCheck start"); |
| printExpectWarningStart(1); |
| callJavaFromNative(2, false); |
| printExpectWarningEnd(); |
| System.out.println("testMultipleCallsNoCheck end"); |
| } |
| |
| public void testMultipleCallsCheck() { |
| System.out.println("testMultipleCallsCheck start"); |
| callJavaFromNative(2, true); |
| System.out.println("testMultipleCallsCheck end"); |
| } |
| |
| public void testNestedSingleCallsNoCheck() { |
| System.out.println("testNestedSingleCallsNoCheck start"); |
| callNestedJavaFromNative(1, false); |
| System.out.println("testNestedSingleCallsNoCheck end"); |
| } |
| |
| public void testNestedSingleCallsCheck() { |
| System.out.println("testNestedSingleCallsCheck start"); |
| callNestedJavaFromNative(1, true); |
| System.out.println("testNestedSingleCallsCheck end"); |
| } |
| |
| public void testNestedMultipleCallsNoCheck() { |
| System.out.println("testNestedMultipleCallsNoCheck start"); |
| printExpectWarningStart(3); |
| callNestedJavaFromNative(2, false); |
| printExpectWarningEnd(); |
| System.out.println("testNestedMultipleCallsNoCheck end"); |
| } |
| |
| public void testNestedMultipleCallsCheck() { |
| System.out.println("testNestedMultipleCallsCheck start"); |
| callNestedJavaFromNative(2, true); |
| System.out.println("testNestedMultipleCallsCheck end"); |
| } |
| |
| public void callableMethod() { |
| callableMethodInvokeCount++; |
| } |
| |
| public void callableNestedMethod(int nofCalls, boolean withExceptionChecks) { |
| callJavaFromNative(nofCalls, withExceptionChecks); |
| } |
| |
| public native void callJavaFromNative(int nofCalls, boolean withExceptionChecks); |
| |
| public native void callNestedJavaFromNative(int nofCalls, boolean withExceptionChecks); |
| |
| private native void initMethodIds(String callableMethodName, |
| String callableMethodSig, |
| String callableNestedMethodName, |
| String callableNestedMethodSig); |
| |
| |
| // Check warnings appear where they should, with start/end statements in output... |
| static void checkOuputForCorrectWarnings(OutputAnalyzer oa) throws RuntimeException { |
| List<String> lines = oa.asLines(); |
| int expectedWarnings = 0; |
| int warningCount = 0; |
| int lineNo = 0; |
| boolean testStartLine = false; |
| for (String line : lines) { |
| lineNo++; |
| if (!testStartLine) { // Skip any warning before the actual test itself |
| testStartLine = line.startsWith(TEST_START); |
| continue; |
| } |
| if (line.startsWith(JNI_CHECK_EXCEPTION)) { |
| if (expectedWarnings == 0) { |
| oa.reportDiagnosticSummary(); |
| throw new RuntimeException("Unexpected warning at line " + lineNo); |
| } |
| warningCount++; |
| if (warningCount > expectedWarnings) { |
| oa.reportDiagnosticSummary(); |
| throw new RuntimeException("Unexpected warning at line " + lineNo); |
| } |
| } |
| else if (line.startsWith(EXPECT_WARNING_START)) { |
| String countStr = line.substring(EXPECT_WARNING_START.length() + 1); |
| expectedWarnings = Integer.parseInt(countStr); |
| } |
| else if (line.startsWith(EXPECT_WARNING_END)) { |
| if (warningCount != expectedWarnings) { |
| oa.reportDiagnosticSummary(); |
| throw new RuntimeException("Missing warning at line " + lineNo); |
| } |
| warningCount = 0; |
| expectedWarnings = 0; |
| } |
| } |
| /* |
| System.out.println("Output looks good..."); |
| oa.reportDiagnosticSummary(); |
| */ |
| } |
| |
| public static void main(String[] args) throws Throwable { |
| if (args == null || args.length == 0) { |
| new TestCheckedJniExceptionCheck().test(); |
| return; |
| } |
| |
| // launch and check output |
| checkOuputForCorrectWarnings(ProcessTools.executeTestJvm("-Xcheck:jni", |
| "TestCheckedJniExceptionCheck")); |
| } |
| |
| } |