Bytecode representation of AnyVal wrappers

I have introduced refined(v0.9.17) into a project using sbt-findsecbugs(v0.16), and they don’t seem to like each other.

I could isolate the problem this far:

final class AnyValWrapper[T] private(val value: T) extends AnyVal

case class WrappedWrapper(w: AnyValWrapper[Long])

sbt-findsecbugs complains:

[error] The following errors occurred during analysis:
[info]   equals() used to compare non-object type(s) long and <long extra> in de.sangamon.anyvalbc.WrappedWrapper.equals(Object) at   63: invokevirtual[182](3) 114
[error] Analysis errors: 1

Comparing a long with a “long extra” would seem to sound pretty bad to me. There’s no evidence of this, though, AFAICS. The offending part of the bytecode, according to javap -v, is this:

37: aload_0
38: invokevirtual #63 // Method w:()Ljava/lang/Long;
41: aload         4
43: invokevirtual #63 // Method w:()Ljava/lang/Long;
46: astore        5
48: dup
49: ifnonnull     61
52: pop
53: aload         5
55: ifnull        69
58: goto          82
61: aload         5
63: invokevirtual #114 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z

Looks inconspicuous to me. But something’s a bit odd at #w()

public long w();
  descriptor: ()Ljava/lang/Long;

Here the signature declares a primitive while the descriptor (correctly, I assume), declares the native wrapper. I have no idea where this signature in the javap output is derived from, though - I see no trace of “long” (lowercase) in the constant pool… [EDIT: Neither a relevant occurrence of ‘J’.]

Does anybody have an idea what’s going on here? Is it a bug in sbt-findsecbugs, maybe getting confused over some irrelevant metadata in the byte code? Or is something more sinister afoot?

1 Like

Reported in the spotbugs tracker - including self-contained sbt sample project. Not sure this is the right place, though. Any insight as to whether this might or might not be a scalac bug would be highly appreciated.

The java.lang.Long <> long thing reminds me of this issue: https://github.com/scala/bug/issues/11321
Which scala version are you using?

I’m on Scala 2.13.3. The example from your issue report correctly shows

public scala.Option<X> b();

(Really nice, BTW, I didn’t know you could invoke javap from the REPL.)