Skip to content

Commit ed0cbe1

Browse files
committed
Remove BotCommands-method-accessors-classfile from core dependencies
Gradle complains about it needing Java 24
1 parent a1a4d42 commit ed0cbe1

File tree

5 files changed

+81
-31
lines changed

5 files changed

+81
-31
lines changed

BotCommands-core/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ dependencies {
3535

3636
api(projects.botCommandsMethodAccessors.core) // API due to opt-in annotation
3737
implementation(projects.botCommandsMethodAccessors.kotlinReflect)
38-
implementation(projects.botCommandsMethodAccessors.classfile)
3938

4039
// -------------------- GLOBAL DEPENDENCIES --------------------
4140

@@ -123,6 +122,8 @@ dependencies {
123122
// but we need to make sure the main module works without it
124123
testImplementation(libs.spring.boot)
125124
testImplementation(libs.spring.boot.autoconfigure)
125+
126+
testImplementation(projects.botCommandsMethodAccessors.classfile)
126127
}
127128

128129
val generateInfo by tasks.registering(GenerateBCInfoTask::class) {

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/BotCommands.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ object BotCommands {
3535
* - No [InvocationTargetExceptions][java.lang.reflect.InvocationTargetException]
3636
* - Better performance
3737
*
38-
* This feature requires *running* on Java 24+, if your bot doesn't, this method has no effect.
38+
* This feature requires adding the `BotCommands-method-accessors-classfile` dependency
39+
* and *running* on Java 24+, if your bot doesn't fulfill these conditions, this method has no effect.
3940
*/
4041
@ExperimentalMethodAccessorsApi
4142
@get:JvmStatic
@@ -49,7 +50,8 @@ object BotCommands {
4950
* - No [InvocationTargetExceptions][java.lang.reflect.InvocationTargetException]
5051
* - Better performance
5152
*
52-
* This feature requires *running* on Java 24+, if your bot doesn't, this method has no effect.
53+
* This feature requires adding the `BotCommands-method-accessors-classfile` dependency
54+
* and *running* on Java 24+, if your bot doesn't fulfill these conditions, this method has no effect.
5355
*/
5456
@JvmStatic
5557
@ExperimentalMethodAccessorsApi

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/internal/core/method/accessors/MethodAccessorFactoryProvider.kt

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.github.freya022.botcommands.internal.core.method.accessors
22

33
import dev.freya02.botcommands.method.accessors.api.annotations.ExperimentalMethodAccessorsApi
4-
import dev.freya02.botcommands.method.accessors.internal.ClassFileMethodAccessorFactory
54
import dev.freya02.botcommands.method.accessors.internal.KotlinReflectMethodAccessorFactory
65
import dev.freya02.botcommands.method.accessors.internal.MethodAccessor
76
import dev.freya02.botcommands.method.accessors.internal.MethodAccessorFactory
@@ -11,37 +10,53 @@ import kotlin.reflect.KFunction
1110

1211
internal object MethodAccessorFactoryProvider {
1312

14-
private var logged = false
13+
private lateinit var accessorFactory: MethodAccessorFactory
14+
private val staticAccessors: MutableMap<KFunction<*>, MethodAccessor<*>> = hashMapOf()
15+
16+
internal fun getAccessorFactory(): MethodAccessorFactory {
17+
if (::accessorFactory.isInitialized) return accessorFactory
18+
19+
synchronized(this) {
20+
if (::accessorFactory.isInitialized) return accessorFactory
1521

16-
private val kotlinReflectAccessorFactory: MethodAccessorFactory = KotlinReflectMethodAccessorFactory()
17-
private val classFileAccessorFactory by lazy<MethodAccessorFactory?> {
18-
if (Runtime.version().feature() >= 24) {
19-
ClassFileMethodAccessorFactory()
20-
} else {
21-
null
22+
accessorFactory = loadAccessorFactory()
2223
}
23-
}
2424

25-
private val staticAccessors: MutableMap<KFunction<*>, MethodAccessor<*>> = hashMapOf()
25+
return accessorFactory
26+
}
2627

2728
@OptIn(ExperimentalMethodAccessorsApi::class)
28-
internal fun getAccessorFactory(): MethodAccessorFactory {
29-
fun logUsage(msg: String) {
30-
if (logged) return
31-
synchronized(this) {
32-
if (logged) return
33-
logged = true
34-
}
35-
KotlinLogging.logger { }.info { msg }
29+
private fun loadAccessorFactory(): MethodAccessorFactory {
30+
if (BotCommands.preferClassFileAccessors) {
31+
val accessorFactory = tryLoadClassFileAccessor()
32+
if (accessorFactory != null) return accessorFactory
3633
}
3734

38-
return if (BotCommands.preferClassFileAccessors && classFileAccessorFactory != null) {
39-
logUsage("Using ClassFile-based method accessor factory")
40-
classFileAccessorFactory!!
41-
} else {
42-
logUsage("Using kotlin-reflect method accessor factory")
43-
kotlinReflectAccessorFactory
35+
val logger = KotlinLogging.logger { }
36+
logger.debug { "Using kotlin-reflect method accessors" }
37+
return KotlinReflectMethodAccessorFactory()
38+
}
39+
40+
private fun tryLoadClassFileAccessor(): MethodAccessorFactory? {
41+
val logger = KotlinLogging.logger { }
42+
43+
val runtimeFeature = Runtime.version().feature()
44+
if (runtimeFeature < 24) {
45+
logger.debug { "Cannot use ClassFile-based method accessors as this feature requires Java 24+, currently running on Java $runtimeFeature" }
46+
return null
4447
}
48+
49+
val accessorFactory = try {
50+
Class.forName("dev.freya02.botcommands.method.accessors.internal.ClassFileMethodAccessorFactory")
51+
.getDeclaredConstructor()
52+
.newInstance() as MethodAccessorFactory
53+
} catch (e: ClassNotFoundException) {
54+
logger.debug(e) { "Cannot use ClassFile-based method accessors as the 'BotCommands-method-accessors-classfile' dependency is missing" }
55+
return null
56+
}
57+
58+
logger.debug { "Using ClassFile-based method accessors" }
59+
return accessorFactory
4560
}
4661

4762
internal fun <R> getStaticAccessor(function: KFunction<R>): MethodAccessor<R> = synchronized(this) {

BotCommands-method-accessors/README.md

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
1+
[bc-module-maven-central-shield]: https://img.shields.io/maven-central/v/io.github.freya022/BotCommands-method-accessors-classfile?label=Maven%20central&logo=apachemaven&versionPrefix=3
2+
[bc-module-maven-central-link]: https://central.sonatype.com/artifact/io.github.freya022/BotCommands-method-accessors-classfile
3+
14
# BotCommands module - Method accessors
2-
This module provides abstractions to call user methods, it should not be included manually.
5+
This module provides abstractions to call user methods.
6+
7+
## Installation
8+
[![BotCommands-method-accessors-classfile on maven central][bc-module-maven-central-shield] ][bc-module-maven-central-link]
9+
10+
You can optionally install this dependency,
11+
it requires Java 24+ and can be enabled with `BotCommand.preferClassFileAccessors()`.
12+
13+
### Maven
14+
```xml
15+
<dependencies>
16+
<dependency>
17+
<groupId>io.github.freya022</groupId>
18+
<artifactId>BotCommands-method-accessors-classfile</artifactId>
19+
<version>VERSION</version>
20+
</dependency>
21+
</dependencies>
22+
```
23+
24+
### Gradle
25+
```gradle
26+
repositories {
27+
mavenCentral()
28+
}
29+
30+
dependencies {
31+
implementation("io.github.freya022:BotCommands-method-accessors-classfile:VERSION")
32+
}
33+
```
34+
35+
Alternatively, you can use Jitpack to use **snapshot** versions,
36+
you can refer to [the JDA wiki](https://jda.wiki/using-jda/using-new-features/) for more information.
337

438
## Implementations
539

@@ -13,9 +47,6 @@ which, for each function, generates a hidden class with instructions optimized t
1347

1448
This allows for shorter stack traces in exceptions and the debugger, no `InvocationTargetException`s, and better performance.
1549

16-
This can be enabled before starting your bot, by calling `BotCommands.preferClassFileAccessors()`,
17-
note that this will only have an effect if your bot runs on Java 24+.
18-
1950
### Stack trace comparison
2051

2152
#### kotlin-reflect

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ The base `BotCommands` artifact will include modules often used, while others ar
174174

175175
### Optional modules
176176
- [`BotCommands-spring`](./BotCommands-spring): Support for Spring Boot
177+
- [`BotCommands-method-accessors-classfile`](./BotCommands-method-accessors): Improved alternative for this framework to call your functions
177178

178179
## Sample usage
179180
Here is how you would create a slash command that sends a message in a specified channel.

0 commit comments

Comments
 (0)