重新启动 Vaadin 应用程序时抛出 java.io.NotSerializableException [英] java.io.NotSerializableException is thrown while restarting Vaadin application

查看:22
本文介绍了重新启动 Vaadin 应用程序时抛出 java.io.NotSerializableException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我重新启动 Tomcat 时,出现以下错误:

When I restart my Tomcat, I get the following error:

2014;10;01; 15;49;47;055; WARN; com.vaadin.event.ListenerMethod;[localhost-startStop-2]; Error in serialization of the application: Class com.aaa.bbb.MyServlet$1 must implement serialization.
2014;10;01; 15;49;47;055; WARN; org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/my-vaadin];[localhost-startStop-2]; Cannot serialize session attribute com.vaadin.server.VaadinSession.MyServlet for session ...
java.io.NotSerializableException: org.apache.catalina.loader.WebappClassLoader
    at java.io.ObjectOutputStream.writeObject0(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.writeObject0(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.writeObject0(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.writeObject0(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) ~[na:1.6.0_31]
    at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source) ~[na:1.6.0_31]
    at com.vaadin.event.ListenerMethod.writeObject(ListenerMethod.java:88) ~[vaadin-server-7.2.7.jar:7.2.7]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_31]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.6.0_31]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.6.0_31]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.6.0_31]
    ...

推荐答案

警告说匿名内部类(在 MyServlet 类中)必须实现序列化.我的 servlet 类只包含一个匿名内部类,它实现了 Serializable 并有一个 serialVersionUID:

The warning says that an anonymous inner class (within MyServlet class) must implement serialization. My servlet class contains only one anonymous inner class and it implements Serializable and have a serialVersionUID:

public class MyServlet extends VaadinServlet implements SessionInitListener {
    //...

    @Override
    public void sessionInit(SessionInitEvent event) throws ServiceException {
        event.getSession().addBootstrapListener(new BootstrapListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void modifyBootstrapPage(BootstrapPageResponse response) {
                //...
            }

            @Override
            public void modifyBootstrapFragment(BootstrapFragmentResponse response) {
                //...
            }
        });
    }
}

经过一番研究,我找到了解决方案:匿名类上的 NotSerializableException
所以我们要把匿名内部类改成静态嵌套类:

After a little research I found the solution: NotSerializableException on anonymous class
So we have to change the anonymous inner class to a static nested class:

public class MyServlet extends VaadinServlet implements SessionInitListener {
    //...

    @Override
    public void sessionInit(SessionInitEvent event) throws ServiceException {
        event.getSession().addBootstrapListener(new MyBootstrapListener());
    }

    private static class MyBootstrapListener implements BootstrapListener {
        private static final long serialVersionUID = 1L;

        @Override
        public void modifyBootstrapPage(BootstrapPageResponse response) {
            //...
        }

        @Override
        public void modifyBootstrapFragment(BootstrapFragmentResponse response) {
            //...
        }
    });
}

或者如果我们在反序列化后不想要多个对象:

Or if we don't want multiple objects after deserialization:

public class MyServlet extends VaadinServlet implements SessionInitListener {
    //...

    @Override
    public void sessionInit(SessionInitEvent event) throws ServiceException {
        event.getSession().addBootstrapListener(MyBootstrapListener.INSTANCE);
    }

    private static class MyBootstrapListener implements BootstrapListener {
        private static final long serialVersionUID = 1L;
        private static final MyBootstrapListener INSTANCE = new MyBootstrapListener();

        @Override
        public void modifyBootstrapPage(BootstrapPageResponse response) {
            //...
        }

        @Override
        public void modifyBootstrapFragment(BootstrapFragmentResponse response) {
            //...
        }

        private Object readResolve() {
            return INSTANCE;
        }
    });
}

这篇关于重新启动 Vaadin 应用程序时抛出 java.io.NotSerializableException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