com.lithic.api.core.PhantomReachable.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lithic-kotlin-core Show documentation
Show all versions of lithic-kotlin-core Show documentation
The Lithic Developer API is designed to provide a predictable programmatic
interface for accessing your Lithic account through an API and transaction
webhooks. Note that your API key is a secret and should be treated as such.
Don't share it with anyone, including us. We will never ask you for it.
The newest version!
@file:JvmName("PhantomReachable")
package com.lithic.api.core
import com.lithic.api.errors.LithicException
import java.lang.reflect.InvocationTargetException
/**
* Closes [closeable] when [observed] becomes only phantom reachable.
*
* This is a wrapper around a Java 9+ [java.lang.ref.Cleaner], or a no-op in older Java versions.
*/
internal fun closeWhenPhantomReachable(observed: Any, closeable: AutoCloseable) {
check(observed !== closeable) {
"`observed` cannot be the same object as `closeable` because it would never become phantom reachable"
}
closeWhenPhantomReachable?.let { it(observed, closeable::close) }
}
private val closeWhenPhantomReachable: ((Any, AutoCloseable) -> Unit)? by lazy {
try {
val cleanerClass = Class.forName("java.lang.ref.Cleaner")
val cleanerCreate = cleanerClass.getMethod("create")
val cleanerRegister =
cleanerClass.getMethod("register", Any::class.java, Runnable::class.java)
val cleanerObject = cleanerCreate.invoke(null);
{ observed, closeable ->
try {
cleanerRegister.invoke(cleanerObject, observed, Runnable { closeable.close() })
} catch (e: ReflectiveOperationException) {
if (e is InvocationTargetException) {
when (val cause = e.cause) {
is RuntimeException,
is Error -> throw cause
}
}
throw LithicException("Unexpected reflective invocation failure", e)
}
}
} catch (e: ReflectiveOperationException) {
// We're running Java 8, which has no Cleaner.
null
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy