Ошибка после обновления - NotSerializableException: java.io.FileInputStream

Сергей Беляков добавил(а) 1 нед. назад
Решена

Еще одна ошибка после обновления до 6.6.3:

InputStream inputStream = new FileInputStream(file);

и

InputStream inputStream = signatureUploadBtn.getFileContent();

, где signatureUploadBtn - это компонент FileUpload.

Выдают ошибку: java.io.NotSerializableException: java.io.FileInputStream

Причем перенеся new FileInputStream(file) из сервиса в web, ошибка пропала !

Что делать с FileUpload, непонятно.

java.io.NotSerializableException: java.io.FileInputStream
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at com.haulmont.cuba.core.sys.serialization.StandardSerialization.serialize(StandardSerialization.java:34)
	at com.haulmont.cuba.core.sys.serialization.StandardSerialization.serialize(StandardSerialization.java:80)
	at com.haulmont.cuba.core.sys.serialization.SerializationSupport.serialize(SerializationSupport.java:60)
	at com.haulmont.cuba.web.sys.remoting.LocalServiceProxy$LocalServiceInvocationHandler.invoke(LocalServiceProxy.java:123)
	at com.sun.proxy.$Proxy73.getX509Certificate(Unknown Source)
	at ru.test.test.gui.extuser.ExtUserEdit.lambda$init$2(ExtUserEdit.java:121)
	at com.haulmont.bali.events.EventRouter.fireEvent(EventRouter.java:45)
	at com.haulmont.cuba.web.gui.components.WebFileUploadField.fireFileUploadSucceed(WebFileUploadField.java:443)
	at com.haulmont.cuba.web.gui.components.WebFileUploadField.lambda$initUploadButton$982e378a$1(WebFileUploadField.java:264)
	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 com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:510)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:200)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:163)
	at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1037)
	at com.haulmont.cuba.web.toolkit.ui.CubaFileUpload.fireUploadSuccess(CubaFileUpload.java:474)
	at com.haulmont.cuba.web.toolkit.ui.CubaFileUpload$1.fileUploaded(CubaFileUpload.java:72)
	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 com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:119)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:444)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:409)
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:274)
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90)
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1436)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:385)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:301)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:192)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at com.haulmont.cuba.web.sys.CubaHttpFilter.handleNotFiltered(CubaHttpFilter.java:108)
	at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:95)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

Комментарии (8)

фото
1

Здравствуйте,

Начиная с версии 6.5 мы полностью запретили передавать в сервисы объекты, которые не являются Serializable. Это связано с тем, что в распределённых вариантах развёртывания, например в кластере core - web ваш код, который работал в одном экземпляре Tomcat может перестать работать. Теперь поведение полностью унифицировано и от вас требуется, чтобы все объекты которые передаются в параметры сервисов и возвращатся в качестве результата были Serializable.

Не могли бы вы приложить полный код обработчика FileUploadSucceed из (ExtUserEdit.java:121)?

фото
1

Вот вызов, компоненты FileUploadField

@Inject
private FileUploadField signatureUploadBtn;

signatureUploadBtn.addFileUploadSucceedListener(e -> {
            InputStream inputStream = signatureUploadBtn.getFileContent();        
});

фото
1

В вашем стеке вызова есть код:

	at com.sun.proxy.$Proxy73.getX509Certificate(Unknown Source)
	at ru.test.test.gui.extuser.ExtUserEdit.lambda$init$2(ExtUserEdit.java:121)

Не могли бы вы приложить сигнатуру метода getX509Certificate ? Похоже что этот метод объявлен в сервисе, так ли это?

И судя по стактрейсу именно этот вызов, а не getFileContent приводит к исключению. В вашем случае я рекомендую либо передать в сервис массив байт, либо переписать код, чтобы файл пересылался при помощи HTTP сервиса.

фото
1

signatureUploadBtn.addFileUploadSucceedListener(e -> {
            InputStream inputStream = signatureUploadBtn.getFileContent();
            X509Certificate x509Certificate = signatureService.getX509Certificate(inputStream);}

public X509Certificate getX509Certificate(InputStream inputStream)
    {
        X509Certificate x509Certificate = null;
        try
        {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            x509Certificate = (X509Certificate) cf.generateCertificate(inputStream);
            inputStream.close();
        }
        catch (CertificateException e) {Logger.getLogger(SignatureServiceBean.class.getName()).log (Level.SEVERE, null, e);}
        catch (IOException e) {Logger.getLogger(SignatureServiceBean.class.getName()).log (Level.SEVERE, null, e);}

        return x509Certificate;
    }

фото
1

Как видно из сигнатуры getX509Certificate вы передаёте в сервис InputStream, который не является Serializable. Проще всего будет получить byte[] массив в обработчике кнопки и передать его в метод сервиса. Для получения byte[] массива можно воспользоваться org.apache.commons.io.IOUtils

byte[] bytes = IOUtils.toByteArray(signatureUploadBtn.getFileContent());

фото
1

А можно тогда попутно вопрос ?

А как преобразовать обратно из byte в InputStream ?

фото
2

Воспользуйтесь java.io.ByteArrayInputStream

фото
1

Спасибо за помощь.

Сейчас все работает.

фото