I am using javassist in a project and I need to create the following interface at runtime:
package com.example;
import org.springframework.data.repository.CrudRepository;
import com.example.Cat;
public interface CatRepository extends CrudRepository<Cat, Long> {}
While I had no problem creating the interface CatRepository
extending CrudRepository
, I do not understand (from the docs and from looking at the source code), how to specify com.example.Cat
and java.lang.Long
as generics types to the super-interface.
Please note that:
com.example.Cat
: created at runtime using javassist (no problems with that, I have also tested and it worksorg.springframework.data.repository.CrudRepository
: existent class from a library.
If any one could help with that it would be great!
Thanks! Luca
Short Answer
The generic information can be manipulated in Javassist using the SignatureAttribute.
Long answer (with code)
The code you probably already have is something like this:
But, like you already said this will not add the information about generics. In order to achieve the same bytecode you would get from compiling the source code, you need to do the following where the comment is:
Let's break down the signature string in order to understand what's happening there:
You see several L[TYPE], what is it? L is the standard notation in bytecode to define an Object Class, you can read more about this if you're interested in the JVM Specification regarding descriptors
';' is being used as a separator between several definitions. Let's look at each one of them:
<Lorg/example/Cat;Ljava/lang/Long;>
The first definition has to be there because in the Java language everything extends from java.lang.Object (doesn't matter if class or interface).
But the most interesting one is the second one, there you have your type with the full classname and the generic types definitions, everything using the L notation. That's what you are missing :-)
Note
Keep in mind that if you want to extend from more than one interface, you just have to add them in the list for example, the following signature would make the interface not only extend from CrudRepository but also from Serializable: