Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't load implementation for DatabaseConnectionAutoRegistration #971

Closed
twixthehero opened this issue Jun 22, 2020 · 4 comments
Closed

Comments

@twixthehero
Copy link

I saw #748 is fixed in 0.20.3. I'm using 0.25.1 and encountering it.

Dependencies

  • org.jetbrains.kotlin:kotlin-stdlib:1.3.72
  • com.h2database:h2:1.4.200
  • org.jetbrains.exposed:exposed-core:0.25.1
  • org.jetbrains.exposed:exposed-dao:0.25.1
  • org.jetbrains.exposed:exposed-jdbc:0.25.1
  • org.jetbrains.exposed:exposed-java-time:0.25.1

Stacktrace

java.lang.ExceptionInInitializerError: null
	at com.krythera.audit.db.DatabaseConnectionManager$Companion.loadDb(DatabaseConnectionManager.kt:73) ~[?:0.0.3]
	at com.krythera.audit.db.DatabaseConnectionManager$Companion.onLoadWorld(DatabaseConnectionManager.kt:57) ~[?:0.0.3]
	at com.krythera.audit.db.DatabaseConnectionManager.onLoadWorld(DatabaseConnectionManager.kt) ~[?:0.0.3]
	at net.minecraftforge.eventbus.ASMEventHandler_138_DatabaseConnectionManager_onLoadWorld_Load.invoke(.dynamic) ~[?:?]
	at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:80) ~[eventbus-2.2.0-service.jar:?]
	at net.minecraftforge.eventbus.EventBus.post(EventBus.java:258) ~[eventbus-2.2.0-service.jar:?]
	at net.minecraft.server.MinecraftServer.func_213194_a(MinecraftServer.java:414) ~[?:?]
	at net.minecraft.server.MinecraftServer.func_71247_a(MinecraftServer.java:364) ~[?:?]
	at net.minecraft.server.dedicated.DedicatedServer.func_71197_b(DedicatedServer.java:212) ~[?:?]
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:613) [?:?]
	at java.lang.Thread.run(Unknown Source) [?:1.8.0_221]
Caused by: java.lang.IllegalStateException: Can't load implementation for DatabaseConnectionAutoRegistration
	at org.jetbrains.exposed.sql.Database.<clinit>(Database.kt:62) ~[?:0.0.3]
	... 11 more

DatabaseConnectionManager$Companion.loadDb

...
val dbFile = "${baseFolderPaths[dimensionId]?.replace('\\', '/')}/data/kryaudit"
var database = Database.connect("jdbc:h2:$dbFile", DRIVER)
...

Info

OS: Windows 10 Pro v2004
Forge: 31.2.9

Debugging

I slightly modified #748 (comment) and noticed that the forge class loader cannot retrieve the implementation class.

val forgeClassLoader = Database::class.java.classLoader
val forgeServiceLoader = ServiceLoader.load(DatabaseConnectionAutoRegistration::class.java,forgeClassLoader)
println("[Forge] ClassLoader: $forgeClassLoader ServiceLoader: ${forgeServiceLoader.toList()}")

val contextClassLoader = Thread.currentThread().contextClassLoader
val contextServiceLoader = ServiceLoader.load(DatabaseConnectionAutoRegistration::class.java,contextClassLoader)
println("[Context] ClassLoader: $contextClassLoader ServiceLoader: ${contextServiceLoader.toList()}")

val dbFile = "${baseFolderPaths[dimensionId]?.replace('\\', '/')}/data/kryaudit"
var database = Database.connect("jdbc:h2:$dbFile", DRIVER)
[22Jun2020 00:03:54.308] [Server thread/INFO] [STDOUT/]: [com.krythera.audit.db.DatabaseConnectionManager$Companion:loadDb:76]: [Forge] ClassLoader: cpw.mods.modlauncher.TransformingClassLoader@9bd0fa6 ServiceLoader: []
[22Jun2020 00:03:54.309] [Server thread/INFO] [STDOUT/]: [com.krythera.audit.db.DatabaseConnectionManager$Companion:loadDb:80]: [Context] ClassLoader: cpw.mods.modlauncher.TransformingClassLoader@9bd0fa6 ServiceLoader: []
[22Jun2020 00:03:54.375] [Server thread/ERROR] [net.minecraftforge.eventbus.EventBus/EVENTBUS]: Exception caught during firing event: null
	Index: 1
	Listeners:
		0: HIGH
		1: ASM: class com.krythera.audit.db.DatabaseConnectionManager onLoadWorld(Lnet/minecraftforge/event/world/WorldEvent$Load;)V
		2: NORMAL
		3: ASM: class com.krythera.audit.items.ForgeItemEvents onLoadWorld(Lnet/minecraftforge/event/world/WorldEvent$Load;)V
		4: ASM: class com.krythera.audit.blocks.ForgeBlockEvents onLoadWorld(Lnet/minecraftforge/event/world/WorldEvent$Load;)V
