Issue with repeated Java 8 annotations


#1

Hi, I’m running into an issue with converting some Java 8 code into Kotlin. I have two annotations:

//Callback.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Repeatable(Callbacks.class)
public @interface Callback {
    Class<?> value();
}
//Callbacks.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Callbacks {
    Callback[] value();
}

And I am using them in Java 8 just fine.

//Demo.java
@Callback(Fizz.java)
@Callback(Buzz.java)
public class Demo {
    //......
}

But when I convert that class into a Kotlin class

//Demo.kt
@Callback(Fizz::class)
@Callback(Buzz::class)
class Demo {
    //......
}

I get the following error

Only annotations with SOURCE retention can be repeated on JVM version before 1.8

I’m not sure if this is a Kotlin/Java 8 incompatibility or I just have my project set up wrong. I should also note that the kotlin code above works fine if I only have one @Callback.
Thanks


Custom Bean Validation (JSR-303) Annotations
#2

Basically, the Kotlin compiler for now targets the jdk 1.6 class file format. This means that, on Java, it cannot write multiple annotations to the class file. While conceptually Kotlin supports multiple annotations, until there is proper 1.8 targeting (scheduled for 1.1), it cannot do so because of the output restrictions. Source level annotations are not written to the class file so there is no issue for that.

So, wait until 1.1, use a hack where you use the annotations in Java, or if possible, use a container annotation that contains a list of callbacks (the way this was done before 1.8).


#3

Okay thanks, that makes sense.


#4

Hi,I’m using Kotlin maven plugin version 1.1.1 and I’ve configured jvmTarget param with 1.8, but still have the same error
would you please give some advices?


#5

The same problem here. I am using 1.1.2-2 and configured kotlin with

compileKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
        javaParameters = true
    }
}

And still got the exception.


#6

Same here

@Configuration
@PropertySource("classpath:/default_appinfo.properties")
@PropertySource("classpath:/default_application.properties")
class ApplicationPropertiesConfiguration @Autowired constructor(val environment: Environment) 

fails with
Only annotations with SOURCE retention can be repeated on JVM version before 1.8


#7

We still don’t support repeatable annotations. The relevant issue is here.


#8

The workaround for this issue is to write something like

@MyAnnotations{
  MyAnnotation(<your regular annotation constructor>),
  MyAnnotation(<your regular annotation constructor>)
}

Not a big difference. Still compillator warning is a bit misleading.


Inherited annotations and other reflections enchancements
#9

We are hitting this at the moment. It’d be great if Kotlin 1.3 could focus on catching up with Java 8 because right now there are still a bunch of tasks where Java is actually better or easier to use than Kotlin - none of them are large, but it seems a shame whenever Java is ahead of Kotlin.


#10

FWIW, this issue is serious enough for me to take my project back to Java…I have to interface with a Java framework that makes extensive use of Annotations. The discovery that Kotlin is essentially Java 6 in this respect makes me sad :frowning: