Мы обновляем наш Jetty с 9.3.x до 9.4.x и сталкиваемся с проблемой кластеризации сеансов.
Когда сервер пытается загрузить сеанс, он пытается демаршировать объекты, хранящиеся ватрибуты сессий.Не удается загрузить соответствующие классы этих объектов.Загрузчик классов SessionManager, по-видимому, не имеет доступа к пути к классам в самой развернутой WAR.
Мы размещаемся на причале, используя отдельную базу причала.Наш WebAppContext выглядит следующим образом:
<Configure id="support-server" class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/</Set>
<Set name="war"><Property name="jetty.base" default="."/>/support-server.war</Set>
<Set name="extraClasspath"><Property name="jetty.base" default="."/>/config</Set>
<Set name="defaultsDescriptor"><Property name="jetty.base" default="."/>/etc/webdefault.xml</Set>
<Set name="tempDirectory">tmp</Set>
<Set name="maxFormKeys">10000</Set>
<Set name="maxFormContentSize">2000000</Set>
</Configure>
Развертывание и запуск веб-приложения с помощью start.jar в работах jetty-home.Приложение можно использовать как надо.Но когда мы перезагружаем сервер и сеанс загружается из хранилища, он генерирует исключение UnreadableSessionDataException.
Мы пробовали хранилище сеансов на основе Google Cloud Datastore и MongoDB, но у обоих возникает одна проблема.Изучение кода на github (https://github.com/eclipse/jetty.project/blob/jetty-9.4.14.v20181114/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java) показывает, что используемый механизм такой же:
try (ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(blob.asInputStream()))
{
SessionData.deserializeAttributes(session, ois);
}
catch (Exception e)
{
throw new UnreadableSessionDataException (id, _context, e);
}
Подробности трассировки стека:
Caused by:
org.eclipse.jetty.server.session.UnreadableSessionDataException:
Unreadable session developmentsplje48spmp5vzaujq3ydjga0 for development__0.0.0.0
at org.eclipse.jetty.gcloud.session.GCloudSessionDataStore.sessionFromEntity(GCloudSessionDataStore.java:944)
at org.eclipse.jetty.gcloud.session.GCloudSessionDataStore.doLoad(GCloudSessionDataStore.java:509)
... 30 more
Caused by: java.lang.ClassNotFoundException:
com.fleetnology.support.web.overview.mo.TicketOverviewTableMo
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:683)
at org.eclipse.jetty.util.ClassLoadingObjectInputStream.resolveClass(ClassLoadingObjectInputStream.java:93)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1863)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1746)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2037)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1568)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:428)
at java.util.HashMap.readObject(HashMap.java:1409)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1158)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2173)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2064)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1568)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:428)
at org.eclipse.jetty.util.ClassLoadingObjectInputStream.readObject(ClassLoadingObjectInputStream.java:70)
at org.eclipse.jetty.server.session.SessionData.deserializeAttributes(SessionData.java:126)
at org.eclipse.jetty.gcloud.session.GCloudSessionDataStore.sessionFromEntity(GCloudSessionDataStore.java:940)
... 31 more
РеализацияSessionManager в 9.3.X не использовал ClassLoadingObjectInputStream и не вызывал никаких проблем.
Большинство вопросов и решений здесь связаны с обратными, классы в WAR не могут использовать классы Jetty Server.
Документация о загрузке классов в Jetty, по-видимому, сосредоточена на доступе из веб-приложения к классам сервера Jetty.