Калитка: передовая практика развертывания, позволяющая избежать исключения ClassNotFoundException

Я новичок в калитке и только недавно начал использовать ее для нового веб-приложения для одного из наших проектов. Сегодня я столкнулся с похожей проблемой, описанной в WICKET-4785, ClassNotFoundException во время десериализация страницы. На мой взгляд, интересная часть этого заключается в том, что упомянутый отсутствующий класс отсутствовал по уважительной причине: я просто провел небольшой рефакторинг и переименовал класс, повторно развернул и перезапустил свой Tomcat. Для меня это выглядит как обычный вариант использования, но я не подумал об этом, когда читал документы, потому что.

Мое развертывание очень простое: я проверяю рабочую копию SVN с предварительно настроенным тегом, содержащим все приложение, один раз, а затем просто нужно объединить/обновить и остановить/запустить веб-сервер/приложение.

Как развертывание должно работать в Wicket после рефакторинга или иного изменения моих классов в отношении кэшированных и сериализованных страниц? Есть ли что-нибудь, что мне нужно сказать калитке, чтобы очищать свои кеши при каждом развертывании или игнорировать их или что-то еще? Должен ли я не удалять однажды развернутые классы в течение достаточного периода времени? Это был бы небольшой кошмар... Или есть еще какие-то проблемы, с которыми я столкнулся, которых мне следовало избегать?

Очевидно, что другие также развертывают свои приложения Wicket, поэтому я надеюсь, что у вас есть какие-то советы о том, как избежать проблемы, с которой я столкнулся. Спасибо!

Важные части трассировки стека:

java.lang.ClassNotFoundException: de.am_soft.util.frontend.wicket.markup.link.LogoutLink
     at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
     at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
     at java.lang.Class.forName0(Native Method)
     at java.lang.Class.forName(Unknown Source)
     at org.apache.wicket.application.AbstractClassResolver.resolveClass(AbstractClassResolver.java:108)
     at org.apache.wicket.serialize.java.JavaSerializer$ClassResolverObjectInputStream.resolveClass(JavaSerializer.java:218)
     at java.io.ObjectInputStream.[...]
     at org.apache.wicket.serialize.java.JavaSerializer.deserialize(JavaSerializer.java:122)
     at org.apache.wicket.pageStore.DefaultPageStore.deserializePage(DefaultPageStore.java:396)
     at org.apache.wicket.pageStore.DefaultPageStore.getPage(DefaultPageStore.java:135)
     at org.apache.wicket.page.PageStoreManager$SessionEntry.getPage(PageStoreManager.java:203)
     at org.apache.wicket.page.PageStoreManager$PersistentRequestAdapter.getPage(PageStoreManager.java:360)
     at org.apache.wicket.page.AbstractPageManager.getPage(AbstractPageManager.java:107)

Я отправил этот вопрос на Список пользователей Wicket также, но пока не получил особого ответа, хотя я думал, что это простой вопрос...


person Thorsten Schöning    schedule 22.11.2014    source источник


Ответы (1)


Wicket — это веб-фреймворк с отслеживанием состояния, в котором хранятся экземпляры страниц, чтобы облегчить тесное взаимодействие пользователя между браузером и сервером. Это означает сериализацию иерархии компонентов каждой страницы, чтобы пользователь мог взаимодействовать с иерархией компонентов, изменять ее (например, заменять панели) и ожидать, что клиент и сервер будут синхронизированы.

Когда вы реорганизуете свои классы, например переименовываете класс ссылки, десериализатор не может найти этот класс, и вы получаете это ClassNotFoundException. Чтобы смягчить это, вы:

а. нужно начать новый сеанс в вашем браузере, чтобы Wicket не привязывал ваш браузер к состоянию сервера со старыми классами (выбросьте файл cookie jsessionid), или

б. создайте новый экземпляр страницы внутри вашего сеанса (удалите параметр ?0 или ?1231 в URL-адресе в вашем браузере) или

в. очистить все данные сеанса на сервере

person Martijn Dashorst    schedule 24.11.2014
comment
(b) очевидно, что это не вариант для моих пользователей, (a) звучит так, как будто мои пользователи выходят из системы без причины и (c) означает, что мне приходится иметь дело с собственной файловой структурой кеша Wickets, которая является деталью реализации и может измениться. Это то, как другие пользователи действительно развертывают? Моя собственная идея заключалась в следующем: поймать (ClassNotFound/)RuntimeException в DelegatingJavaSerializer и просто вернуть null в этом случае и позволить Wicket выполнять свою работу с автоматическим созданием новых экземпляров страниц. Более подробно это описано в списке пользователей. - person Thorsten Schöning; 24.11.2014
comment
Теперь вы говорите о пользователях, а не о разработке (я в вашем вопросе). Разные варианты использования требуют разных решений. Используйте BookmarkablePageLinks для перехода между страницами, чтобы свести к минимуму риск попадания по устаревшему URL-адресу. Не развертывайте новое приложение с каждым рефакторингом в рабочей среде (ваши пользователи будут вам благодарны), развертывайте приложение в кластере и позволяйте старым сеансам голодать в старой версии и отправляйте новые сеансы в новую версию приложения. - person Martijn Dashorst; 24.11.2014
comment
Я говорю о вас, я тот, кто развертывает, производство или нет. ;-) Я буду помнить о BookmarkablePageLinks, спасибо, но другие обходные пути не кажутся мне практическим решением. Это означало бы, что программное обеспечение с ошибками всегда будет рядом, а в настоящее время мы вообще не используем кластеризацию. Я попробую свой подход DelegatingJavaSerializer и посмотрю, как он работает. Интересно, почему Wicket ведет себя так... - person Thorsten Schöning; 25.11.2014