java.lang.ExceptionInInitializerError
	at com.krythera.audit.db.DatabaseConnectionManager$Companion.loadDb(DatabaseConnectionManager.kt:83)
	at com.krythera.audit.db.DatabaseConnectionManager$Companion.onLoadWorld(DatabaseConnectionManager.kt:59)
	at com.krythera.audit.db.DatabaseConnectionManager.onLoadWorld(DatabaseConnectionManager.kt)
	at net.minecraftforge.eventbus.ASMEventHandler_16_DatabaseConnectionManager_onLoadWorld_Load.invoke(.dynamic)
	at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:80)
	at net.minecraftforge.eventbus.EventBus.post(EventBus.java:258)
	at net.minecraft.server.MinecraftServer.func_213194_a(MinecraftServer.java:414)
	at net.minecraft.server.MinecraftServer.func_71247_a(MinecraftServer.java:364)
	at net.minecraft.server.dedicated.DedicatedServer.func_71197_b(DedicatedServer.java:212)
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:613)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Can't load implementation for DatabaseConnectionAutoRegistration
	at org.jetbrains.exposed.sql.Database.<clinit>(Database.kt:62)
	... 11 more
@twixthehero
Copy link
Author

I believe this is caused by a Forge class loading issue and not Exposed. I will reopen if it is not.

@RemyyB
Copy link

RemyyB commented Nov 7, 2020

Hey @twixthehero , how did you fix this issue exactly? I'm currently experiencing the same issue but cannot seem to fix it, I'm not using Forge but PlaceholderExpansion, but I think that requires the same fix. Thanks in advance

@twixthehero
Copy link
Author

Hi @RemyyB , I ended up forking Exposed and making changes at https://github.com/JetBrains/Exposed/blob/master/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Database.kt#L61.

private var _connectionInstanceImpl : DatabaseConnectionAutoRegistration? = null
private val connectionInstanceImpl : DatabaseConnectionAutoRegistration
    get() {
        return _connectionInstanceImpl ?: error("Implementation for ${DatabaseConnectionAutoRegistration::class.simpleName} was not set")
    }

fun setDatabaseConnectionAutoRegistrationImpl(impl: DatabaseConnectionAutoRegistration) {
    _connectionInstanceImpl = impl
}

Then during Forge initialization, I manually set the implementation:

Database.setDatabaseConnectionAutoRegistrationImpl(
    Database::class.java.classLoader
        .loadClass("org.jetbrains.exposed.jdbc.ExposedConnectionImpl")
        .newInstance() as ExposedConnectionImpl
)

While this is not ideal, it was definitely faster in my case to just fork Exposed rather than waiting for Forge to support Jar unpacking.

@RemyyB
Copy link

RemyyB commented Nov 8, 2020

Hi @twixthehero , thank you! Unfortunately now something else is going wrong, I keep getting the following error, but I have stdlib installed:

Caused by: java.lang.NoClassDefFoundError: kotlin/KotlinNothingValueException
	at org.jetbrains.exposed.sql.Table.registerColumn(Table.kt:362) ~[?:?]
	at org.jetbrains.exposed.sql.Table.integer(Table.kt:514) ~[?:?]

I just can't seem to fix this issue, it keeps coming back and Google has no fix for me :/
Thank you in advance :)

Edit: I seem to have narrowed it down, when I implement the original Exposed the database works, only the Table class is not working and giving the error NoClassDefFoundError, do you have any experience with this?

Nevermind the issue has been fixed, thank you very much :)

If anyone every has this problem, follow the steps from @twixthehero above, but fork version 0.26.1 as 0.28.1 has a lot of issues with classes that cannot be found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants