2.8.13 release doesn't work with Java 8

The new 2.8.13 release doesn’t appear to work with Java 8.
I believe this is because it was built with a newer version of Java, as in later versions of Java, the ByteBuffer class started overriding the .flip() method, which causes javac to generate incorrect linkages to ByteBuffer.flip() instead of Buffer.flip() that don’t exist in Java 8:

java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer;
at org.snmp4j.security.AuthGeneric.passwordToKey(AuthGeneric.java:313)
at org.snmp4j.security.SecurityProtocols.passwordToKey(SecurityProtocols.java:313)
at org.snmp4j.security.USM.addUser(USM.java:892)

We encountered a similar issue with the Apache MINA SSHD project in their 2.9.0 release (see [SSHD-1285] 2.9.0 release broken on Java 8 - ASF JIRA).

The fix is to either strictly build using JDK version 8 only or to conditionally add the “8” flag to maven-compiler-plugin if the build JDK is > 8 (see [SSHD-1285] Fix runtime linkage errors with Java 8 when building with… by norrisjeremy · Pull Request #235 · apache/mina-sshd · GitHub for the fix we submitted to their project).

The build was done with OpenJDK 18.0.02 and the target release was set in the maven-compiler-plug-in to 1.8.
I will investigate this, maybe it is a bug in the JDK but maybe the configuration needs to be changed too.

Also probably should unconditionally add the <release> item in 3.x releases as well, to avoid any binary compatibility issues there too:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.10.1</version>
    <configuration>
        <source>9</source>
        <target>9</target>
        <release>9</release>
        <encoding>UTF-8</encoding>
        <compilerArgument>-Xlint:all</compilerArgument>
    </configuration>
</plugin>

FYI, using just the following in Maven isn’t sufficient in JDK versions > 9 to ensure binary compatibility with Java 8 at runtime:

<source>1.8</source>
<target>1.8</target>

It also requires the new <release> parameter:

<release>8</release>

This coerces javac to ensure Java 8 binary compatibility (by passing the new --release 8 param & thus handling cases such as this, in which newer Java releases define new method overloads in ByteBuffer that override parent methods inherited from Buffer).

In all of our projects that must maintain Java 8 binary compatibility, we add a new profile definition into pom.xml that automatically triggers the addition of this parameter whenever the build JDK is > 8:

<profile>
  <id>javac-jdk9+</id>
  <activation>
    <jdk>[9,)</jdk>
  </activation>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <release>8</release>
        </configuration>
      </plugin>
  </build>
</profile>

Funny stuff, this maven.compiler.release option. I have really overseen this for years now although I already recognised that the maven.compiler.target option did not work as expected. What I really expected was that the Java folks would fix the target option (i.e., extending its scope on the API level) instead of inventing a third option.

OK, you never stop learning :wink:. Thus, I will add the release option to all SNMP4J* pom.xml specification and will release new builds accordingly.

Thanks for the updated 2.8.14 release, we’ve confirmed it no longer throws an exception with Java 8!