Java Hashset和Hashmap Jboss-RMI序列化异常,openJDK-1.8.0-312

发布于 2025-01-26 21:49:00 字数 1300 浏览 2 评论 0原文

由于我安装了OpenJDK-1.8.0-312补丁程序,因此在所有使用hashmaphashset的JBOSS-RMI调用中都有此错误。

这是使用OpenJDK-1.8.0,并且运行JBOSS为6.1.1:

2022-05-05 10:30:19,761 ERROR [STDERR]  ... 100 more
2022-05-05 10:30:19,761 ERROR [STDERR] Caused by: org.jboss.serial.exception.SerializationException: Excepted to be String
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.readUTF(DataContainer.java:1120)
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.persister.ObjectInputStreamProxy.readUTF(ObjectInputStreamProxy.java:196)
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.objectmetamodel.FieldsContainer.readField(FieldsContainer.java:147)
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.objectmetamodel.FieldsContainer.readMyself(FieldsContainer.java:218)
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.persister.ObjectInputStreamProxy.readFields(ObjectInputStreamProxy.java:224)
2022-05-05 10:30:19,761 ERROR [STDERR]  at java.util.HashSet.readObject(HashSet.java:298)
2022-05-05 10:30:19,763 ERROR [STDERR]  ... 104 more
2022-05-05 10:30:19,763 ERROR [STDERR] Caused by: java.lang.ClassCastException

有人遇到了这个错误吗?关于如何解决此问题的任何线索(不从方法中删除标签和哈希图)?

谢谢

Since I installed openjdk-1.8.0-312 patch I got this error in all JBoss-RMI invocations that use HashMap and HashSet.

This is using openjdk-1.8.0 and running JBoss as 6.1.1:

2022-05-05 10:30:19,761 ERROR [STDERR]  ... 100 more
2022-05-05 10:30:19,761 ERROR [STDERR] Caused by: org.jboss.serial.exception.SerializationException: Excepted to be String
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.readUTF(DataContainer.java:1120)
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.persister.ObjectInputStreamProxy.readUTF(ObjectInputStreamProxy.java:196)
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.objectmetamodel.FieldsContainer.readField(FieldsContainer.java:147)
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.objectmetamodel.FieldsContainer.readMyself(FieldsContainer.java:218)
2022-05-05 10:30:19,761 ERROR [STDERR]  at org.jboss.serial.persister.ObjectInputStreamProxy.readFields(ObjectInputStreamProxy.java:224)
2022-05-05 10:30:19,761 ERROR [STDERR]  at java.util.HashSet.readObject(HashSet.java:298)
2022-05-05 10:30:19,763 ERROR [STDERR]  ... 104 more
2022-05-05 10:30:19,763 ERROR [STDERR] Caused by: java.lang.ClassCastException

Has anyone gotten this error? Any clue on how to solve this (without removing HashSet and HashMap from methods)?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡写薰衣草的香 2025-02-02 21:49:00

我知道我已经迟到了两年了,但是我只是花了几天的时间来弄清楚这个确切的错误,所以我们去了。我有一个古老的JBOSS EAP 5.X服务器,我必须保持足够长的时间才能使开发人员团队从中完成移动服务。 (为什么是,我在企业中工作,你怎么说?)

这里的根本原因是jboss序列化。回到Java 4-ish Days Jboss创建了自己的序列化实现,比JVM中的序列化实现更快。这效果很好,直到在后来的Java 8版本中出现安全性的安全性,该版本打破了图书馆。这就是为什么尽管最初是为Java 8建造的,即使EAP 5.2.0和6.x断裂,也是为什么回滚回到JVM的早期补丁版本的原因。

