Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ open class PublicKey(bytes: List<Byte>) : Key32(bytes), Parcelable {
return PublicKey(byteString.toByteArray().toList())
}

val ZERO: PublicKey = PublicKey(zero.bytes)
// Not Key32.zero: Key32's companion constructs PublicKeys, so when Key32 initializes
// first, this runs before Key32.zero is assigned.
val ZERO: PublicKey = PublicKey(ByteArray(LENGTH_32).toList())

@JvmField
val CREATOR: Parcelable.Creator<PublicKey> =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.getcode.solana.keys

import java.io.File
import java.net.URLClassLoader
import kotlin.test.Test
import kotlin.test.assertEquals

class KeyInitOrderTest {

// Key32's companion builds PublicKeys, so which of the two classes the JVM
// initializes first matters. A fresh class loader controls that order
// regardless of what other tests in this JVM have already touched.
@Test
fun `Key32 initializes when it is loaded before PublicKey`() {
freshClassLoader().use { loader ->
val key32 = Class.forName("com.getcode.solana.keys.Key32", true, loader)
val companion = key32.getField("Companion").get(null)
val zero = companion.javaClass.getMethod("getZero").invoke(companion)

val publicKey = Class.forName("com.getcode.solana.keys.PublicKey", false, loader)
val publicKeyCompanion = publicKey.getField("Companion").get(null)
val publicZero = publicKeyCompanion.javaClass.getMethod("getZERO").invoke(publicKeyCompanion)

val bytes = key32.getMethod("getBytes")
assertEquals(bytes.invoke(zero), bytes.invoke(publicZero))
}
}

private fun freshClassLoader(): URLClassLoader {
val urls = System.getProperty("java.class.path")
.split(File.pathSeparator)
.map { File(it).toURI().toURL() }
.toTypedArray()
return URLClassLoader(urls, null)
}
}
Loading