Is there a mechanism in Kotlin that could trigger ...
# announcements
j
Is there a mechanism in Kotlin that could trigger the init on an object / class without having to call a blank function?
Copy code
class TestClass {

	init {
		println("????????????")
	}

	companion object {
		init {
			println("!!!!!!!!!!!!!")
		}

		fun touch() {
			// empty function to trigger init
		}
	}
}

object TestObject {
	init {
		println(">>>>>>>>>>>>>>>>>")
	}

	fun touch() {
		// empty function to trigger init
	}
}
In my main, i literally have to call touch before the TestObject and TestClass' init is called
Copy code
@JvmStatic
	fun main(args: Array<String>) {
		TestClass.touch()
		TestObject.touch()
	}
i'm tryin to implement some form of inversion of control where classes register themselve to a central place My use-case is building the equivalent of a Controller, but instead of wiring in URLs in a central place, each Controller wires itself in to the central point
n
pretty sure this is just how the JVM works; class initializers aren't called until something references the class
j
What are my options for triggering class referencing, i'm assuming annotation processors are my only option here ?
n
you could perhaps use something like https://docs.oracle.com/javase/9/docs/api/java/util/ServiceLoader.html or reflection to scan for every class that implements an interface, and then poke them
conceptually, something like
getClassesImplementing(RequiresInitializationInterface::class)
might be sufficient
classpath scanning isn't particularly fast though, to say the least
serviceloader is moderately faster but requires maintaining a separate text file
https://stackoverflow.com/a/9240969/341772 this is maybe the way to go for the reflection route
j
yeah, was trying to escape classpath scanning, typical Spring projects from what i remember do that and when they get big, startup times are very slow seems one way or another i'd either be doing classpath scanning, annotation scanning or keeping a list of classes somewhere
this service load mechanism looks interesting, let me dig through that, thanks for the links!
b
Why don't you just write an annotation processor with kapt that inserts "touch" methods and calls at compile time?
👍 1
n
I think he's trying to avoid writing an annotation processor
👍 1
j
any kind of thing that scans classes causes startup slowdown, in large projects, this can often add up to 10 seconds on startup whereas now my startup times are a fraction of a second how does kapt handle annotation processing, if i were to create a @Controller annotation (to copy what SpringMVC is doing), would kapt then be able to wire in these annotated classes at compile time instead of doing it at runtime? I've opted to manually wire in these classes for now, the startup performance penalty for runtime class scanning is just too much
b
Kapt runs at compile time and is able to extend your code. So yes, it's able to insert wiring
j
ok, is it possible to generate class1.wire(), class2.wire(), ... etc in fun main automatically ? adding the wire method is easy enough, i can just put it in a base class
b
Should be able to.
Collect all annotated classes. Then insert wire call for each
j
and this collection step happens at compile time?
b
Yes
j
thanks, I'll dig into kapt then! the docs are a bit sparse on kapt and most tutorials seems to point to a now deprecated version of kapt, so didn't give it much attention