JBOSS序列化实际上不再需要IMO了,因此,这里简单的修复是禁用它。在/deploy/ejb3-connectors-bean.xml中,查找InvokerLocator remotingConnector的属性,然后添加 serializationType 参数的参数

  <bean name="org.jboss.ejb3.RemotingConnector"
    class="org.jboss.remoting.transport.Connector">

    <property name="invokerLocator">

      <value-factory bean="ServiceBindingManager"
        method="getStringBinding">
        <parameter>
          jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3
        </parameter>
        <parameter>
          <null />
        </parameter>
        <parameter>socket://${jboss.bind.address}:${port}?timeout=300000&invokerDestructionDelay=5000&serializationType=java</parameter>
        <parameter>
          <null />
        </parameter>
        <parameter>3873</parameter>
      </value-factory>

    </property>
    <property name="serverConfiguration">
      <inject bean="ServerConfiguration" />
    </property>
  </bean>

类似的定义/exploys>/exploys/exploys>/exploys/exploys/exployploy/exployploy/exployploy/exployploy/exployploy/exployploy/exploys/exployploy/exploys/exploys>/exploye/exploys>/远程Jboss-beans.xml 。我很确定不再使用了,但是在此处添加参数也没有害处:

<bean name="UnifiedInvokerConfiguration" class="org.jboss.remoting.ServerConfiguration">
   <constructor>
      <!-- transport: Others include sslsocket, bisocket, sslbisocket, http, https, rmi, sslrmi, servlet, sslservlet. -->
      <parameter>socket</parameter>
   </constructor>
 
 
   <!-- Parameters visible to both client and server -->
   <property name="invokerLocatorParameters">
      <map keyClass="java.lang.String" valueClass="java.lang.String">
 
         <!-- Other map entries ... -->
          
         <entry><key>serializationType</key><value>java</value></entry>
 
      </map>
   </property>
    
</bean>

对于所有远程EJB调用,这应该禁用JBOSS序列化。 但是,,我确实发现了拦截器的另一个问题。 jboss-ejb3核库包含两个AOP拦截器,旨在检查服务是否意外调用本地提供的远程绑定,并将该调用转换为本地调用。表面上是个好主意,但是这些拦截器与serializationType参数相当。它们是硬编码的,将始终使用JBOSS序列化。我个人认为这是一个错误,但是JBOSS 5.x很快就不会得到补丁!

有两个非常简单的选择可以解决此问题。您当然可以更新服务以使用本地绑定。这将是首选的选项,但是显然,作为服务器管理员,很难预见到存在这些问题的地方,而且我们不想破坏当前有效的事情。

第二个选项是,您只需在/deploy/ejb3-interceptors-aop.xml中禁用拦截器即可。我不确定我是否可以推荐这样做,因为我遇到了问题。它将对任何错误使用其自己的远程绑定的服务产生负面的性能影响,因为这些调用实际上将被派往远程服务器。它还可能与跨服务交易混乱。我禁用拦截器的最初测试解决了一项服务中最初观察到的错误,但立即在另一个服务中造成了交易错误。我有一种令人沮丧的感觉,我最终将建立自己的版本的jboss-remoting-apepts,或者在执行堆栈和强制使用JVM Serialization下方的其他版本。

更新2025-01-13:我实际上确实进行了修补jboss-ejb3核,编辑islocalInterpector使用serializationmanagerfactory以获取适当的序列化器基于服务器设置,就像其他地方一样。但是,这导致了最终的并发症:JBOSS序列化与JDK中的序列化没有相同的严格要求。一方面,它不需要您实现序列化。十多年来,我无法想象需要进行所有这些检测和测试才能纠正所有这些。长话短说,我们正在咬着子弹,然后用本地呼叫代替任何不必要的远程呼叫,以使拦截器首先从未开火。

显然,这篇文章引用了JBoss 5.X,但希望它能使任何人阅读此内容的起点,供以后版本查看。我发现许多人在网上遇到这个问题,但没有具体的修复程序,所以直到答复是我希望它仍然对某人有用。

I know I'm two years late to this one, but I just spent days figuring this exact error out so here we go. I have an ancient JBoss EAP 5.x server I have to keep running long enough for the dev team to finish moving services out of it. (Why yes, I do work in enterprise, how could you tell?)

The root cause here is JBoss Serialization. Back in the Java 4-ish days JBoss created their own serialization implementation to be quicker than the one in the JVM. This worked fine until security fixes to deserialization appeared in later versions of Java 8, which broke the library. This is why even EAP 5.2.0 and 6.x break despite being originally built for Java 8, and why rolling back to earlier patch versions of the JVM works.

JBoss Serialization isn't really needed any more IMO, so the easy fix here is to disable it. In /deploy/ejb3-connectors-bean.xml, find the invokerLocator property of RemotingConnector and add the serializationType parameter to the invocation URL, like this:

  <bean name="org.jboss.ejb3.RemotingConnector"
    class="org.jboss.remoting.transport.Connector">

    <property name="invokerLocator">

      <value-factory bean="ServiceBindingManager"
        method="getStringBinding">
        <parameter>
          jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3
        </parameter>
        <parameter>
          <null />
        </parameter>
        <parameter>socket://${jboss.bind.address}:${port}?timeout=300000&invokerDestructionDelay=5000&serializationType=java</parameter>
        <parameter>
          <null />
        </parameter>
        <parameter>3873</parameter>
      </value-factory>

    </property>
    <property name="serverConfiguration">
      <inject bean="ServerConfiguration" />
    </property>
  </bean>

There's a similar definition in /deploy/remoting-jboss-beans.xml. I'm pretty sure that one's not used any more, but no harm in adding the parameter there too:

<bean name="UnifiedInvokerConfiguration" class="org.jboss.remoting.ServerConfiguration">
   <constructor>
      <!-- transport: Others include sslsocket, bisocket, sslbisocket, http, https, rmi, sslrmi, servlet, sslservlet. -->
      <parameter>socket</parameter>
   </constructor>
 
 
   <!-- Parameters visible to both client and server -->
   <property name="invokerLocatorParameters">
      <map keyClass="java.lang.String" valueClass="java.lang.String">
 
         <!-- Other map entries ... -->
          
         <entry><key>serializationType</key><value>java</value></entry>
 
      </map>
   </property>
    
</bean>

That should disable JBoss Serialization for all remote EJB invocations. However, I did find one more issue with Interceptors. The jboss-ejb3-core library contains two AOP interceptors that are designed to check if a service is accidentally calling a remote binding that is provided locally, and turn that call into a local invocation instead. Good idea on the surface, but these interceptors do not have an equivalent of the serializationType parameter. They are hard-coded and will always use JBoss Serialization. Personally I consider this a bug, but JBoss 5.x ain't getting patches any time soon!

There are two pretty simple options to work around this. You can of course update your services to use local bindings. That would be the preferred option, but obviously as a server admin it's hard to anticipate where these issues are present and we don't want to go breaking things that currently work.

The second option is that you simply disable the interceptors in /deploy/ejb3-interceptors-aop.xml. I'm not sure I can recommend doing this, as I've had issues with it. It will have a negative performance impact on any service that incorrectly uses its own remote bindings, as those calls will actually get dispatched to the remoting server. It can also mess with transactions across services. My initial tests with disabling the interceptor resolved the initially observed bug in one service, but immediately caused transactional errors in another. I have a sinking feeling I'm going to end up building my own version of jboss-remoting-aspects or something further down the execution stack and force usage of JVM serialization.

Update 2025-01-13: I did actually patch jboss-ejb3-core, editing the IsLocalInterceptor to use the SerializationManagerFactory to fetch an appropriate serializer based on server settings, as works elsewhere. However, this led to one final complication: JBoss Serialization doesn't have the same strict requirements as serialization in the JDK. For one thing, it doesn't require you to implement Serializable. After over a decade, I can't imagine the amount of detection and testing that would need to be done to correct all of these. Long story short, we're biting the bullet and going through to replace any unnecessary remote calls with local ones, so that the interceptor never fires in the first place.

Obviously this post references JBoss 5.x but hopefully it gives anyone reading this a starting point for where to look on later versions. I found a number of instances of people running into this issue around the net, but no concrete fixes, so as late as the reply is I hope it's still of use to someone.

抚你发端 2025-02-02 21:49:00

尝试切换回OpenJDK的先前版本。

Try switching back to previous versions of openjdk.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文