I have a Maven parent POM that configures the Maven Compiler Plugin like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<configuration>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<compilerArgs>
<arg>-Xlint:all</arg>
</compilerArgs>
</configuration>
</plugin>
The project uses Java 21. According to the Java 21 javac docs, -Xlint:all
"Enables all warnings." One of those warnings is:
serial
: Warns about the serializable classes that do not provide a serial version ID. Also warns about access to non-public members from a serializable element.
In the project I create an anonymous subclass without providing a serialVersionUID
. (Specifically I create a Jackson deserializer instance new FromStringDeserializer<FooBar>(FooBar.class) { … }
, although the specific class and library are not relevant to this issue.) Eclipse EE 2025-06 duly shows a warning in the IDE:
The serializable class does not declare a static final serialVersionUID field of type long
However building the project using Maven 3.9.10 with mvn clean compile
on Windows 10 with Java 24 does not show any warning.
Here is a small POM to reproduce the issue:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>serialversionid-check</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>serialversionid Check</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>21</maven.compiler.release>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<configuration>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<compilerArgs>
<arg>-Xlint:all</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
Here is the source file src/main/java/com/example/Test.java
to reproduce the issue:
package com.example;
public class Test {
void test() {
new Number() {
public double doubleValue() {return 0.0;}
public float floatValue() {return 0.0f;}
public int intValue() {return 0;}
public long longValue() {return 0L;}
};
}
}
Granted I'm not a big fan of this warning; and I am fully aware that this is a legacy approach to Java serialization and that use of this antiquated subsystem for actual serialization should be avoided. Nevertheless I would like some consistency across environments, and I'm puzzled as to why javac
is not showing the warnings its documentation indicates it should.
Why does javac 21 not produce warnings for missing serial version ID, even though the Maven Compiler Plugin is passing it the -Xlint:all
configuration?
The described behavior was real, but the subtlety is that the serializable class in question was an anonymous inner class, and javac
no longer displays this warning for anonymous inner classes (see below). This is why in most cases no one one noticed a discrepancy: javac
usually honors the Xlint serial
setting and generates a warning when a serial version ID is missing from a class marked serializable. (This also explains why this question kept getting closed: several people attempted to reproduce the problem using a test case that did not use an anonymous subclass.)
Serializing of anonymous inner classes poses various problem, so Java advises against it. This means it is pointless to include a serial version ID in anonymous inner classes, so in JDK-7152104 Java removed the warning from javac
in this situation. (Thanks for finding that JDK ticket, Mark.)
This means that the warning Eclipse currently shows is not in line with javac
behavior. I thus filed Eclipse JDT Core Issue #4209. It turns out that back in 2011 (almost 15 years ago!) a similar issue for the same problem had already been filed with Eclipse on Bugzilla as Eclipse Bug 343858 (and a duplicate filed as Eclipse Bug 426320), but had grown stale and was automatically closed in 2019.
The Eclipse team has now already addressed the issue I opened, and the discrepancy is scheduled to be fixed in Eclipse 4.37 M2, due out in a few days. It appears that if all goes well Eclipse behavior will come into line with that of javac
in the coordinated Eclipse 2025-09 release in a couple of months.