杰克逊映射器在三星 SM-T580 上抛出“冲突的二传手定义”

Posted

技术标签:

【中文标题】杰克逊映射器在三星 SM-T580 上抛出“冲突的二传手定义”【英文标题】:Jackson mapper throws "conflicting setter definitions" on Samsung SM-T580 【发布时间】:2017-04-25 02:51:01 【问题描述】:

问题: 使用 Jackson 将 JSON 转换为对象时,在我的三星 SM-T580 (android 6.0.1) 上引发以下异常。该异常不会在 OnePlus3 (Android 6.0.1) 或 ZenPad 8.0 (Android 5) 上引发,仅在三星 SM-T580 上。

java.lang.IllegalArgumentException: Conflicting setter definitions for property "myanmarEncoding": android.graphics.Paint#setMyanmarEncoding(1 params) vs android.graphics.Paint#setMyanmarEncoding(1 params)
           at [Source: N/A; line: -1, column: -1]

映射执行如下(Jackson 版本 2.8.4)。

import com.fasterxml.jackson.databind.ObjectMapper;
...
ObjectMapper objectMapper = new ObjectMapper();
try 
    myObj = objectMapper.convertValue(document.getProperties(), MyClass.class);
 catch (Exception e) 
    Log.e(TAG, e.getLocalizedMessage());
    return;

方法:首先,我已将@JsonIgnoreProperties(ignoreUnknown = true) 添加到MyClass。然后,我尝试通过混合在 android.graphics.Paint 类上使用 @JsonIgnoreType 来解决此问题。 这有点成功,因为它防止了第一个异常。

不幸的是,又抛出了一个异常:

java.lang.IllegalArgumentException: Conflicting setter definitions for property "content": android.widget.HoverPopupWindow#setContent(1 params) vs android.widget.HoverPopupWindow#setContent(1 params)
           at [Source: N/A; line: -1, column: -1]

android.graphics.Paint#setMyanmarEncoding 方法和 android.widget.HoverPopupWindow 类似乎是隐藏的 android 源代码的一部分。

这里发生了什么,我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

我找到了一种解决方法,方法是排除 Paint.class 并忽略 Android 隐藏的 HoverPopupWindow.class 中的 setContent 方法。相关方法参数定义在HoverPopupWindow.smali(GitHub)。

这就是 mixins 的应用方式(在使用 objectMapper.convertValue 之前):

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(android.graphics.Paint.class, IgnoreType.class);
objectMapper.addMixIn(Object.class, IgnoreMethods.class);

mixin 类的定义如下:

@JsonIgnoreType
public class IgnoreType 

interface IgnoreMethods 
    @JsonIgnore
    void setContent(int resId);

    @JsonIgnore
    void setContent(View view);

    @JsonIgnore
    void setContent(View view, ViewGroup.LayoutParams lp);

    @JsonIgnore
    void setContent(CharSequence text);

不幸的是,我仍然不知道为什么映射器会尝试在此特定设备上实例化 PaintHoverPopupView 类。

【讨论】:

以上是关于杰克逊映射器在三星 SM-T580 上抛出“冲突的二传手定义”的主要内容,如果未能解决你的问题,请参考以下文章

如何使用杰克逊映射器自动识别不同的类型

有没有办法阻止 Scala 2.12 破坏 Jackson 对象映射器?

keycloak 从自定义协议映射器抛出身份验证错误

信标 - 三星 Galaxy Tab A6 SM-T280 上的 RSSI 错误

杰克逊 - 必需的财产?

Sqoop 导入映射器失败,但 sqoop 作业显示正在运行