I have a @Singleton
class with a method annotated with @EventListener
in my Micronaut project:
@Singleton
class Bot {
@Inject
private val environment: Environment? = null
@EventListener
fun initialize(event: ServerStartupEvent) {
val key = environment?.getProperty("discord.api.key", String::class.java)?.get().orEmpty()
// code that is using the key variable
}
}
The key is in application.yml
file:
discord:
api:
key: MY_API_KEY // key is here as it is, without " or ' quotes, tried to enclose it with quotes - it doesn't work either
But when I'm trying to run the application, I get an error:
java.lang.IllegalArgumentException: Invalid token, make sure you're using the token from the developer portal Bot section and not the application client secret or public key.
at discord4j.common.util.TokenUtil.getSelfId(TokenUtil.java:35)
at discord4j.rest.RestResources.<init>(RestResources.java:58)
at discord4j.core.CoreResources.<init>(CoreResources.java:44)
at discord4j.core.DiscordClientBuilder.lambda$create$0(DiscordClientBuilder.java:45)
at discord4j.rest.RestClientBuilder.build(RestClientBuilder.java:249)
at discord4j.core.DiscordClientBuilder.build(DiscordClientBuilder.java:85)
at discord4j.core.DiscordClientBuilder.build(DiscordClientBuilder.java:73)
at com.codenamite.majorbot.MajorBot.initialize(MajorBot.kt:23)
at com.codenamite.majorbot.$MajorBotDefinition$$exec1.invokeInternal(Unknown Source)
at io.micronaut.context.AbstractExecutableMethod.invoke(AbstractExecutableMethod.java:151)
at io.micronaut.context.DefaultBeanContext$BeanExecutionHandle.invoke(DefaultBeanContext.java:3414)
at io.micronaut.aop.chain.AdapterIntroduction.intercept(AdapterIntroduction.java:81)
at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:96)
at com.codenamite.majorbot.MajorBot$ApplicationEventListener$initialize1$Intercepted.onApplicationEvent(Unknown Source)
at io.micronaut.context.DefaultBeanContext.notifyEventListeners(DefaultBeanContext.java:1326)
at io.micronaut.context.DefaultBeanContext.publishEvent(DefaultBeanContext.java:1311)
at io.micronaut.http.server.netty.NettyHttpServer.fireStartupEvents(NettyHttpServer.java:512)
at io.micronaut.http.server.netty.NettyHttpServer.start(NettyHttpServer.java:355)
at io.micronaut.http.server.netty.NettyHttpServer.start(NettyHttpServer.java:114)
at io.micronaut.runtime.Micronaut.lambda$start$2(Micronaut.java:77)
at java.base/java.util.Optional.ifPresent(Optional.java:183)
at io.micronaut.runtime.Micronaut.start(Micronaut.java:75)
at com.codenamite.ApplicationKt.main(Application.kt:8)
Caused by: java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Long.parseLong(Long.java:702)
at java.base/java.lang.Long.parseLong(Long.java:817)
at discord4j.common.util.TokenUtil.getSelfId(TokenUtil.java:32)
... 22 common frames omitted
The Caused by: java.lang.NumberFormatException: For input string: ""
part is telling me that the key was null, so the .orEmpty()
part was used.
I have no clue what is happening, the only one idea that comes to my mind is that the properties are not available at the moment when this code is running, but I have no idea how to fix this... Or maybe there is something else? I am running out of ideas...
i recommend using either configuration injection: https://docs.micronaut.io/latest/guide/index.html#valueAnnotation
@Context
class Bot(@Value("${discord.api.key}") String key) {
init {
// code that is using the key variable
}
}
or what I prefer configuration properties https://docs.micronaut.io/latest/guide/index.html#configurationProperties
your bot will look like that:
@ConfigurationProperties("discord")
class DiscordConfig {
@NotBlank
var token: String = ""
}
@Context
class Bot(config: DiscordConfig) {
init {
val client = DiscordClient.create(config.token)
// code that is using the key variable
}
}
I see no need of using the server start event. If you annotate your "singleton" with "context" the bean is instanciated on startup which is quite the same like a server start event. Using constructor injection makes shure the stuff is there on instanciation.
Oli