Utils.java revision 16015:b1d58146df13
1/*
2 * Copyright (c) 2016, 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
24package com.app;
25
26import java.lang.StackWalker.StackFrame;
27import java.lang.module.ModuleDescriptor;
28import java.lang.reflect.Module;
29import java.util.Objects;
30
31public class Utils {
32    public static void verify(Class<?> caller, String loaderName,
33                              String methodname, String filename) {
34        StackTraceElement[] stes = Thread.currentThread().getStackTrace();
35        StackWalker.StackFrame[] frames = new StackFrame[] {
36            makeStackFrame(Utils.class, "verify", "Utils.java"),
37            makeStackFrame(caller, methodname, filename)
38        };
39
40        checkFrame("app", frames[0], stes[1]);
41        checkFrame(loaderName, frames[1], stes[2]);
42    }
43
44    public static StackFrame makeStackFrame(Class<?> c, String methodname, String filename) {
45        return new StackFrame() {
46            @Override
47            public String getClassName() {
48                return c.getName();
49            }
50            @Override
51            public String getMethodName() {
52                return methodname;
53            }
54            @Override
55            public Class<?> getDeclaringClass() {
56                return c;
57            }
58            @Override
59            public int getByteCodeIndex() {
60                return 0;
61            }
62            @Override
63            public String getFileName() {
64                return filename;
65            }
66
67            @Override
68            public int getLineNumber() {
69                return 0;
70            }
71            @Override
72            public boolean isNativeMethod() {
73                return false;
74            }
75            @Override
76            public StackTraceElement toStackTraceElement() {
77                return null;
78            }
79
80            private String getClassLoaderName(Class<?> c) {
81                ClassLoader loader = c.getClassLoader();
82                String name = "";
83                if (loader == null) {
84                    name = "boot";
85                } else if (loader.getName() != null) {
86                    name = loader.getName();
87                }
88                return name;
89            }
90
91            @Override
92            public String toString() {
93                String mid = getClassLoaderName(c);
94                Module module = c.getModule();
95                if (module.isNamed()) {
96                    ModuleDescriptor md = module.getDescriptor();
97                    mid = md.name();
98                    if (md.version().isPresent())
99                        mid += "@" + md.version().get().toString();
100                    mid += "/";
101                }
102                String fileName = getFileName();
103                int lineNumber = getLineNumber();
104                String sourceinfo = "Unknown Source";
105                if (isNativeMethod()) {
106                    sourceinfo = "Native Method";
107                } else if (fileName != null && lineNumber >= 0) {
108                    sourceinfo = fileName + ":" + lineNumber;
109                }
110                return String.format("%s/%s.%s(%s)", mid, getClassName(), getMethodName(),
111                                     sourceinfo);
112
113            }
114        };
115    }
116
117    public static void checkFrame(String loaderName, StackFrame frame,
118                                  StackTraceElement ste) {
119        System.err.println("checking " + ste.toString() + " expected: " + frame.toString());
120        Class<?> c = frame.getDeclaringClass();
121        Module module = c.getModule();
122        assertEquals(ste.getModuleName(), module.getName(), "module name");
123        assertEquals(ste.getClassLoaderName(), loaderName, "class loader name");
124        assertEquals(ste.getClassLoaderName(), c.getClassLoader().getName(),
125                     "class loader name");
126        assertEquals(ste.getClassName(), c.getName(), "class name");
127        assertEquals(ste.getMethodName(), frame.getMethodName(), "method name");
128        assertEquals(ste.getFileName(), frame.getFileName(), "file name");
129
130    }
131    private static void assertEquals(String actual, String expected, String msg) {
132        if (!Objects.equals(actual, expected))
133            throw new AssertionError("Actual: " + actual + " Excepted: " +
134                expected + " mismatched " + msg);
135    }
136}
137