我正在使用配置了会话复制的 OpenLiberty 24.0.0.6。该应用程序将 JSF 与 PrimeFaces 结合使用。我的一些业务对象存储在 HTTP 会话中(通过 CDI 包的 @SessionScoped 注释)。
当会话反序列化时,我收到以下错误(取自 ffdc 日志):
Exception = java.lang.ClassNotFoundException
Source = com.ibm.ws.session.SessionLoader.loadObject
probeid = 82
Stack Dump = java.lang.ClassNotFoundException: org.jboss.weld.module.web.HttpSessionBean$SerializableProxy
at com.ibm.ws.classloading.internal.UnifiedClassLoader.findClass(UnifiedClassLoader.java:167)
at com.ibm.ws.classloading.internal.ThreadContextClassLoader.findClass(ThreadContextClassLoader.java:145)
at com.ibm.ws.classloading.internal.UnifiedClassLoader.loadClass0(UnifiedClassLoader.java:141)
at com.ibm.ws.classloading.internal.UnifiedClassLoader$Delegation.loadClass(UnifiedClassLoader.java:87)
at com.ibm.ws.classloading.internal.UnifiedClassLoader.loadClass(UnifiedClassLoader.java:106)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527)
at com.ibm.ws.serialization.DeserializationObjectInputStream.loadClass(DeserializationObjectInputStream.java:64)
at com.ibm.ws.serialization.internal.DeserializationObjectInputStreamImpl.loadClass(DeserializationObjectInputStreamImpl.java:50)
at com.ibm.ws.serialization.DeserializationObjectInputStream.resolveClass(DeserializationObjectInputStream.java:135)
at com.ibm.ws.serialization.DeserializationObjectInputStream.resolveClass(DeserializationObjectInputStream.java:173)
at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2003)
at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1870)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2201)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1687)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2496)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2390)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2228)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1687)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:489)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:447)
at java.base/java.util.Hashtable.readHashtable(Hashtable.java:1315)
at java.base/java.util.Hashtable.readObject(Hashtable.java:1259)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1046)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2357)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2228)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1687)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:489)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:447)
at com.ibm.ws.session.utils.SessionLoader.loadObject(SessionLoader.java:64)
at com.ibm.ws.session.store.db.DatabaseHashMap.getValue(DatabaseHashMap.java:1615)
服务器正在响应:
[15.08.24, 16:03:13:605 MESZ] 0000007c com.ibm.ws.session.WASSession E SESN0051E: Attempting to deserialize a session object from the backend resulted in a ClassNotFoundException..
[15.08.24, 16:03:13:605 MESZ] 0000007c com.ibm.ws.session.WASSession E ID: n3KSj82AVIMrmIK9ZH8A0WH
[15.08.24, 16:03:13:605 MESZ] 0000007c com.ibm.ws.session.WASSession E Exception:
java.lang.ClassNotFoundException: org.jboss.weld.module.web.HttpSessionBean$SerializableProxy
我在OL中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<server>
<!-- https://openliberty.io/docs/latest/create-session-table.html -->
<library id="SessionDriverLib">
<fileset dir="${shared.resource.dir}/session" includes="*.jar"/>
</library>
<dataSource id="SessionDS">
<jdbcDriver libraryRef="SessionDriverLib" />
<properties.postgresql serverName="${postgres_server}"
portNumber="5432"
databaseName="httpSession"
user="session_user"
password="***"/>
</dataSource>
<httpSessionDatabase
id="SessionDB"
dataSourceRef="SessionDS"
tableName="sessions"/>
<httpSession storageRef="SessionDB" cloneId="${clone_id}"/>
</server>
我们正在使用以下功能:
<featureManager>
<feature>javaee-8.0</feature>
<feature>microProfile-3.3</feature>
<feature>monitor-1.0</feature>
<feature>sessionDatabase-1.0</feature>
</featureManager>
我注销了 HTTP 会话的内容,我想知道 WELD 代理是会话的一部分:
attribute name:
WELD_S#F_WELD%AbstractBuiltInBean%web_war_exploded#twl-web%HttpSession
attribute value (from toString())
Bean: ForwardingBean null for WELD%AbstractBuiltInBean%web_war_exploded#web%HttpSession; Instance: org.jboss.weld.module.web.HttpSessionBean$SerializableProxy@1bbaee59; CreationalContext: org.jboss.weld.contexts.CreationalContextImpl@27396b8a
我不知道为什么 WELD 在会话中存储这样的代理类。 顺便提一句。一些内容存储在数据库中。
HTTP 会话中存储的所有对象都是可序列化的。如果不是,我想我会得到一个 NotSerializedExcpeption (不在日志或跟踪中)
我在数据库中查找序列化数据,找到了代理类。
应用程序中没有 WELD 依赖项(意味着应用程序战争)。类路径对我来说看起来不错。
如果您需要更多信息,请告诉我。
欢迎任何想法。 :-)
我认为你的场景应该可行,并且我相当确定这是 Liberty 中的一个错误。 (我已经在更高版本的 CDI 上重现了它,您使用的版本似乎也有同样的问题。)
我认为注入
HttpSession
时就会出现问题。在幕后,Weld 使用 SessionScoped
bean 来启用此功能,这就是对象作为会话的一部分被持久化的原因。错误在于,当会话恢复时,liberty 不会在正确的包中查找用于反序列化该对象的类。
请在 github 上打开错误报告,我们将修复它。