1

我有一个 bean,它包含对 JSF 组件(确切地说是primefaces 组件)的引用。

根据规范,JSF 组件不可序列化。我的 Web 应用程序在 JBoss 集群中运行,并且需要分发 bean,这意味着它们需要可序列化。因此,

因此,每当我使用其支持 bean 是具有 JSF 组件引用的页面时,我都会遇到此异常:

Caused by: java.lang.RuntimeException: Failure to marshal argument(s)
   at org.infinispan.remoting.transport.jgroups.CommandAwareRpcDispatcher.marshallCall(CommandAwareRpcDispatcher.java:257)
   at org.infinispan.remoting.transport.jgroups.CommandAwareRpcDispatcher.processSingleCall(CommandAwareRpcDispatcher.java:274)
   at org.infinispan.remoting.transport.jgroups.CommandAwareRpcDispatcher.invokeRemoteCommand(CommandAwareRpcDispatcher.java:165)
   ... 74 more
Caused by: org.infinispan.marshall.NotSerializableException: org.primefaces.component.fileupload.FileUpload
Caused by: an exception which occurred:
   in field uploadComponent
   in field bean
   in object java.util.HashMap@0
   in object org.jboss.as.clustering.SimpleMarshalledValue@0
   in object org.infinispan.atomic.PutOperation@1fe7028
   in object java.util.LinkedList@90f00d5b
   in object org.infinispan.atomic.AtomicHashMapDelta@46933
   in object org.infinispan.commands.write.PutKeyValueCommand@515ccf63
   in object org.infinispan.commands.tx.PrepareCommand@1aaebdcd 

我检查了 infinispan 文档,发现实际上可以使用 AdvancedExternalizers 处理更细粒度的组件编组(包括那些不实现 Serializable 的组件)。

所以我为non-Serializable jsf组件写了一个,如下图:

public static class FileUploadExternalizer implements AdvancedExternalizer<FileUpload> {

        private static final long serialVersionUID = 1L;

        @Override
          public void writeObject(ObjectOutput output, FileUpload fileUpload)
                throws IOException {

          }

          @Override
          public FileUpload readObject(ObjectInput input)
                throws IOException, ClassNotFoundException {
             return new FileUpload();
          }

          @SuppressWarnings("unchecked")
         @Override
          public Set<Class<? extends FileUpload>> getTypeClasses() {
             return Util.<Class<? extends FileUpload>>asSet(FileUpload.class);
          }

          @Override
          public Integer getId() {
             return null;
          }
       }

其中 FileUpload 是不可序列化的 jsf(primefaces)组件。

对于独立的 infinispan,可以使用 infinispan 配置元素中的 xml 配置向 infinispan 注册 Externalizer 类,如下所示:

<infinispan>
  <global>
    <serialization>
      <advancedExternalizers>
        <advancedExternalizer externalizerClass="..."/>
      </advancedExternalizers>
    </serialization>
  </global>
  ...
</infinispan>

问题是当从 JBoss 7 容器中使用 infinispan 时,配置是不同的。配置在 jboss7 Standalone.xml(或任何其他配置 xml 文件)中完成。

不幸的是,在 Jboss7 中,无法配置元素。根据关于 infinispan 配置的 jboss7 文档,

Where is <global/>?
Much of the global configuration contains references to other JBoss AS services. In JBoss AS 7, these services are auto-injected behind the scenes. This includes things like thread pools (described below), the JGroups transport (also described below), and the mbean server.

这让我可以选择通过代码进行注册。所以我创建了一个应用程序范围的接缝组件来在那里进行注册:

@Name("infinispanExternalizerRegistration")
@Scope(ScopeType.APPLICATION)
@Startup
public class InfinispanAdvancedExternalizerRegistration {

    @Create
    public void init(){

        GlobalConfigurationBuilder builder = new GlobalConfigurationBuilder();
        builder.serialization().addAdvancedExternalizer(2345, new PhotoUploader.FileUploadExternalizer());

    }
}

但是,我仍然得到这个问题开头描述的 NotSerializableExceptions。这是正确的行为吗?还是我的 AdvancedExternalizer 真的因为一些错误的配置而无法工作?提前感谢您的帮助。

4

1 回答 1

0

交叉发布到https://community.jboss.org/message/754711#754711,在那里查看我的答案。

于 2012-08-22T10:59:57.507 回答