views:

113

answers:

1

I've ran into a problem recently while developing with Spring Security. It has an interface GrantedAuthority with following signature:

public interface GrantedAuthority extends Serializable, Comparable

And as for Java 1.5 and later, the interface Comparable takes a type parameter T, which is omitted in Spring Security libraries (obviously, for JVM 1.4 compatibility).

So I am trying to implement GrantedAuthority in Scala.

class Role extends GrantedAuthority {
  . . .
  def compareTo(obj: Any): Int = obj match {
    case (r: Role) => r.toString.compareTo(this.toString)
    case _ => -1
  }
}

It does not compile:

error: class Role needs to be abstract, since method compareTo in trait Comparable of type (T)Int is not defined

How can I implement such interface in Scala?

+4  A: 

Interop problems with Java Generics come in (at least) two forms:

  1. Java code that omits type arguments, as in your example, leads to 'raw types'. Comparable is treated as the existential type Comparable[_]. Sometimes you can cast your way out of this problem. However, I don't see a way to implement def compareTo(other: _) = ... in this case.
  2. Java generics don't have a notion of declaration site variance. To extend Comparable[T] with a contravariant scala trait Ordering[-T] an error would occur unless you use the @uncheckedVariance annotation. (Discussion on the mailing list)

I suggest you try to upgrade to Spring 3.x which is compiled against Java 1.5. If this is not possible, write a base class BaseGrantedAuthority in Java that implements compareTo and delegates to a template method that can implemented in Scala.

retronym
I was interested in this interop problem, rather than solving my particular case -- you showed me the point perfectly. Thanks!
incarnate