I wrote an application that tried to create a default HBaseConfiguration, but when I package the application as a jar it won’t work properly because it is trying to use 127.0.0.1’s zookeeper and not the one specified in my /etc/hbase/conf/hbase-site.xml. The application can be stripped down to something like this:
object TestUtil extends App {
val hbaseTable = new HTable(HBaseConfiguration.create, "tableName")
println(hbaseTable)
}
When I run this using the following command it works fine:
CLASSPATH=`hbase classpath` java fully.qualified.name.TestUtil
If I package it as a jar and call it using CLASSPATH='hbase classpath' java -jar TestUtil.jar then I get the following error:
org.apache.hadoop.hbase.ZooKeeperConnectionException: HBase is able to connect to ZooKeeper but the connection closes immediately.
I’ve checked the logs and can see that it is trying to connect to 127.0.0.1 for Zookeeper, which is different from the zookeeper configuration in my /etc/hbase/conf/hbase-site.xml. The jar seems to be ignoring my classpath even though I explicitly set it on the command line.
How can I make the JVM honor my classpath when executing a jar?
When starting a JVM with
java -jarthe resulting environment does not see files in the classpath from the outsideCLASSPATHvariable. It instead uses the classpath from the MANIFEST file.Assuming you don’t want to hardcode the paths to your dependencies in the manifest, You can get around this by:
-jarswitch, andmain()as an argument.For example:
This is the same approach that HBase’s
hbaseshell script uses. Take a look at line 332.So long as your JAR doesn’t include an
hbase-site.xml, this approach should result in the JVM loading thehbase-site.xmlfrom your classpath.