0

This is hard to describe, so I hope I make this clear.

We compile a large application containing many EJB's and Java Swing client code into a typical class file hierarchy. We then build a .EAR containing all compiled classes and deploy the .EAR to Weblogic 12.2.1.3.

In Eclipse, we define a run configuration for the local Java Swing client. The run config classpath points to the local package root of the compiled classes on the development machine.

So we have (a) compiled class hierarchy; (b) the same classes deployed in an .EAR on the server.

We start Weblogic and then run the local Swing client.
Weblogic and the client run in different Java 8.x JVM's.

The local client calls Weblogic, causing remote JNDI lookup of EJB's.
Most of it works fine.

PROBLEM

We occasionally get a seemingly random error, for example: [java] java.io.InvalidClassException: com.framework.SomeEjbImpl; local class incompatible: stream classdesc serialVersionUID = 6099783323740404732, local class serialVersionUID = -7124492888158518181

Note that the exception only occurs on EJB's which do not have an explicitly declared serialVersionUID.
If I add an ID to the failed class then recompile and redeploy, then some other EJB without a declared serialVersionUID will fail... a bump in the rug problem.

The problem might not appear for some time, then one day, it appears. After wasted hours of cursing recompiling and redeploying, it eventually hides for a while, only to appear maybe a week later. We have also tried cleaning out the cache and tmp folders in the Weblogic domain, then clean build, redeploy the .EAR. This seems to have no effect.

Having made no changes to the compiled classes, why is the serialVersionUID different between stream and local?

J Slick
  • 929
  • 11
  • 17

1 Answers1

0

From the java.io.Serializable documentation...

If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.

Since you said Weblogic and the client run in different Java 8.x JVM's, then you're going to hit the above problem using the default jvm generated serialVersionUID. The fix is to explicitly specify the serialVersionUID for all the request and response classes used by your EJB interfaces.

httPants
  • 1,832
  • 1
  • 11
  • 13
  • Thank you httPants. I know about what you posted. However, this goofy system usually works for the EJB's which lack an explicit serialVersionUID. Occasionally, the InvalidClassException occurs on a seemingly random EJB. So I wonder why it is inconsistent. It may work alright for a couple of weeks, then throw the exception. – J Slick Nov 11 '22 at 17:13