From 67c71ef325d8ad30201ea68c992bcf5d64e91cac Mon Sep 17 00:00:00 2001 From: Gideon Zenz Date: Fri, 29 May 2026 21:07:16 +0200 Subject: [PATCH] Garmin: Replace SLF4J 2.0 fluent API call with 1.x-compatible logging LOG.atLevel(logLevel).log(...) in NativeFITMessage.getFieldDefinition uses the SLF4J 2.0 fluent API, which logback-android 3.0.0 does not implement. This throws AbstractMethodError at runtime, crashing the FitAsyncProcessor thread and aborting the entire Garmin device sync when a .FIT file triggers the type/size mismatch path. Replace with a switch dispatching to LOG.debug/info/warn. --- .../devices/garmin/fit/NativeFITMessage.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/NativeFITMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/NativeFITMessage.java index 8da59703e1..49e0bdc583 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/NativeFITMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/NativeFITMessage.java @@ -2700,17 +2700,13 @@ public class NativeFITMessage { } if (logLevel != null) { - LOG.atLevel(logLevel).log( - "Native for {}[{}] is of type {} with size {} (base: {}), but message declares {} with size {} (base: {})", - name(), - fieldDefinitionPrimitive.name, - stdBaseType, - fieldDefinitionPrimitive.size, - stdBaseType.getSize(), - baseType, - size, - baseType.getSize() - ); + final String msg = "Native for {}[{}] is of type {} with size {} (base: {}), but message declares {} with size {} (base: {})"; + final Object[] args = new Object[]{name(), fieldDefinitionPrimitive.name, stdBaseType, fieldDefinitionPrimitive.size, stdBaseType.getSize(), baseType, size, baseType.getSize()}; + switch (logLevel) { + case DEBUG: LOG.debug(msg, args); break; + case INFO: LOG.info(msg, args); break; + default: LOG.warn(msg, args); break; + } if (size == 1 && (baseType == BaseType.UINT16 || baseType == BaseType.UINT32 || baseType == BaseType.UINT64)) { // very common issue for COROS: