2012-06-22 2 views
1

Мы продолжаем получать исключение followng в нашем веб-приложении Java на основе JSF, и Googling об этом говорит о том, что это может быть вызвано управляемым приложением jsf управляемым bean-компонентом, который может быть сериализуемым.Создание @ApplicationScoped JSF управляемых bean-сериализуемых плохих методов?

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.apache.catalina.session.StandardSessionFacade 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source) 
    at java.io.ObjectInputStream.readSerialData(Unknown Source) 
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.readObject(Unknown Source) 
    at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1509) 
    at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:998) 
    at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:394) 
    at org.apache.catalina.session.StandardManager.load(StandardManager.java:321) 
    at org.apache.catalina.session.StandardManager.start(StandardManager.java:648) 
    at org.apache.catalina.core.ContainerBase.setManager(ContainerBase.java:446) 
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4631) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:779) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601) 
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:675) 
    at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:601) 
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:502) 
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1317) 
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324) 
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142) 
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1065) 
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840) 
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057) 
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463) 
    at org.apache.catalina.core.StandardService.start(StandardService.java:525) 
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:754) 
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) 
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) 
Caused by: java.io.NotSerializableException: org.apache.catalina.session.StandardSessionFacade 
    at java.io.ObjectOutputStream.writeObject0(Unknown Source) 
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) 
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source) 
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) 
    at java.io.ObjectOutputStream.writeObject0(Unknown Source) 
    at java.io.ObjectOutputStream.writeObject(Unknown Source) 
    at org.apache.catalina.session.StandardSession.writeObject(StandardSession.java:1585) 
    at org.apache.catalina.session.StandardSession.writeObjectData(StandardSession.java:1015) 
    at org.apache.catalina.session.StandardManager.doUnload(StandardManager.java:528) 
    at org.apache.catalina.session.StandardManager.unload(StandardManager.java:469) 
    at org.apache.catalina.session.StandardManager.stop(StandardManager.java:678) 
    at org.apache.catalina.core.StandardContext.stop(StandardContext.java:4882) 
    at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:936) 
    at org.apache.catalina.startup.HostConfig.undeployApps(HostConfig.java:1359) 
    at org.apache.catalina.startup.HostConfig.stop(HostConfig.java:1330) 
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:326) 
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142) 
    at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1098) 
    at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1110) 
    at org.apache.catalina.core.StandardEngine.stop(StandardEngine.java:468) 
    at org.apache.catalina.core.StandardService.stop(StandardService.java:604) 
    at org.apache.catalina.core.StandardServer.stop(StandardServer.java:788) 
    at org.apache.catalina.startup.Catalina.stopServer(Catalina.java:408) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.apache.catalina.startup.Bootstrap.stopServer(Bootstrap.java:338) 
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:416) 

Управляемый боб в вопросе впрыскивается сессия область действия фасоли в некоторых случаях с использованием @ManagedProperty аннотации.

Является ли это плохой практикой, или это что-то еще, чего я не понимаю?

ответ

0

Это связано с тем, что объект управления JSF не интегрируется с сериализацией Java. Если aBean зависит от anotherBean, экземпляр anotherBean вводится в aBean. Поскольку сериализация объекта также сериализует его поля, будет также сериализован другойBean, который в лучшем случае является пустой тратой памяти, а в худшем случае очень сложно реализовать (потому что у него могут быть зависимости, которые не могут быть сериализованы ...).

Достойный контейнер для инъекций зависимых, такой как CDI или Spring, решит эту проблему, введя сериализуемый прокси-сервер, делегирующий текущий другой бит в aBean. Это одна из причин, почему нужно поддерживать бобы в другом контейнере DI. (В JSF довольно просто использовать CDI или Spring-управляемые бобы).

Edit: Мои симпатии быть запертым в Java EE 5. В этом случае, вы могли бы:

  1. Не сохранять ссылки на приложения в области видимости боба, как зависимость, но искать его по имени, когда вы нужно это.
  2. Внесите сериализуемый прокси-сервер вашего компонента с областью приложения (или сделайте сам объект-фасоль сериализуемым). Это будет связано с подключением к механизму сериализации для сериализации компонента по имени и восстановления его при десериализации путем поиска.
  3. Разделите свои бобы на две части: один объект для зависимостей (область запроса), другой объект для состояния (с областью действия сеанса). Лично я нахожу это громоздким и запретительным для содержательной инкапсуляции бэкэнсов, но это вопрос вкуса.
+0

Проект Java EE 5 (CDI неподдерживается) – fledglingCoder

+0

А, тогда, см. Мое редактирование. – meriton

0

Хммм ... по моему мнению, управляемый bean-компонент @ApplicationScoped будет работать до тех пор, пока приложение будет развернуто. Другими словами, я думаю, что вам не нужно хранить и восстанавливать компонент, когда это необходимо. Он всегда должен быть там.

Вместо введения в @ApplicationScoped боб как @ManagedProperty из @SessionScoped фасоли, почему бы вам не попробовать внедрить его в @RequestScoped боба, а затем вводят эту @RequestScoped фасоль в ваш @SessionScoped боба. :)

+0

Благодарим вас за ответ, но RequestScoped bean был бы мертв к тому времени, когда закончится процесс HTTP-запроса/ответа, поэтому мне не имеет смысла вводить более низкоуровневый bean-компонент в более высокий. – fledglingCoder

+0

@fledglingCoder Как упоминалось выше в meriton, если вы введете '@ ApplicationScoped' в качестве свойства в свой« Serializable »bean, ваш компонент' @ ApplicationScoped' всегда будет сериализован, что приведет к вашему исключению. Если вы не переключитесь на использование CDI bean, вы должны сделать то, что я предлагаю, и получить доступ к тому, что вам нужно от компонента '@ RequestScoped'. –

+0

спасибо, но ваше предложение не применимо, потому что проект Java EE 5 (CDI невозможен), свойство, которое должно быть введено, находится в ApplicationScoped Bean, где он будет впрыснут в (и должен быть) компонент SessionScoped, Я удалил реализацию Serializable компонента Application Scoped и увидит, что произойдет. – fledglingCoder

0

org.apache.catalina.session.StandardSessionFacade Реализация Tomcat HttpSession. Таким образом, это исключение предполагает, что вы имеете в одном из вашего зрения/сессии контекстной управляемых компонентов следующего свойство:

private HttpSession session; 

Это совершенно неправильно. Вы никогда не должны этого делать. Эта же история относится к FacesContext, ExternalContext и всем ее артефактам. Они никогда не должны быть объявлены как свойство управляемого компонента, но всегда должны быть объявлены в локальной области потока (т. Е. Внутри того же блока методов, где они вам нужны).

Смежные вопросы