key, T value) {
/** Removes all key/value pairs for a given key. */
void removeAllValues(FloggerMetadataKey> key) {
- int index = indexOf(key);
+ var index = indexOf(key);
if (index >= 0) {
- int dest = 2 * index;
- int src = dest + 2;
+ var dest = 2 * index;
+ var src = dest + 2;
while (src < (2 * keyValueCount)) {
- Object nextKey = keyValuePairs[src];
+ var nextKey = keyValuePairs[src];
if (!nextKey.equals(key)) {
keyValuePairs[dest] = nextKey;
keyValuePairs[dest + 1] = keyValuePairs[src + 1];
@@ -322,8 +323,8 @@ void removeAllValues(FloggerMetadataKey> key) {
/** Strictly for debugging. */
@Override
public String toString() {
- StringBuilder out = new StringBuilder("Metadata{");
- for (int n = 0; n < size(); n++) {
+ var out = new StringBuilder("Metadata{");
+ for (var n = 0; n < size(); n++) {
out.append(" '").append(getKey(n)).append("': ").append(getValue(n));
}
return out.append(" }").toString();
@@ -335,6 +336,7 @@ public String toString() {
* instance must be unique and it is important not to replace this with {@code ""} or any other
* value than might be interned and be accessible to code outside this class.
*/
+ @SuppressWarnings("StringOperationCanBeSimplified")
private static final String LITERAL_VALUE_MESSAGE = new String();
// TODO: Aggressively attempt to reduce the number of fields in this instance.
@@ -597,7 +599,7 @@ protected boolean postProcess(@Nullable LogSiteKey logSiteKey) {
// Since the base class postProcess() should be invoked before subclass logic, we can set
// the initial status here. Subclasses can combine this with other rate limiter statuses by
// calling updateRateLimiterStatus() before we get back into shouldLog().
- RateLimitStatus status = DurationRateLimiter.check(metadata, logSiteKey, timestampNanos);
+ var status = DurationRateLimiter.check(metadata, logSiteKey, timestampNanos);
status = RateLimitStatus.combine(status, CountingRateLimiter.check(metadata, logSiteKey));
status = RateLimitStatus.combine(status, SamplingRateLimiter.check(metadata, logSiteKey));
this.rateLimitStatus = status;
@@ -610,7 +612,7 @@ protected boolean postProcess(@Nullable LogSiteKey logSiteKey) {
}
// This does not affect whether logging will occur, only what additional data it contains.
- StackSize stackSize = metadata.findValue(Key.CONTEXT_STACK_SIZE);
+ var stackSize = metadata.findValue(Key.CONTEXT_STACK_SIZE);
if (stackSize != null) {
// We add this information to the stack trace exception so it doesn't need to go here.
removeMetadata(Key.CONTEXT_STACK_SIZE);
@@ -626,11 +628,11 @@ protected boolean postProcess(@Nullable LogSiteKey logSiteKey) {
//
// By skipping the initial code inside this method, we don't trigger any stack capture until
// after the "log" method.
- LogSiteStackTrace context =
+ var context =
new LogSiteStackTrace(
getMetadata().findValue(Key.LOG_CAUSE),
stackSize,
- getStackForCallerOf(LogContext.class, stackSize.getMaxDepth(), 1));
+ stackForCallerOf(LogContext.class, stackSize.getMaxDepth(), 1));
// The "cause" is a unique metadata key, we must replace any existing value.
addMetadata(Key.LOG_CAUSE, context);
}
@@ -691,10 +693,10 @@ private boolean shouldLog() {
logSiteKey = specializeLogSiteKeyFromMetadata(logSiteKey, metadata);
}
}
- boolean shouldLog = postProcess(logSiteKey);
+ var shouldLog = postProcess(logSiteKey);
if (rateLimitStatus != null) {
// We check rate limit status even if it is "DISALLOW" to update the skipped logs count.
- int skippedLogs = RateLimitStatus.checkStatus(rateLimitStatus, logSiteKey, metadata);
+ var skippedLogs = RateLimitStatus.checkStatus(rateLimitStatus, logSiteKey, metadata);
if (shouldLog && skippedLogs > 0) {
metadata.addValue(Key.SKIPPED_LOG_COUNT, skippedLogs);
}
@@ -745,7 +747,7 @@ private void logImpl(String message, Object... args) {
// Evaluate any (rare) LazyArg instances early. This may throw exceptions from user code, but
// it seems reasonable to propagate them in this case (they would have been thrown if the
// argument was evaluated at the call site anyway).
- for (int n = 0; n < args.length; n++) {
+ for (var n = 0; n < args.length; n++) {
if (args[n] instanceof LazyArg) {
args[n] = ((LazyArg>) args[n]).evaluate();
}
@@ -759,9 +761,9 @@ private void logImpl(String message, Object... args) {
}
// Right at the end of processing add any tags injected by the platform. Any tags supplied at
// the log site are merged with the injected tags (though this should be very rare).
- Tags tags = Platform.getInjectedTags();
+ var tags = Platform.getInjectedTags();
if (!tags.isEmpty()) {
- Tags logSiteTags = getMetadata().findValue(Key.TAGS);
+ var logSiteTags = getMetadata().findValue(Key.TAGS);
if (logSiteTags != null) {
tags = tags.merge(logSiteTags);
}
@@ -1061,7 +1063,7 @@ public final void log(
Object... rest) {
if (shouldLog()) {
// Manually create a new varargs array and copy the parameters in.
- Object[] params = new Object[rest.length + 10];
+ var params = new Object[rest.length + 10];
params[0] = p1;
params[1] = p2;
params[2] = p3;
diff --git a/flogger/middleware/src/main/java/io/spine/logging/flogger/util/CallerFinder.java b/flogger/middleware/src/main/java/io/spine/logging/flogger/util/CallerFinder.java
deleted file mode 100644
index d14ef98f2..000000000
--- a/flogger/middleware/src/main/java/io/spine/logging/flogger/util/CallerFinder.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2012, The Flogger Authors; 2023, TeamDev. All rights reserved.
- *
- * 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
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.spine.logging.flogger.util;
-
-import static io.spine.logging.flogger.util.Checks.checkNotNull;
-
-import org.checkerframework.checker.nullness.qual.Nullable;
-
-/**
- * A helper class for determining callers of a specified class currently on the stack.
- *
- * @see
- * Original Java code of Google Flogger
- */
-public final class CallerFinder {
-
- private static final StackGetter STACK_GETTER = getBestStackGetter();
-
- /**
- * Returns the first available class implementing the {@link StackGetter} methods. The
- * implementation returned is dependent on the current java version.
- */
- private static StackGetter getBestStackGetter() {
- try {
- return new StackWalkerStackGetter();
- } catch (Throwable ignored) {
- // We may not be able to create `StackWalkerStackGetter` sometimes,
- // for example, on Android. This is not a problem because we have
- // `ThrowableStackGetter` as a fallback option.
- return new ThrowableStackGetter();
- }
- }
-
- /**
- * Returns the stack trace element of the immediate caller of the specified class.
- *
- * @param target the target class whose callers we are looking for.
- * @param skip the minimum number of calls known to have occurred between the first call to the
- * target class and the point at which the specified throwable was created. If in doubt,
- * specify zero here to avoid accidentally skipping past the caller. This is particularly
- * important for code which might be used in Android, since you cannot know whether a tool
- * such as Proguard has merged methods or classes and reduced the number of intermediate stack
- * frames.
- * @return the stack trace element representing the immediate caller of the specified class, or
- * null if no caller was found (due to incorrect target, wrong skip count or use of JNI).
- */
- @Nullable
- public static StackTraceElement findCallerOf(Class> target, int skip) {
- checkNotNull(target, "target");
- if (skip < 0) {
- throw new IllegalArgumentException("skip count cannot be negative: " + skip);
- }
- return STACK_GETTER.callerOf(target, skip + 1);
- }
-
- /**
- * Returns a synthetic stack trace starting at the immediate caller of the specified target.
- *
- * @param target the class who caller the returned stack trace will start at.
- * @param maxDepth the maximum size of the returned stack (pass -1 for the complete stack).
- * @param skip the minimum number of stack frames to skip before looking for callers.
- * @return a synthetic stack trace starting at the immediate caller of the specified target, or
- * the empty array if no caller was found (due to incorrect target, wrong skip count or use of
- * JNI).
- */
- public static StackTraceElement[] getStackForCallerOf(Class> target, int maxDepth, int skip) {
- checkNotNull(target, "target");
- if (maxDepth <= 0 && maxDepth != -1) {
- throw new IllegalArgumentException("invalid maximum depth: " + maxDepth);
- }
- if (skip < 0) {
- throw new IllegalArgumentException("skip count cannot be negative: " + skip);
- }
- return STACK_GETTER.getStackForCaller(target, maxDepth, skip + 1);
- }
-
- private CallerFinder() {}
-}
diff --git a/flogger/middleware/src/main/java/io/spine/logging/flogger/util/StackGetter.java b/flogger/middleware/src/main/java/io/spine/logging/flogger/util/StackGetter.java
deleted file mode 100644
index 5d6b1dd24..000000000
--- a/flogger/middleware/src/main/java/io/spine/logging/flogger/util/StackGetter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021, The Flogger Authors; 2023, TeamDev. All rights reserved.
- *
- * 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
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.spine.logging.flogger.util;
-
-/**
- * Interface for finding call site information.
- *
- * @see
- * Original Java code of Google Flogger
- */
-interface StackGetter {
- /**
- * Returns the first caller of a method on the {@code target} class that is *not* a member of
- * {@code target} class, by walking back on the stack, or null if the {@code target} class cannot
- * be found or is the last element of the stack.
- *
- * @param target the class to find the caller of
- * @param skipFrames skip this many frames before looking for the caller. This can be used for
- * optimization.
- */
- StackTraceElement callerOf(Class> target, int skipFrames);
-
- /**
- * Returns up to {@code maxDepth} frames of the stack starting at the stack frame that is a caller
- * of a method on {@code target} class but is *not* itself a method on {@code target} class.
- *
- * @param target the class to get the stack from
- * @param maxDepth the maximum depth of the stack to return. A value of -1 means to return the
- * whole stack
- * @param skipFrames skip this many stack frames before looking for the target class. Used for
- * optimization.
- * @throws IllegalArgumentException if {@code maxDepth} is 0 or < -1 or {@code skipFrames} is < 0.
- */
- StackTraceElement[] getStackForCaller(Class> target, int maxDepth, int skipFrames);
-}
diff --git a/flogger/middleware/src/main/java/io/spine/logging/flogger/util/StackWalkerStackGetter.java b/flogger/middleware/src/main/java/io/spine/logging/flogger/util/StackWalkerStackGetter.java
deleted file mode 100644
index 3be273553..000000000
--- a/flogger/middleware/src/main/java/io/spine/logging/flogger/util/StackWalkerStackGetter.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2021, The Flogger Authors; 2023, TeamDev. All rights reserved.
- *
- * 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
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.spine.logging.flogger.util;
-
-import static io.spine.logging.flogger.util.Checks.checkArgument;
-
-import java.lang.StackWalker.StackFrame;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-
-/**
- * StackWalker based implementation of the {@link StackGetter} interface.
- *
- * Note, that since this is using Java 9 api, it is being compiled separately from the rest of
- * the source code.
- *
- * @see
- * Original Java code of Google Flogger
- */
-final class StackWalkerStackGetter implements StackGetter {
- private static final StackWalker STACK_WALKER =
- StackWalker.getInstance(StackWalker.Option.SHOW_REFLECT_FRAMES);
-
- public StackWalkerStackGetter() {
- // Due to b/241269335, we check in constructor whether this implementation crashes in runtime,
- // and CallerFinder should catch any Throwable caused.
- StackTraceElement unused = callerOf(StackWalkerStackGetter.class, 0);
- }
-
- @Override
- public StackTraceElement callerOf(Class> target, int skipFrames) {
- checkArgument(skipFrames >= 0, "skipFrames must be >= 0");
- return STACK_WALKER.walk(
- s ->
- filterStackTraceAfterTarget(isTargetClass(target), skipFrames, s)
- .findFirst()
- .orElse(null));
- }
-
- @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");
- return STACK_WALKER.walk(
- s ->
- filterStackTraceAfterTarget(isTargetClass(target), skipFrames, s)
- .limit(maxDepth == -1 ? Long.MAX_VALUE : maxDepth)
- .toArray(StackTraceElement[]::new));
- }
-
- private Predicate isTargetClass(Class> target) {
- String name = target.getName();
- return f -> f.getClassName().equals(name);
- }
-
- private Stream filterStackTraceAfterTarget(
- Predicate isTargetClass, int skipFrames, Stream s) {
- // need to skip + 1 because of the call to the method this method is being called from
- return s.skip(skipFrames + 1)
- // skip all classes which don't match the name we are looking for
- .dropWhile(isTargetClass.negate())
- // then skip all which matches
- .dropWhile(isTargetClass)
- .map(StackFrame::toStackTraceElement);
- }
-}
diff --git a/flogger/middleware/src/main/java/io/spine/logging/flogger/util/ThrowableStackGetter.java b/flogger/middleware/src/main/java/io/spine/logging/flogger/util/ThrowableStackGetter.java
deleted file mode 100644
index 7294a5ba8..000000000
--- a/flogger/middleware/src/main/java/io/spine/logging/flogger/util/ThrowableStackGetter.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2021, The Flogger Authors; 2023, TeamDev. All rights reserved.
- *
- * 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
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.spine.logging.flogger.util;
-
-import static io.spine.logging.flogger.util.Checks.checkArgument;
-
-/**
- * Default implementation of {@link StackGetter} using {@link Throwable#getStackTrace}.
- *
- * @see
- * Original Java code of Google Flogger
- */
-final class ThrowableStackGetter implements StackGetter {
-
- @Override
- public StackTraceElement callerOf(Class> target, int skipFrames) {
- checkArgument(skipFrames >= 0, "skipFrames must be >= 0");
- StackTraceElement[] stack = new Throwable().getStackTrace();
- int callerIndex = findCallerIndex(stack, target, skipFrames + 1);
- if (callerIndex != -1) {
- return stack[callerIndex];
- }
-
- return null;
- }
-
- @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");
- StackTraceElement[] stack = new Throwable().getStackTrace();
- int callerIndex = findCallerIndex(stack, target, skipFrames + 1);
- if (callerIndex == -1) {
- return new StackTraceElement[0];
- }
- int elementsToAdd = stack.length - callerIndex;
- if (maxDepth > 0 && maxDepth < elementsToAdd) {
- elementsToAdd = maxDepth;
- }
- StackTraceElement[] stackTrace = new StackTraceElement[elementsToAdd];
- System.arraycopy(stack, callerIndex, stackTrace, 0, elementsToAdd);
- return stackTrace;
- }
-
- private int findCallerIndex(StackTraceElement[] stack, Class> target, int skipFrames) {
- boolean foundCaller = false;
- String targetClassName = target.getName();
- for (int frameIndex = skipFrames; frameIndex < stack.length; frameIndex++) {
- if (stack[frameIndex].getClassName().equals(targetClassName)) {
- foundCaller = true;
- } else if (foundCaller) {
- return frameIndex;
- }
- }
- return -1;
- }
-}
diff --git a/flogger/middleware/src/test/kotlin/io/spine/logging/flogger/util/AbstractStackGetterSpec.kt b/flogger/middleware/src/test/kotlin/io/spine/logging/flogger/util/AbstractStackGetterSpec.kt
deleted file mode 100644
index 8b43628c0..000000000
--- a/flogger/middleware/src/test/kotlin/io/spine/logging/flogger/util/AbstractStackGetterSpec.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2023, TeamDev. All rights reserved.
- *
- * 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
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.spine.logging.flogger.util
-
-import io.kotest.matchers.shouldBe
-import io.kotest.matchers.shouldNotBe
-import org.junit.jupiter.api.Test
-
-/**
- * An abstract base for testing concrete implementations of [StackGetter].
- *
- * @see
- * Original Java code of Google Flogger
- */
-internal abstract class AbstractStackGetterSpec(
- private val stackGetter: StackGetter
-) {
-
- @Test
- fun `find the stack trace element of the immediate caller of the specified class`() {
- // There are 2 internal methods (not including the log method itself)
- // in our fake library.
- val library = LoggerCode(skipCount = 2, stackGetter)
- val code = UserCode(library)
- code.invokeUserCode()
- library.caller shouldNotBe null
- library.caller!!.className shouldBe UserCode::class.java.name
- library.caller!!.methodName shouldBe "loggingMethod"
- }
-
- @Test
- fun `return 'null' due to wrong skip count`() {
- // If the minimum offset exceeds the number of internal methods, the find fails.
- val library = LoggerCode(skipCount = 3, stackGetter)
- val code = UserCode(library)
- code.invokeUserCode()
- library.caller shouldBe null
- }
-}
-
-/**
- * Fake class that emulates some code calling a log method.
- */
-internal class UserCode(private val logger: LoggerCode) {
-
- fun invokeUserCode() {
- loggingMethod()
- }
-
- private fun loggingMethod() {
- logger.logMethod()
- }
-}
-
-/**
- * A fake class that emulates the logging library, which eventually
- * calls the given [StackGetter], if any, or [CallerFinder].
- */
-internal class LoggerCode(
- private val skipCount: Int,
- private val stackGetter: StackGetter? = null
-) {
-
- var caller: StackTraceElement? = null
-
- fun logMethod() {
- internalMethodOne()
- }
-
- private fun internalMethodOne() {
- internalMethodTwo()
- }
-
- private fun internalMethodTwo() {
- caller = if (stackGetter != null) {
- stackGetter.callerOf(LoggerCode::class.java, skipCount)
- } else {
- CallerFinder.findCallerOf(LoggerCode::class.java, skipCount)
- }
- }
-}
diff --git a/flogger/middleware/src/test/kotlin/io/spine/logging/flogger/util/CallerFinderSpec.kt b/flogger/middleware/src/test/kotlin/io/spine/logging/flogger/util/CallerFinderSpec.kt
deleted file mode 100644
index 040fe11c4..000000000
--- a/flogger/middleware/src/test/kotlin/io/spine/logging/flogger/util/CallerFinderSpec.kt
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2023, TeamDev. All rights reserved.
- *
- * 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
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.spine.logging.flogger.util
-
-import io.kotest.matchers.shouldBe
-import io.kotest.matchers.shouldNotBe
-import org.junit.jupiter.api.DisplayName
-import org.junit.jupiter.api.Test
-
-/**
- * Tests for [CallerFinder].
- *
- * @see
- * Original Java code of Google Flogger
- */
-@DisplayName("`CallerFinder` should")
-internal class CallerFinderSpec {
-
- /**
- * A sanity check if we ever discover a platform where the class name
- * in the stack trace does not match [Class.getName] – this is never quite
- * guaranteed by the JavaDoc in the JDK but is relied upon during log site analysis.
- */
- @Test
- fun `use the class name that matches one in the stack trace`() {
- // Simple case for a top-level named class.
- Throwable().stackTrace[0].className shouldBe CallerFinderSpec::class.java.name
-
- // Anonymous inner class.
- val obj = object {
- override fun toString(): String {
- return Throwable().stackTrace[0].className
- }
- }
-
- "$obj" shouldBe obj::class.java.name
- }
-
- @Test
- fun `find the stack trace element of the immediate caller of the specified class`() {
- // There are 2 internal methods (not including the log method itself)
- // in our fake library.
- val library = LoggerCode(skipCount = 2)
- val code = UserCode(library)
- code.invokeUserCode()
- library.caller shouldNotBe null
- library.caller!!.className shouldBe UserCode::class.java.name
- library.caller!!.methodName shouldBe "loggingMethod"
- }
-
- @Test
- fun `return 'null' due to wrong skip count`() {
- // If the minimum offset exceeds the number of internal methods, the find fails.
- val library = LoggerCode(skipCount = 3)
- val code = UserCode(library)
- code.invokeUserCode()
- library.caller shouldBe null
- }
-}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 943f0cbfa..afba10928 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 744c64d12..20db9ad5c 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/logging/src/jvmMain/kotlin/io/spine/logging/LoggingFactory.kt b/logging/src/jvmMain/kotlin/io/spine/logging/LoggingFactory.kt
index 6c0c89d51..bae8a45b0 100644
--- a/logging/src/jvmMain/kotlin/io/spine/logging/LoggingFactory.kt
+++ b/logging/src/jvmMain/kotlin/io/spine/logging/LoggingFactory.kt
@@ -28,7 +28,7 @@ package io.spine.logging
import io.spine.logging.flogger.FluentLogger2
import io.spine.logging.flogger.backend.Platform
-import io.spine.logging.flogger.util.CallerFinder
+import io.spine.reflect.CallerFinder
import kotlin.reflect.KClass
/**
@@ -77,17 +77,6 @@ public actual object LoggingFactory: ClassValue() {
public fun repeatedMetadataKey(label: String, type: Class): MetadataKey =
repeatedMetadataKey(label, type.kotlin)
- /**
- * Obtains an instance of [FluentLogger2] for the given class.
- *
- * The same instance is returned for the same class.
- */
- @JvmStatic
- @JvmName("getFluentLogger") // Set the name explicitly to avoid synthetic `$logging` suffix.
- internal fun getFluentLogger(cls: Class<*>): FluentLogger2 {
- return get(cls).delegate
- }
-
private fun createForClass(cls: Class<*>): JvmLogger {
val floggerBackend = Platform.getBackend(cls.name)
val flogger = FluentLogger2(floggerBackend)
diff --git a/platforms/jvm-default-platform/build.gradle.kts b/platforms/jvm-default-platform/build.gradle.kts
index efdf7a213..aee0f21a9 100644
--- a/platforms/jvm-default-platform/build.gradle.kts
+++ b/platforms/jvm-default-platform/build.gradle.kts
@@ -25,6 +25,7 @@
*/
import io.spine.internal.dependency.AutoService
+import io.spine.internal.dependency.Spine
import io.spine.internal.gradle.java.disableLinters
plugins {
@@ -33,6 +34,7 @@ plugins {
}
dependencies {
+ implementation(Spine.reflect)
implementation(project(":middleware"))
implementation(project(":jul-backend"))
testImplementation(project(":middleware", configuration = "testArtifacts"))
diff --git a/platforms/jvm-default-platform/src/main/java/io/spine/logging/backend/system/StackBasedCallerFinder.java b/platforms/jvm-default-platform/src/main/java/io/spine/logging/backend/system/StackBasedCallerFinder.java
index aa826e034..86d34a67f 100644
--- a/platforms/jvm-default-platform/src/main/java/io/spine/logging/backend/system/StackBasedCallerFinder.java
+++ b/platforms/jvm-default-platform/src/main/java/io/spine/logging/backend/system/StackBasedCallerFinder.java
@@ -30,7 +30,8 @@
import io.spine.logging.flogger.FloggerLogSite;
import io.spine.logging.flogger.FloggerLogSites;
import io.spine.logging.flogger.backend.Platform.LogCallerFinder;
-import io.spine.logging.flogger.util.CallerFinder;
+
+import static io.spine.reflect.CallerFinder.findCallerOf;
/**
* The default caller finder implementation for Java 9+.
@@ -51,7 +52,7 @@ public static LogCallerFinder getInstance() {
@Override
public String findLoggingClass(Class extends AbstractLogger>> loggerClass) {
// We can skip at most only 1 method from the analysis, the inferLoggingClass() method itself.
- StackTraceElement caller = CallerFinder.findCallerOf(loggerClass, 1);
+ var caller = findCallerOf(loggerClass, 1);
if (caller != null) {
// This might contain '$' for inner/nested classes, but that's okay.
return caller.getClassName();
@@ -64,7 +65,7 @@ public FloggerLogSite findLogSite(Class> loggerApi, int stackFramesToSkip) {
// Skip an additional stack frame because we create the Throwable inside this method, not at
// the point that this method was invoked (which allows completely alternate implementations
// to avoid even constructing the Throwable instance).
- StackTraceElement caller = CallerFinder.findCallerOf(loggerApi, stackFramesToSkip + 1);
+ var caller = findCallerOf(loggerApi, stackFramesToSkip + 1);
// Returns INVALID if "caller" is null (no caller found for given API class).
return FloggerLogSites.logSiteFrom(caller);
}
diff --git a/pom.xml b/pom.xml
index f5b23ce5c..7c6099393 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@ all modules and does not describe the project structure per-subproject.
-->
io.spine
spine-logging
-2.0.0-SNAPSHOT.233
+2.0.0-SNAPSHOT.234
2015
@@ -26,31 +26,31 @@ all modules and does not describe the project structure per-subproject.
com.google.guava
guava
- 32.1.2-jre
+ 32.1.3-jre
compile
com.google.protobuf
protobuf-java
- 3.23.4
+ 3.25.1
compile
com.google.protobuf
protobuf-java-util
- 3.23.4
+ 3.25.1
compile
com.google.protobuf
protobuf-kotlin
- 3.23.4
+ 3.25.1
compile
io.grpc
grpc-api
- 1.57.2
+ 1.59.0
compile
@@ -65,16 +65,10 @@ all modules and does not describe the project structure per-subproject.
1.1.1
test
-
- com.google.flogger
- flogger-slf4j-backend
- 0.7.4
- test
-
com.google.guava
guava-testlib
- 32.1.2-jre
+ 32.1.3-jre
test
@@ -127,18 +121,18 @@ all modules and does not describe the project structure per-subproject.
com.google.errorprone
error_prone_annotations
- 2.21.1
+ 2.23.0
provided
com.google.errorprone
error_prone_core
- 2.21.1
+ 2.23.0
com.google.errorprone
error_prone_type_annotations
- 2.21.1
+ 2.23.0
provided
@@ -149,7 +143,7 @@ all modules and does not describe the project structure per-subproject.
com.puppycrawl.tools
checkstyle
- 10.3.4
+ 10.12.1
io.gitlab.arturbosch.detekt
@@ -159,32 +153,32 @@ all modules and does not describe the project structure per-subproject.
io.kotest
kotest-assertions-core
- 5.6.2
+ 5.8.0
io.kotest
kotest-framework-api
- 5.6.2
+ 5.8.0
io.kotest
kotest-framework-datatest
- 5.6.2
+ 5.8.0
io.kotest
kotest-framework-engine
- 5.6.2
+ 5.8.0
io.kotest
kotest-runner-junit5-jvm
- 5.6.2
+ 5.8.0
io.spine
spine-reflect
- 2.0.0-SNAPSHOT.182
+ 2.0.0-SNAPSHOT.184
io.spine.tools
@@ -210,88 +204,78 @@ all modules and does not describe the project structure per-subproject.
org.checkerframework
checker-qual
- 3.37.0
+ 3.40.0
provided
org.jacoco
org.jacoco.agent
- 0.8.10
+ 0.8.11
org.jacoco
org.jacoco.ant
- 0.8.10
+ 0.8.11
org.jetbrains.dokka
analysis-kotlin-descriptors
- 1.9.0
+ 1.9.10
org.jetbrains.dokka
dokka-base
- 1.9.0
+ 1.9.10
org.jetbrains.dokka
dokka-core
- 1.9.0
+ 1.9.10
org.jetbrains.dokka
kotlin-as-java-plugin
- 1.9.0
+ 1.9.10
org.jetbrains.kotlin
kotlin-annotation-processing-gradle
- 1.9.10
+ 1.9.22
org.jetbrains.kotlin
kotlin-build-tools-impl
- 1.9.10
+ 1.9.22
org.jetbrains.kotlin
kotlin-compiler-embeddable
- 1.9.10
+ 1.9.22
org.jetbrains.kotlin
kotlin-klib-commonizer-embeddable
- 1.9.10
+ 1.9.22
org.jetbrains.kotlin
kotlin-scripting-compiler-embeddable
- 1.9.10
+ 1.9.22
org.jetbrains.kotlin
kotlin-stdlib
- 1.9.10
-
-
- org.jetbrains.kotlin
- kotlin-stdlib-common
- 1.9.10
-
-
- org.jetbrains.kotlin
- kotlin-stdlib-jdk8
- 1.9.10
+ 1.9.22
org.jetbrains.kotlin
kotlin-test-annotations-common
- 1.9.10
+ 1.9.22
org.jetbrains.kotlin
kotlin-test-common
- 1.9.10
+ 1.9.22
org.junit.jupiter
diff --git a/tests/jvm-slf4j-jdk14-backend-std-context/build.gradle.kts b/tests/jvm-slf4j-jdk14-backend-std-context/build.gradle.kts
index 508bed210..c3a89248d 100644
--- a/tests/jvm-slf4j-jdk14-backend-std-context/build.gradle.kts
+++ b/tests/jvm-slf4j-jdk14-backend-std-context/build.gradle.kts
@@ -24,7 +24,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import io.spine.internal.dependency.Flogger
import io.spine.internal.dependency.Slf4J
plugins {
@@ -34,9 +33,6 @@ plugins {
dependencies {
testImplementation(project(":logging"))
testImplementation(project(":fixtures"))
- testRuntimeOnly(Flogger.Runtime.slf4JBackend) {
- exclude(group = "com.google.flogger")
- }
testRuntimeOnly(Slf4J.jdk14)
testRuntimeOnly(project(":std-context"))
}
diff --git a/tests/jvm-slf4j-reload4j-backend-std-context/build.gradle.kts b/tests/jvm-slf4j-reload4j-backend-std-context/build.gradle.kts
index 8fcadf18a..96a61a848 100644
--- a/tests/jvm-slf4j-reload4j-backend-std-context/build.gradle.kts
+++ b/tests/jvm-slf4j-reload4j-backend-std-context/build.gradle.kts
@@ -24,7 +24,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import io.spine.internal.dependency.Flogger
import io.spine.internal.dependency.Slf4J
plugins {
@@ -34,9 +33,6 @@ plugins {
dependencies {
testImplementation(project(":logging"))
testImplementation(project(":fixtures"))
- testRuntimeOnly(Flogger.Runtime.slf4JBackend) {
- exclude(group = "com.google.flogger")
- }
testRuntimeOnly(Slf4J.reload4j)
testRuntimeOnly(project(":std-context"))
}
diff --git a/version.gradle.kts b/version.gradle.kts
index d5c0ca3f7..1421022b9 100644
--- a/version.gradle.kts
+++ b/version.gradle.kts
@@ -24,4 +24,4 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-val versionToPublish: String by extra("2.0.0-SNAPSHOT.233")
+val versionToPublish: String by extra("2.0.0-SNAPSHOT.234")