Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;无效的lambda反序列化“;当lambda用于接口实现时_Lambda_Wicket_Java 8 - Fatal编程技术网

&引用;无效的lambda反序列化“;当lambda用于接口实现时

&引用;无效的lambda反序列化“;当lambda用于接口实现时,lambda,wicket,java-8,Lambda,Wicket,Java 8,我有一个带有lambda表达式的wicket项目。在一个页面上,当用户单击“后退”按钮时,我的应用程序崩溃: java.lang.IllegalArgumentException: Invalid lambda deserialization at x.y.z.MyPage$3.$deserializeLambda$(MyPage.java:1) 在page类(返回的地方)中,我使用lambda表达式实现此接口: public interface Localizator extends Ser

我有一个带有lambda表达式的wicket项目。在一个页面上,当用户单击“后退”按钮时,我的应用程序崩溃:

java.lang.IllegalArgumentException: Invalid lambda deserialization
at x.y.z.MyPage$3.$deserializeLambda$(MyPage.java:1)
在page类(返回的地方)中,我使用lambda表达式实现此接口:

public interface Localizator extends Serializable {
    String getLocalizedString(String key);
}
兰姆达:

protected void someMethod() {
    localize((String key) -> getString(key));
}
当我将lambda更改为匿名类时,一切正常。在这种情况下,我应该如何使用lambda

Env:java1.8.0_25,netbeans8.0.2,Wicket 6.17.0

编辑: 这是使用lambda的真实(但简化)方法:

@Override
protected DataLoader createDataLoader() {

    return new DataLoader(){

        @Override
        public List loadData() {
            ...
        }

        @Override
        public List convertToTableRows(List data) {
            return Converter.asRowList(
                data, 
                (Record record) -> {...}, // this lambda is OK
                (String key) -> getString(key)); // this lambda is crashing
        }

        @Override
        public List filterTableRow() {
            ...
        }

    };
}
转换器等级:

public class Converter implements Serializable { 
    public static ArrayList asRowList(List data, OtherLoader loader, Localizator localizator){...}

DataLoader还扩展了Serializable

要启用
序列化
支持,拥有一个
接口
扩展
可序列化
就足够了。那么就没有必要再做额外的演员阵容了。代码可以序列化lambda表达式实例这一事实表明了这一点。反序列化时失败,这是类不兼容的指标,因此如果插入强制转换有帮助,很可能是一个副作用,因为插入强制转换会强制重新编译包含lambda表达式的类


如果要继续使用序列化lambda,应了解其工作原理,如中所述:

可序列化lambda的实现者(如编译器或语言运行库)应确保实例正确反序列化。一种方法是确保
writeReplace
方法返回
SerializedLambda
的实例,而不是允许进行默认序列化

SerializedLambda
有一个
readResolve
方法,该方法在捕获类中查找名为
$deserializeLambda$(SerializedLambda)
的(可能是私有的)静态方法,将其本身作为第一个参数调用,并返回结果。实现
$deserializeLambda$
的Lambda类负责验证
SerializedLambda
的属性是否与该类实际捕获的Lambda一致

因此,当
$deserializeLambda$
异常拒绝反序列化时,这意味着序列化lambda的属性与类中定义的已知可序列化lambda的属性不匹配。这些特性可能非常脆弱

它们包括函数接口、捕获的参数和目标方法。对于lambda表达式(而不是方法引用),目标方法是定义类中的合成方法,选择了编译器,未指定的名称甚至可能依赖于同一类中的其他lambda表达式,因为插入另一个表达式可能会由于编号方案而导致名称更改


与插入
serialVersionUID
可能会告诉序列化框架它不应该关心明显的不一致性的普通类不同,您不能告诉lambda表达式显示更健壮性。换句话说,一旦序列化了应该持久化的lambda实例,就不能更改它们的定义类。另请参见

这并没有回答上述问题,但在Flink中搜索
无效lambda反序列化时,首先会弹出此线程

如果在发布前使用Proguard进行模糊处理

  • Proguard将
    可序列化的类弄乱了

  • 您需要配置
    proguard.pro
    来修复此错误,请参阅


在我自己的例子中,我实现了一段时间前建议的“Java 8 Lambda”设置,但文档发生了变化,现在我缺少了其中解释的新设置。

您的
localize()
方法是什么样子的?实际上localize方法只是一个示例,Lambda用于更复杂的上下文中,我将编辑我的问题来展示它在现实中是如何使用的。是的,通过这种方式(Localizator&Serializable)(String key)->getString(key)会有所帮助,但我不明白为什么我必须将Serializable接口的lambda转换为Serializable。我必须在每一页中将每个lambda转换为可序列化吗?这毫无意义……当功能性
接口
扩展了
可序列化
时,不需要额外的强制转换。确保类是同步的,例如,您没有编译
MyPage.java
,而
interface
的版本尚未扩展
Serializable
,并且您没有尝试使用
MyPage
类的不同版本反序列化。我希望这种“链接另一个问题”的方式可以。这个引用可以让我省下一天的时间去理解哪一个lambda是不可序列化的,而事实上一切都正常(只有混淆破坏了一切)。