I have converted a REST resource in a JEE application formally written in Java to Kotlin. The application runs in a Wildfly Application Server with Weld as Dependency Injection framework.
This is the final implementation I came up with:
@Path("/myResource")
open class MyResource {
@Context
private lateinit var context: SecurityContext
open protected setSecurityContext(securityContext: SecurityContext) {
this.context = securityContext
}
@POST
@Path("/change")
@Transactional
@Consumes(MediaType.APPLICATION_JSON)
open internal fun change(data: MyChangeData, @Context uriInfo: UriInfo): Response {
// ...
}
}
The setter is for testing purposes. With Mockito or other mocking frameworks that can set private fields this is not neccessary.
I had some issues with this implementation:
- I had to change the class and all methods to
open
to allow the CDI Container to create a proxy for this bean. As I understand this topic there is no other way to allow Weld to do its work without allowing subclassing? - Generally Kotlin generates setters and getters for properties with the given modifier (public/private/protected) backed by a private field. But when using
lateinit
the field is generated with the same visibility as the getters and setters (Kotlin in Action, p. 146). I don't understand the background for this special behaviour. Usingpublic
property causes an error in Weld reporting that public fields are not allowed. How can I declare that the field should be private but the getter and setter is protected (to initialize the Resource in tests)? - What is annotated in the code above? The field or the generated methods? If it is the field: How can I annotate the setter only?
- Because all methods but private ones have to be
open
all properties but private ones are rejected by the Weld container: Kotlin creates Getters and Setters with the same visibility and the container tries to proxy the bean proxying all methods for the bean. This does not work because the generated getters and setters are notopen
. For private properties there simply is no problem because the container does not proxy private methods. As I see there is no possibility to declare a getter/setter asopen
therefor it is not possible to use protected properties
EDIT: Added Ploblem 4 and changed the Implementation because of this problem to private with a setter.