All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.com.giancarlobuenaflor.kflogger.util.JavaLangAccessStackGetter Maven / Gradle / Ivy

/*
 * Copyright (C) 2021 The Flogger Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.giancarlobuenaflor.kflogger.util;

import static com.giancarlobuenaflor.kflogger.util.Checks.checkArgument;

import sun.misc.JavaLangAccess;
import sun.misc.SharedSecrets;

/**
 * {@link JavaLangAccess} based implementation of {@link StackGetter}.
 *
 * 

Note. This is being compiled separate from the rest of the code, because it uses Java 8 * private api. */ final class JavaLangAccessStackGetter implements StackGetter { private static final JavaLangAccess access = SharedSecrets.getJavaLangAccess(); @Override public StackTraceElement callerOf(Class target, int skipFrames) { checkArgument(skipFrames >= 0, "skipFrames must be >= 0"); Throwable throwable = new Throwable(); int index = findCallerIndex(throwable, target, skipFrames + 1); return index == -1 ? null : access.getStackTraceElement(throwable, index); } @Override public StackTraceElement[] getStackForCaller(Class target, int maxDepth, int skipFrames) { checkArgument(maxDepth == -1 || maxDepth > 0, "maxDepth must be > 0 or -1"); checkArgument(skipFrames >= 0, "skipFrames must be >= 0"); Throwable throwable = new Throwable(); int callerIndex = findCallerIndex(throwable, target, skipFrames + 1); if (callerIndex == -1) { return new StackTraceElement[0]; } int elementsToAdd = access.getStackTraceDepth(throwable) - callerIndex; if (maxDepth > 0 && maxDepth < elementsToAdd) { elementsToAdd = maxDepth; } StackTraceElement[] stackTrace = new StackTraceElement[elementsToAdd]; for (int i = 0; i < elementsToAdd; i++) { stackTrace[i] = access.getStackTraceElement(throwable, callerIndex + i); } return stackTrace; } private int findCallerIndex(Throwable throwable, Class target, int skipFrames) { int depth = access.getStackTraceDepth(throwable); boolean foundCaller = false; String targetClassName = target.getName(); for (int index = skipFrames; index < depth; index++) { if (access.getStackTraceElement(throwable, index).getClassName().equals(targetClassName)) { foundCaller = true; } else if (foundCaller) { return index; } } return -1; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy