* @param env the environment strings to pass to any subprocess.
* @throws IOException if Hive did not exit successfully.
*/
private void executeScript(String filename, List<String> env)
throws IOException {
SubprocessSecurityManager subprocessSM = null;
if (testMode) {
// We use external mock hive process for test mode as
// HCatalog dependency would have brought in Hive classes.
LOG.debug("Using external Hive process in test mode.");
executeExternalHiveScript(filename, env);
return;
}
try {
Class cliDriverClass = Class.forName(HIVE_MAIN_CLASS);
// We loaded the CLI Driver in this JVM, so we will just
// call it in-process. The CliDriver class has a method:
// void main(String [] args) throws Exception.
//
// We'll call that here to invoke 'hive -f scriptfile'.
// Because this method will call System.exit(), we use
// a SecurityManager to prevent this.
LOG.debug("Using in-process Hive instance.");
subprocessSM = new SubprocessSecurityManager();
subprocessSM.install();
// Create the argv for the Hive Cli Driver.
String [] argArray = new String[2];
argArray[0] = "-f";
argArray[1] = filename;
// And invoke the static method on this array.
Method mainMethod = cliDriverClass.getMethod("main", argArray.getClass());
mainMethod.invoke(null, (Object) argArray);
} catch (ClassNotFoundException cnfe) {
// Hive is not on the classpath. Run externally.
// This is not an error path.
LOG.debug("Using external Hive process.");
executeExternalHiveScript(filename, env);
} catch (NoSuchMethodException nsme) {
// Could not find a handle to the main() method.
throw new IOException("Could not access CliDriver.main()", nsme);
} catch (IllegalAccessException iae) {
// Error getting a handle on the main() method.
throw new IOException("Could not access CliDriver.main()", iae);
} catch (InvocationTargetException ite) {
// We ran CliDriver.main() and an exception was thrown from within Hive.
// This may have been the ExitSecurityException triggered by the
// SubprocessSecurityManager. If so, handle it. Otherwise, wrap in
// an IOException and rethrow.
Throwable cause = ite.getCause();
if (cause instanceof ExitSecurityException) {
ExitSecurityException ese = (ExitSecurityException) cause;
int status = ese.getExitStatus();
if (status != 0) {
throw new IOException("Hive CliDriver exited with status=" + status);
}
} else {
throw new IOException("Exception thrown in Hive", ite);
}
} finally {
if (null != subprocessSM) {
// Uninstall the SecurityManager used to trap System.exit().
subprocessSM.uninstall();
}
}
}