gpt4 book ai didi

Java:序列化外部(最终)字段

转载 作者:行者123 更新时间:2023-12-01 16:59:26 40 4
gpt4 key购买 nike

我有一个类PasswordEncryptor,它使用org.jasypt.util.password.StrongPasswordEncryptor作为其字段之一,因为我试图使应用程序“可集群”所有类都需要可序列化才能进行 session 复制,但是每当访问 PasswordEncryptor 时,我都会遇到以下异常:

Caused by: java.io.NotSerializableException: org.jasypt.util.password.StrongPasswordEncryptor
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:891)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1063)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1019)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:885)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1063)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1019)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:885)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:680)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:62)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:119)
at org.jboss.as.clustering.SimpleMarshalledValue.getBytes(SimpleMarshalledValue.java:74)
at org.jboss.as.clustering.SimpleMarshalledValue.writeObject(SimpleMarshalledValue.java:172)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.6.0_34]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.6.0_34]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.6.0_34]
at java.lang.reflect.Method.invoke(Method.java:622) [rt.jar:1.6.0_34]
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:175)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1007)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:885)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:62)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:119)
at org.infinispan.marshall.MarshallUtil.marshallMap(MarshallUtil.java:60)
at org.infinispan.marshall.exts.MapExternalizer.writeObject(MapExternalizer.java:63)
at org.infinispan.marshall.exts.MapExternalizer.writeObject(MapExternalizer.java:47)
at org.infinispan.marshall.jboss.ExternalizerTable$ExternalizerAdapter.writeObject(ExternalizerTable.java:406)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:145)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:62)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:119)
at org.infinispan.atomic.AtomicHashMap$Externalizer.writeObject(AtomicHashMap.java:229)
at org.infinispan.atomic.AtomicHashMap$Externalizer.writeObject(AtomicHashMap.java:226)
at org.infinispan.marshall.jboss.ExternalizerTable$ExternalizerAdapter.writeObject(ExternalizerTable.java:406)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:145)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:62)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:119)
at org.infinispan.marshall.jboss.AbstractJBossMarshaller.objectToObjectStream(AbstractJBossMarshaller.java:86)
at org.infinispan.marshall.VersionAwareMarshaller.objectToObjectStream(VersionAwareMarshaller.java:151)
at org.infinispan.marshall.AbstractDelegatingMarshaller.objectToObjectStream(AbstractDelegatingMarshaller.java:44)
at org.infinispan.marshall.MarshalledValue.serialize0(MarshalledValue.java:119)
... 117 more
Caused by: an exception which occurred:
in field spe
in field bean
in object java.util.HashMap@b629b463
in object org.jboss.as.clustering.SimpleMarshalledValue@b629b463
in object org.infinispan.util.FastCopyHashMap@43ad73a2
in object org.infinispan.atomic.AtomicHashMap@4fd181fe
in object org.infinispan.marshall.MarshalledValue@4fd181fe
in object org.infinispan.commands.write.PutKeyValueCommand@ce32d716
in object org.infinispan.commands.tx.PrepareCommand@293098b

我已经尝试将该字段标记为transient,如下所示:

import java.io.Serializable;

import org.jasypt.util.password.StrongPasswordEncryptor;

public class PasswordEncryptor implements Serializable {

private static final long serialVersionUID = 1L;

//Need to mark transient as its not serializable
private transient StrongPasswordEncryptor spe = new StrongPasswordEncryptor();

public String encrypt(String password){
return spe.encryptPassword(password);
}

public boolean isPasswordCorrect(String enteredPassword, String passwordHash){
return spe.checkPassword(enteredPassword, passwordHash);
}

}

并且我无法使用包装器来子类 StrongPasswordEncryptor,因为它是最终的

还有其他方法可以做到这一点吗? (最好不引入任何其他库)

最佳答案

从 Infinispan 的角度来看,控制类序列化方式的最佳方法,特别是当类是最终类或您无法修改类时,是为您想要序列化的类提供您自己的 Infinispan externalizer。 Infinispan 的用户指南包含有关 how to Plug Infinispan with User-Defined Externalizers 的完整章节。解释其好处,包括减少有效负载、更快的序列化以及解决无法修改要序列化的类时出现的问题。除了文档中的示例之外,Infinispan source code (ASL2)包含大量外部化器示例来实现您的需求。

更具体地说,PasswordEncryptor 的Externalizer 不需要在writeObject 中写入任何内容,而在readObject 中它只需要实例化PasswordEncryptor。

关于Java:序列化外部(最终)字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28838756/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com