Fix: toStringForLoggingLazy() was broken on some compilers, e.g. Eclipse
It seems different compilers generate different method names for
lambdas. This change avoids the use of lambdas.
Change-Id: I4159adfa279cf48a7a6dab2d3ca76e1d3483a053
diff --git a/java/com/google/gerrit/server/logging/Metadata.java b/java/com/google/gerrit/server/logging/Metadata.java
index 4defded..7af204e 100644
--- a/java/com/google/gerrit/server/logging/Metadata.java
+++ b/java/com/google/gerrit/server/logging/Metadata.java
@@ -183,63 +183,66 @@
* @return string representation of this instance that is suitable for logging
*/
LazyArg<String> toStringForLoggingLazy() {
- return LazyArgs.lazy(
- () -> {
- // Append class name.
- String className = getClass().getSimpleName();
- if (className.startsWith("AutoValue_")) {
- className = className.substring(10);
- }
- ToStringHelper stringHelper = MoreObjects.toStringHelper(className);
+ // Don't use a lambda because different compilers generate different method names for lambdas,
+ // e.g. "lambda$myFunction$0" vs. just "lambda$0" in Eclipse. We need to identify the method
+ // by name to skip it and avoid infinite recursion.
+ return LazyArgs.lazy(this::toStringForLoggingImpl);
+ }
- // Append key-value pairs for field which are set.
- Method[] methods = Metadata.class.getDeclaredMethods();
- Arrays.sort(methods, Comparator.comparing(Method::getName));
- for (Method method : methods) {
- if (Modifier.isStatic(method.getModifiers())) {
- // skip static method
- continue;
- }
+ private String toStringForLoggingImpl() {
+ // Append class name.
+ String className = getClass().getSimpleName();
+ if (className.startsWith("AutoValue_")) {
+ className = className.substring(10);
+ }
+ ToStringHelper stringHelper = MoreObjects.toStringHelper(className);
- if (method.getName().matches("(lambda\\$)?toStringForLoggingLazy(\\$0)?")) {
- // skip toStringForLoggingLazy() and the lambda itself
- continue;
- }
+ // Append key-value pairs for field which are set.
+ Method[] methods = Metadata.class.getDeclaredMethods();
+ Arrays.sort(methods, Comparator.comparing(Method::getName));
+ for (Method method : methods) {
+ if (Modifier.isStatic(method.getModifiers())) {
+ // skip static method
+ continue;
+ }
- if (method.getReturnType().equals(Void.TYPE) || method.getParameterCount() > 0) {
- // skip method since it's not a getter
- continue;
- }
+ if (method.getName().equals("toStringForLoggingLazy")
+ || method.getName().equals("toStringForLoggingImpl")) {
+ // Don't call myself in infinite recursion.
+ continue;
+ }
- method.setAccessible(true);
+ if (method.getReturnType().equals(Void.TYPE) || method.getParameterCount() > 0) {
+ // skip method since it's not a getter
+ continue;
+ }
- Object returnValue;
- try {
- returnValue = method.invoke(this);
- } catch (IllegalArgumentException
- | IllegalAccessException
- | InvocationTargetException e) {
- // should never happen
- throw new IllegalStateException(e);
- }
+ method.setAccessible(true);
- if (returnValue instanceof Optional) {
- Optional<?> fieldValueOptional = (Optional<?>) returnValue;
- if (!fieldValueOptional.isPresent()) {
- // drop this key-value pair
- continue;
- }
+ Object returnValue;
+ try {
+ returnValue = method.invoke(this);
+ } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
+ // should never happen
+ throw new IllegalStateException(e);
+ }
- // format as 'key=value' instead of 'key=Optional[value]'
- stringHelper.add(method.getName(), fieldValueOptional.get());
- } else {
- // not an Optional value, keep as is
- stringHelper.add(method.getName(), returnValue);
- }
- }
+ if (returnValue instanceof Optional) {
+ Optional<?> fieldValueOptional = (Optional<?>) returnValue;
+ if (!fieldValueOptional.isPresent()) {
+ // drop this key-value pair
+ continue;
+ }
- return stringHelper.toString();
- });
+ // format as 'key=value' instead of 'key=Optional[value]'
+ stringHelper.add(method.getName(), fieldValueOptional.get());
+ } else {
+ // not an Optional value, keep as is
+ stringHelper.add(method.getName(), returnValue);
+ }
+ }
+
+ return stringHelper.toString();
}
public static Metadata.Builder builder() {