scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

We need meta-annotations to control placement of runtime visible annotations #1846

Closed scabug closed 13 years ago

scabug commented 15 years ago

If you compile the class

import _root_.javax.persistence._

@Entity class JPA {

  @Id var someId: Int = _

}

scalac puts the @Id-annotation on the private field:

Field name: 3=someId private Signature: 4=int
Attribute "RuntimeVisibleAnnotations", length:6

as well as on the accessors:

Method name:15="someId_$$eq" public Signature: 16=(int)void
Attribute "Code", length:58, max_stack:2, max_locals:2, code_length:6
  0: aload_0
  1: iload_1
  2: putfield SI-20=<Field JPA.someId int>
  5: return
Attribute "LineNumberTable", length:6, count: 1
  line: 5 at pc: 0
Attribute "LocalVariableTable", length:22, count: 2
  slotSI-0: name: 21=this, type: 22=JPA (pc: 0 length: 6)
  slotSI-1: name: 23=x$$1, type: 4=int (pc: 0 length: 6)
Attribute "RuntimeVisibleAnnotations", length:6

Method name:3="someId" public Signature: 25=()int
Attribute "Code", length:29, max_stack:1, max_locals:1, code_length:5
  0: aload_0
  1: getfield SI-20=<Field JPA.someId int>
  4: ireturn
Attribute "LineNumberTable", length:6, count: 1
  line: 5 at pc: 0
Attribute "RuntimeVisibleAnnotations", length:6

This is deep within undefined behavior territory in JPA.

Eclipselink copes just fine (I think it just ignores the methods), while OpenJPA seems to identify the methods as annotated property accessors and complains that the entity uses field access on someId and property access on someId() and someId_$$eq().

This severely limits the interoperability with java, since you cannot write a JPA entity using field access that will be accepted by OpenJPA.

scabug commented 15 years ago

Imported From: https://issues.scala-lang.org/browse/SI-1846?orig=1 Reporter: Florian Hars (florian)

scabug commented 15 years ago

Florian Hars (florian) said: Another situation where the defaulf may be problematic are annotations on @BeanProperty getters and setters, see http://www.nabble.com/Scala-%40BeanProperty-with-other-annotations-to22844596.html

So @Id @BeanProperty var id = 0 can have 31 different interpretations, and we need a concise way to choose among the useful ones.

scabug commented 15 years ago

@dragos said: This seems important, but we don't have much experience with JPA. I think the best way to handle this ticket is to start a [http://www.scala-lang.org/node/233 SIP]. You could put your ideas up for discussion on scala-debate and see what other people think.

scabug commented 15 years ago

@retronym said: We just had a related discussion on scala-users r1

I just encountered a similar problem when attempting to annotate a field with the @Autowired annotation from Spring. Spring looks for this annotation on fields and methods. Normally, one would choose to annotated the field, or a setter.

There was a suggestion on that thread to use the forthcoming support for nested annotations in 2.8.0 to use such a meta-annotation along these lines:

class Foo {
    // Specific case.
    @FieldAnnotation(value=@Autowired)
    def myField

    // or more generally.
    @TargetedAnnotation(targets={@Field, @BeanPropertyAccessor}, value=@Autowired)
    def myField
}

The typical use case would be to target the annotation to exactly one of the field, scala mutator, scala accessor, bean property mutator, bean property accessor.

Ideally, the meta-annotation should be extensible, so that new compiler plugins that generate potential annotation targets could be used in addition to this meta-annotation. If this were achieved, @BeanProperty would not be treated specially by the compiler.

1 http://www.nabble.com/-scala--Annotating-a-field-without-annotating-the-associated-methods---Spring--%40Autowired-annotation-td23596908.html

scabug commented 15 years ago

James Strachan (jstrachan) said: BTW I raised this issue for a suggestion of how we can add more natural support for Java annotation-based frameworks like IoC and JPA frameworks to Scala - without end users having to use nested annotations (which IMHO adds lots of noise to the end user and it not very DRY)

http://lampsvn.epfl.ch/trac/scala/ticket/2245

scabug commented 15 years ago

Chris Herron (cherro) said: I disagree with this enhancement request. I have suggested a simpler solution in #2252.

scabug commented 15 years ago

@lrytz said: fixed in r18787 and r18829

scabug commented 15 years ago

Florian Hars (florian) said: The documentation does not mention if annotating with e.g. @beanGetter will suppress the default annotation on the field or not, "will be added to the bean getter" may be read either way.

scabug commented 13 years ago

Antony Stubbs (astubbs) said: Great - where is the documentation for the fix?

scabug commented 13 years ago

@retronym said: http://www.scala-lang.org/api/current/index.html#scala.annotation.target.package