private void cancelDelegationTokens(JobContext context) throws IOException{
    LOG.info("Cancelling delegation token for the job.");
    IMetaStoreClient client = null;
    try {
      HiveConf hiveConf = HCatUtil
          .getHiveConf(context.getConfiguration());
      client = HCatUtil.getHiveMetastoreClient(hiveConf);
      // cancel the deleg. tokens that were acquired for this job now that
      // we are done - we should cancel if the tokens were acquired by
      // HCatOutputFormat and not if they were supplied by Oozie.
      // In the latter case the HCAT_KEY_TOKEN_SIGNATURE property in
      // the conf will not be set
      String tokenStrForm = client.getTokenStrForm();
      String hCatKeyTokenSignature = context.getConfiguration().get(
          HCatConstants.HCAT_KEY_TOKEN_SIGNATURE);
      if (tokenStrForm != null
          && hCatKeyTokenSignature != null) {
        LOG.info("FileOutputCommitterContainer::cancelDelegationTokens(): " +
            "Cancelling token fetched for HCAT_KEY_TOKEN_SIGNATURE == (" + hCatKeyTokenSignature + ").");
        client.cancelDelegationToken(tokenStrForm);
      }
      else {
        LOG.info("FileOutputCommitterContainer::cancelDelegationTokens(): " +
            "Could not find tokenStrForm, or HCAT_KEY_TOKEN_SIGNATURE. Skipping token cancellation.");
      }
    } catch (MetaException e) {
      LOG.warn("MetaException while cancelling delegation token.", e);
    } catch (TException e) {
      LOG.warn("TException while cancelling delegation token.", e);
    } finally {
      HCatUtil.closeHiveClientQuietly(client);
    }
  }
Dynamic partitioning & Append incompatibility note:

Currently, we do not support mixing dynamic partitioning and append in the
same job. One reason is that we need exhaustive testing of corner cases
for that, and a second reason is the behaviour of add_partitions. To support
dynamic partitioning with append, we'd have to have a add_partitions_if_not_exist
call, rather than an add_partitions call. Thus far, we've tried to keep the
implementation of append jobtype-agnostic, but here, in code, we assume that
a table is considered immutable if dynamic partitioning is enabled on the job.

This does not mean that we can check before the job begins that this is going
to be a dynamic partition job on an immutable table and thus fail the job, since
it is quite possible to have a dynamic partitioning job run on an unpopulated
immutable table. It simply means that at the end of the job, as far as copying
in data is concerned, we will pretend that the table is immutable irrespective
of what table.isImmutable() tells us.
hcatalog/core/src/main/java/org/apache/hive/hcatalog/mapreduce/FileOutputCommitterContainer.java