diff --git a/reactor-core/build.gradle b/reactor-core/build.gradle index eb6b46d28e..55d9cfee2d 100644 --- a/reactor-core/build.gradle +++ b/reactor-core/build.gradle @@ -292,4 +292,13 @@ if (JavaVersion.current().java9Compatible) { dependencies { compileOnly sourceSets.java8stubs.output } +} +else { + sourceSets { + java9stubs.java.srcDirs = ['src/main/java9stubs'] + } + + dependencies { + compileOnly sourceSets.java9stubs.output + } } \ No newline at end of file diff --git a/reactor-core/src/main/java/reactor/core/publisher/Traces.java b/reactor-core/src/main/java/reactor/core/publisher/Traces.java index d461234200..8feed50b1f 100644 --- a/reactor-core/src/main/java/reactor/core/publisher/Traces.java +++ b/reactor-core/src/main/java/reactor/core/publisher/Traces.java @@ -32,6 +32,7 @@ package reactor.core.publisher; +import java.util.Iterator; import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -65,7 +66,7 @@ final class Traces { static { String[] strategyClasses = { - Traces.class.getPackage().getName() + ".StackWalkerCallSiteSupplierFactory", + Traces.class.getName() + "$StackWalkerCallSiteSupplierFactory", Traces.class.getName() + "$SharedSecretsCallSiteSupplierFactory", Traces.class.getName() + "$ExceptionCallSiteSupplierFactory", }; @@ -87,6 +88,90 @@ final class Traces { .orElseThrow(() -> new IllegalStateException("Valid strategy not found")); } + /** + * Utility class for the call-site extracting on Java 9+. + * + */ + @SuppressWarnings("unused") + static final class StackWalkerCallSiteSupplierFactory implements Supplier> { + + static { + // Trigger eager StackWalker class loading. + StackWalker.getInstance(); + } + + /** + * Transform the current stack trace into a {@link String} representation, + * each element being prepended with a tabulation and appended with a + * newline. + * + * @return the string version of the stacktrace. + */ + @Override + public Supplier get() { + StackWalker.StackFrame[] stack = StackWalker.getInstance().walk(s -> { + StackWalker.StackFrame[] result = new StackWalker.StackFrame[10]; + Iterator iterator = s.iterator(); + iterator.next(); // .get + + int i = 0; + while (iterator.hasNext()) { + StackWalker.StackFrame frame = iterator.next(); + + if (i >= result.length) { + return new StackWalker.StackFrame[0]; + } + + result[i++] = frame; + + if (isUserCode(frame.getClassName())) { + break; + } + } + StackWalker.StackFrame[] copy = new StackWalker.StackFrame[i]; + System.arraycopy(result, 0, copy, 0, i); + return copy; + }); + + if (stack.length == 0) { + return () -> ""; + } + + if (stack.length == 1) { + return () -> "\t" + stack[0].toString() + "\n"; + } + + return () -> { + StringBuilder sb = new StringBuilder(); + + for (int j = stack.length - 2; j > 0; j--) { + StackWalker.StackFrame previous = stack[j]; + + if (!full) { + if (previous.isNativeMethod()) { + continue; + } + + String previousRow = previous.getClassName() + "." + previous.getMethodName(); + if (shouldSanitize(previousRow)) { + continue; + } + } + sb.append("\t") + .append(previous.toString()) + .append("\n"); + break; + } + + sb.append("\t") + .append(stack[stack.length - 1].toString()) + .append("\n"); + + return sb.toString(); + }; + } + } + @SuppressWarnings("unused") static class SharedSecretsCallSiteSupplierFactory implements Supplier> { @@ -303,5 +388,4 @@ else if (i == traces.size()) { return apiLine + " ⇢ " + userCodeLine; } - } diff --git a/reactor-core/src/main/java9/reactor/core/publisher/StackWalkerCallSiteSupplierFactory.java b/reactor-core/src/main/java9/reactor/core/publisher/StackWalkerCallSiteSupplierFactory.java deleted file mode 100644 index ef64f2c365..0000000000 --- a/reactor-core/src/main/java9/reactor/core/publisher/StackWalkerCallSiteSupplierFactory.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2011-2018 Pivotal Software Inc, 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 - * - * 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 reactor.core.publisher; - -import java.lang.StackWalker.StackFrame; -import java.util.Iterator; -import java.util.function.Supplier; - -/** - * Utility class for the call-site extracting on Java 9+. - * - * @author Sergei Egorov - */ -@SuppressWarnings("unused") -final class StackWalkerCallSiteSupplierFactory implements Supplier> { - - /** - * Transform the current stack trace into a {@link String} representation, - * each element being prepended with a tabulation and appended with a - * newline. - * - * @return the string version of the stacktrace. - */ - @Override - public Supplier get() { - StackFrame[] stack = StackWalker.getInstance().walk(s -> { - StackFrame[] result = new StackFrame[10]; - Iterator iterator = s.iterator(); - iterator.next(); // .get - - int i = 0; - while (iterator.hasNext()) { - StackFrame frame = iterator.next(); - - if (i >= result.length) { - return new StackFrame[0]; - } - - result[i++] = frame; - - if (Traces.isUserCode(frame.getClassName())) { - break; - } - } - StackFrame[] copy = new StackFrame[i]; - System.arraycopy(result, 0, copy, 0, i); - return copy; - }); - - if (stack.length == 0) { - return () -> ""; - } - - if (stack.length == 1) { - return () -> "\t" + stack[0].toString() + "\n"; - } - - return () -> { - StringBuilder sb = new StringBuilder(); - - for (int j = stack.length - 2; j > 0; j--) { - StackFrame previous = stack[j]; - - if (!Traces.full) { - if (previous.isNativeMethod()) { - continue; - } - - String previousRow = previous.getClassName() + "." + previous.getMethodName(); - if (Traces.shouldSanitize(previousRow)) { - continue; - } - } - sb.append("\t") - .append(previous.toString()) - .append("\n"); - break; - } - - sb.append("\t") - .append(stack[stack.length - 1].toString()) - .append("\n"); - - return sb.toString(); - }; - } -} diff --git a/reactor-core/src/main/java9stubs/java/lang/StackWalker.java b/reactor-core/src/main/java9stubs/java/lang/StackWalker.java new file mode 100644 index 0000000000..4f2264eceb --- /dev/null +++ b/reactor-core/src/main/java9stubs/java/lang/StackWalker.java @@ -0,0 +1,30 @@ +package java.lang; + +import java.util.function.Function; +import java.util.stream.Stream; + +import sun.reflect.CallerSensitive; + +/** + * Stub for the Java 9 compatibility when compiled with JDK 8. + */ +public class StackWalker { + + public static StackWalker getInstance() { + return null; + } + + @CallerSensitive + public T walk(Function, ? extends T> function) { + return null; + } + + public interface StackFrame { + String getClassName(); + + String getMethodName(); + + boolean isNativeMethod(); + } + +}