Spring Core XML Config And Kotlin

Hey guys. I am relearning Kotlin and decided to use it in place of Java while going through a tutorial going through Spring XML configurations. Now I know Spring XML is old and Annotation based configurations (and even the new Kotlin based configuration) is the way to go. However, this isn’t necessary a Spring thing (hopefully) as more of a Kotlin thing.

First Question:

fun main(args: Array<String>) {
	var context = ClassPathXmlApplicationContext("activity_3.xml")

	val a = context.getBean("item1", ClassA::class) as ClassA
}

Why do we need to cast to ClassA here as we are explicitly saying we want ClassA? Is there a way to not cast here?

Second Question

When using prototype scope for beans (not singleton scope), why is Kotlin trying to call this constructor (note without it the program fails with org.springframework.beans.BeanInstantiationException / java.lang.IllegalArgumentException)

constructor(a: Any): this() {
println(a)
println(a::class)
}

The results of the print statements is the following:

class com.rtomyj.springtutorial.model.ClassA
class kotlin.reflect.jvm.internal.KClassImpl

In Java you don’t have to specify a special constructor.

Small disclaimer: I have never used spring, so I might get some things wrong, but those questions are kotlin specific so I should still be able to answer.
Question 1
It depends on the definition of getBean. My guess is that it is defined as something lik

fun getBean(name: String, clazz: Class<Any>): Any // probably in java, but you get the idea

This means that kotlin doesn’t know what type is actually returned. A similar version with generics would be

fun <T>getBean(name: String, clazz: Class<T>): T

Now you can still call it with

context.getBan("item1", ClassA:class)

but now the compiler knows that it will return an object of type ClassA. The compiler is smart enough to infer that T is of type ClassA.

Question 2
I’m not entirely if this will help you since you didn’t post the “entire” class definition. My guess is that you have a primary constructor defined. In that case every secondary constructor has to call it.
https://kotlinlang.org/docs/reference/classes.html#constructors

Hey thanks for the help.

So it turns out for the First question the method being called wasn’t the one I thought. There are two similar methods:

@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
	assertBeanFactoryActive();
	return getBeanFactory().getBean(name, requiredType);
}

@Override
public Object getBean(String name, Object... args) throws BeansException {
	assertBeanFactoryActive();
	return getBeanFactory().getBean(name, args);
}

The code I provided is using the second when I wanted the first. To get it to use the first method I changed the code to the following:

fun main(args: Array<String>) {
var context = ClassPathXmlApplicationContext("activity_3.xml")
val a = context.getBean("item1", ClassA::class.java)
}

adding the .java will force the compiler to use the Java class spec rather than the Kotlin as is what’s returned by ClassName::class. your response made me isolate the issue by messing around with Kotlin generics. Thanks!


For the Second question here is the full class:

data class ClassA(override var classB: ClassB? = null) : ClassB
{
	init
	{
		println("Class A: In init method")
	}

	constructor(classA: Any): this()
	{
		println(classA)
		println(classA::class)
	}
}

So in Java, Spring creates the object/bean using the default constructor (as I’m not using constructor injection). However in Kotlin it doesn’t call the default constructor when using a Bean Scope of prototype (but does for singleton). It instead tries to call a constructor using an arg. I made the constructor above accept anything and print out object info. However, it doesn’t make sense that the constructor is called here. And the print statements are also unexpected:

class com.rtomyj.springtutorial.model.ClassA
class kotlin.reflect.jvm.internal.KClassImpl