Skip to content

Instantly share code, notes, and snippets.

@ChristopherDavenport
Created November 15, 2018 14:04
Show Gist options
  • Save ChristopherDavenport/e380e0ff9c68d52a963bab89cbb8cb8c to your computer and use it in GitHub Desktop.
Save ChristopherDavenport/e380e0ff9c68d52a963bab89cbb8cb8c to your computer and use it in GitHub Desktop.
HBase Class Loading Trick
/**
* Hacky Workaround for Getting the Current Context Classloader
* Executing Some arbitrary Sync with the Hbase Classloader
* Then reseting that thread to how it was previously.
*
* The moments I believe this is neccessary is when connections or
* configurations are being created to HBase. At these times it
* needs to have the hbase-default.xml which it will be lacking
* otherwise.
*
* NOTICE: If your F is an Async and you pass this function something that
* forks you are defeating the purpose and likely screwing up your threads.
* You want the thread that is executing any action to have a classpath.
* So Fork inside what is passed to this function at your own risk.
*
* Fixes: java.lang.RuntimeException: hbase-default.xml file seems to be for and old version of HBase (null)
* Solution Modified From:
* https://stackoverflow.com/questions/18272268/hbase-default-xml-file-seems-to-be-for-and-old-version-of-hbase-null-this-ver
*
*/
private[hbase] def withHBaseClassLoader[F[_]: Sync, A](a: F[A]): F[A] =
for {
initialClassLoader <- Sync[F].delay(
Thread.currentThread.getContextClassLoader())
_ <- Sync[F].delay(
Thread
.currentThread()
.setContextClassLoader(classOf[HBaseConfiguration].getClassLoader()))
aE <- a.attempt
_ <- Sync[F].delay(
Thread.currentThread().setContextClassLoader(initialClassLoader))
a <- Sync[F].pure(aE).rethrow
} yield a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment