http://git-wip-us.apache.org/repos/asf/hbase-site/blob/e10887fe/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamCapabilities.html
----------------------------------------------------------------------
diff --git 
a/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamCapabilities.html
 
b/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamCapabilities.html
index c6bfdca..cae3d07 100644
--- 
a/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamCapabilities.html
+++ 
b/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamCapabilities.html
@@ -829,90 +829,217 @@
 <span class="sourceLineNo">821</span>    conf.setIfUnset(dfsKey, 
Integer.toString(hbaseSize));<a name="line.821"></a>
 <span class="sourceLineNo">822</span>  }<a name="line.822"></a>
 <span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>  // Holder singleton idiom. JVM spec 
ensures this will be run at most once per Classloader, and<a 
name="line.824"></a>
-<span class="sourceLineNo">825</span>  // not until we attempt to reference 
it.<a name="line.825"></a>
-<span class="sourceLineNo">826</span>  private static class StreamCapabilities 
{<a name="line.826"></a>
-<span class="sourceLineNo">827</span>    public static final boolean 
PRESENT;<a name="line.827"></a>
-<span class="sourceLineNo">828</span>    public static final Class&lt;?&gt; 
CLASS;<a name="line.828"></a>
-<span class="sourceLineNo">829</span>    public static final Method METHOD;<a 
name="line.829"></a>
-<span class="sourceLineNo">830</span>    static {<a name="line.830"></a>
-<span class="sourceLineNo">831</span>      boolean tmp = false;<a 
name="line.831"></a>
-<span class="sourceLineNo">832</span>      Class&lt;?&gt; clazz = null;<a 
name="line.832"></a>
-<span class="sourceLineNo">833</span>      Method method = null;<a 
name="line.833"></a>
-<span class="sourceLineNo">834</span>      try {<a name="line.834"></a>
-<span class="sourceLineNo">835</span>        clazz = 
Class.forName("org.apache.hadoop.fs.StreamCapabilities");<a name="line.835"></a>
-<span class="sourceLineNo">836</span>        method = 
clazz.getMethod("hasCapability", String.class);<a name="line.836"></a>
-<span class="sourceLineNo">837</span>        tmp = true;<a name="line.837"></a>
-<span class="sourceLineNo">838</span>      } 
catch(ClassNotFoundException|NoSuchMethodException|SecurityException exception) 
{<a name="line.838"></a>
-<span class="sourceLineNo">839</span>        LOG.warn("Your Hadoop 
installation does not include the StreamCapabilities class from " +<a 
name="line.839"></a>
-<span class="sourceLineNo">840</span>                 "HDFS-11644, so we will 
skip checking if any FSDataOutputStreams actually " +<a name="line.840"></a>
-<span class="sourceLineNo">841</span>                 "support hflush/hsync. 
If you are running on top of HDFS this probably just " +<a name="line.841"></a>
-<span class="sourceLineNo">842</span>                 "means you have an older 
version and this can be ignored. If you are running on " +<a 
name="line.842"></a>
-<span class="sourceLineNo">843</span>                 "top of an alternate 
FileSystem implementation you should manually verify that " +<a 
name="line.843"></a>
-<span class="sourceLineNo">844</span>                 "hflush and hsync are 
implemented; otherwise you risk data loss and hard to " +<a name="line.844"></a>
-<span class="sourceLineNo">845</span>                 "diagnose errors when 
our assumptions are violated.");<a name="line.845"></a>
-<span class="sourceLineNo">846</span>        LOG.debug("The first request to 
check for StreamCapabilities came from this stacktrace.",<a name="line.846"></a>
-<span class="sourceLineNo">847</span>            exception);<a 
name="line.847"></a>
-<span class="sourceLineNo">848</span>      } finally {<a name="line.848"></a>
-<span class="sourceLineNo">849</span>        PRESENT = tmp;<a 
name="line.849"></a>
-<span class="sourceLineNo">850</span>        CLASS = clazz;<a 
name="line.850"></a>
-<span class="sourceLineNo">851</span>        METHOD = method;<a 
name="line.851"></a>
-<span class="sourceLineNo">852</span>      }<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span>  }<a name="line.854"></a>
-<span class="sourceLineNo">855</span><a name="line.855"></a>
-<span class="sourceLineNo">856</span>  /**<a name="line.856"></a>
-<span class="sourceLineNo">857</span>   * If our FileSystem version includes 
the StreamCapabilities class, check if<a name="line.857"></a>
-<span class="sourceLineNo">858</span>   * the given stream has a particular 
capability.<a name="line.858"></a>
-<span class="sourceLineNo">859</span>   * @param stream capabilities are 
per-stream instance, so check this one specifically. must not be<a 
name="line.859"></a>
-<span class="sourceLineNo">860</span>   *        null<a name="line.860"></a>
-<span class="sourceLineNo">861</span>   * @param capability what to look for, 
per Hadoop Common's FileSystem docs<a name="line.861"></a>
-<span class="sourceLineNo">862</span>   * @return true if there are no 
StreamCapabilities. false if there are, but this stream doesn't<a 
name="line.862"></a>
-<span class="sourceLineNo">863</span>   *         implement it. return result 
of asking the stream otherwise.<a name="line.863"></a>
-<span class="sourceLineNo">864</span>   */<a name="line.864"></a>
-<span class="sourceLineNo">865</span>  public static boolean 
hasCapability(FSDataOutputStream stream, String capability) {<a 
name="line.865"></a>
-<span class="sourceLineNo">866</span>    // be consistent whether or not 
StreamCapabilities is present<a name="line.866"></a>
-<span class="sourceLineNo">867</span>    if (stream == null) {<a 
name="line.867"></a>
-<span class="sourceLineNo">868</span>      throw new 
NullPointerException("stream parameter must not be null.");<a 
name="line.868"></a>
-<span class="sourceLineNo">869</span>    }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    // If o.a.h.fs.StreamCapabilities 
doesn't exist, assume everyone does everything<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    // otherwise old versions of Hadoop 
will break.<a name="line.871"></a>
-<span class="sourceLineNo">872</span>    boolean result = true;<a 
name="line.872"></a>
-<span class="sourceLineNo">873</span>    if (StreamCapabilities.PRESENT) {<a 
name="line.873"></a>
-<span class="sourceLineNo">874</span>      // if StreamCapabilities is 
present, but the stream doesn't implement it<a name="line.874"></a>
-<span class="sourceLineNo">875</span>      // or we run into a problem 
invoking the method,<a name="line.875"></a>
-<span class="sourceLineNo">876</span>      // we treat that as equivalent to 
not declaring anything<a name="line.876"></a>
-<span class="sourceLineNo">877</span>      result = false;<a 
name="line.877"></a>
-<span class="sourceLineNo">878</span>      if 
(StreamCapabilities.CLASS.isAssignableFrom(stream.getClass())) {<a 
name="line.878"></a>
+<span class="sourceLineNo">824</span>  private static class DfsBuilderUtility 
{<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    static Class&lt;?&gt; dfsClass = 
null;<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    static Method createMethod;<a 
name="line.826"></a>
+<span class="sourceLineNo">827</span>    static Method overwriteMethod;<a 
name="line.827"></a>
+<span class="sourceLineNo">828</span>    static Method bufferSizeMethod;<a 
name="line.828"></a>
+<span class="sourceLineNo">829</span>    static Method blockSizeMethod;<a 
name="line.829"></a>
+<span class="sourceLineNo">830</span>    static Method recursiveMethod;<a 
name="line.830"></a>
+<span class="sourceLineNo">831</span>    static Method replicateMethod;<a 
name="line.831"></a>
+<span class="sourceLineNo">832</span>    static Method replicationMethod;<a 
name="line.832"></a>
+<span class="sourceLineNo">833</span>    static Method buildMethod;<a 
name="line.833"></a>
+<span class="sourceLineNo">834</span>    static boolean allMethodsPresent = 
false;<a name="line.834"></a>
+<span class="sourceLineNo">835</span><a name="line.835"></a>
+<span class="sourceLineNo">836</span>    static {<a name="line.836"></a>
+<span class="sourceLineNo">837</span>      String dfsName = 
"org.apache.hadoop.hdfs.DistributedFileSystem";<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      String builderName = dfsName + 
"$HdfsDataOutputStreamBuilder";<a name="line.838"></a>
+<span class="sourceLineNo">839</span>      Class&lt;?&gt; builderClass = 
null;<a name="line.839"></a>
+<span class="sourceLineNo">840</span><a name="line.840"></a>
+<span class="sourceLineNo">841</span>      try {<a name="line.841"></a>
+<span class="sourceLineNo">842</span>        dfsClass = 
Class.forName(dfsName);<a name="line.842"></a>
+<span class="sourceLineNo">843</span>      } catch (ClassNotFoundException e) 
{<a name="line.843"></a>
+<span class="sourceLineNo">844</span>        LOG.debug("{} not available, will 
not use builder API for file creation.", dfsName);<a name="line.844"></a>
+<span class="sourceLineNo">845</span>      }<a name="line.845"></a>
+<span class="sourceLineNo">846</span>      try {<a name="line.846"></a>
+<span class="sourceLineNo">847</span>        builderClass = 
Class.forName(builderName);<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      } catch (ClassNotFoundException e) 
{<a name="line.848"></a>
+<span class="sourceLineNo">849</span>        LOG.debug("{} not available, will 
not use builder API for file creation.", builderName);<a name="line.849"></a>
+<span class="sourceLineNo">850</span>      }<a name="line.850"></a>
+<span class="sourceLineNo">851</span><a name="line.851"></a>
+<span class="sourceLineNo">852</span>      if (dfsClass != null &amp;&amp; 
builderClass != null) {<a name="line.852"></a>
+<span class="sourceLineNo">853</span>        try {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>          createMethod = 
dfsClass.getMethod("createFile", Path.class);<a name="line.854"></a>
+<span class="sourceLineNo">855</span>          overwriteMethod = 
builderClass.getMethod("overwrite", boolean.class);<a name="line.855"></a>
+<span class="sourceLineNo">856</span>          bufferSizeMethod = 
builderClass.getMethod("bufferSize", int.class);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>          blockSizeMethod = 
builderClass.getMethod("blockSize", long.class);<a name="line.857"></a>
+<span class="sourceLineNo">858</span>          recursiveMethod = 
builderClass.getMethod("recursive");<a name="line.858"></a>
+<span class="sourceLineNo">859</span>          replicateMethod = 
builderClass.getMethod("replicate");<a name="line.859"></a>
+<span class="sourceLineNo">860</span>          replicationMethod = 
builderClass.getMethod("replication", short.class);<a name="line.860"></a>
+<span class="sourceLineNo">861</span>          buildMethod = 
builderClass.getMethod("build");<a name="line.861"></a>
+<span class="sourceLineNo">862</span><a name="line.862"></a>
+<span class="sourceLineNo">863</span>          allMethodsPresent = true;<a 
name="line.863"></a>
+<span class="sourceLineNo">864</span>          LOG.debug("Using builder API 
via reflection for DFS file creation.");<a name="line.864"></a>
+<span class="sourceLineNo">865</span>        } catch (NoSuchMethodException e) 
{<a name="line.865"></a>
+<span class="sourceLineNo">866</span>          LOG.debug("Could not find 
method on builder; will use old DFS API for file creation {}",<a 
name="line.866"></a>
+<span class="sourceLineNo">867</span>              e.getMessage());<a 
name="line.867"></a>
+<span class="sourceLineNo">868</span>        }<a name="line.868"></a>
+<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
+<span class="sourceLineNo">871</span><a name="line.871"></a>
+<span class="sourceLineNo">872</span>    /**<a name="line.872"></a>
+<span class="sourceLineNo">873</span>     * Attempt to use builder API via 
reflection to create a file with the given parameters and<a name="line.873"></a>
+<span class="sourceLineNo">874</span>     * replication enabled.<a 
name="line.874"></a>
+<span class="sourceLineNo">875</span>     */<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    static FSDataOutputStream 
createHelper(FileSystem fs, Path path, boolean overwritable,<a 
name="line.876"></a>
+<span class="sourceLineNo">877</span>        int bufferSize, short 
replication, long blockSize, boolean isRecursive) throws IOException {<a 
name="line.877"></a>
+<span class="sourceLineNo">878</span>      if (allMethodsPresent &amp;&amp; 
dfsClass.isInstance(fs)) {<a name="line.878"></a>
 <span class="sourceLineNo">879</span>        try {<a name="line.879"></a>
-<span class="sourceLineNo">880</span>          result = 
((Boolean)StreamCapabilities.METHOD.invoke(stream, 
capability)).booleanValue();<a name="line.880"></a>
-<span class="sourceLineNo">881</span>        } catch 
(IllegalAccessException|IllegalArgumentException|InvocationTargetException<a 
name="line.881"></a>
-<span class="sourceLineNo">882</span>            exception) {<a 
name="line.882"></a>
-<span class="sourceLineNo">883</span>          LOG.warn("Your Hadoop 
installation's StreamCapabilities implementation doesn't match " +<a 
name="line.883"></a>
-<span class="sourceLineNo">884</span>              "our understanding of how 
it's supposed to work. Please file a JIRA and include " +<a name="line.884"></a>
-<span class="sourceLineNo">885</span>              "the following stack trace. 
In the mean time we're interpreting this behavior " +<a name="line.885"></a>
-<span class="sourceLineNo">886</span>              "difference as a lack of 
capability support, which will probably cause a failure.",<a 
name="line.886"></a>
-<span class="sourceLineNo">887</span>              exception);<a 
name="line.887"></a>
-<span class="sourceLineNo">888</span>        }<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      }<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
-<span class="sourceLineNo">891</span>    return result;<a name="line.891"></a>
-<span class="sourceLineNo">892</span>  }<a name="line.892"></a>
-<span class="sourceLineNo">893</span><a name="line.893"></a>
-<span class="sourceLineNo">894</span>  /**<a name="line.894"></a>
-<span class="sourceLineNo">895</span>   * Helper exception for those cases 
where the place where we need to check a stream capability<a 
name="line.895"></a>
-<span class="sourceLineNo">896</span>   * is not where we have the needed 
context to explain the impact and mitigation for a lack.<a name="line.896"></a>
-<span class="sourceLineNo">897</span>   */<a name="line.897"></a>
-<span class="sourceLineNo">898</span>  public static class 
StreamLacksCapabilityException extends Exception {<a name="line.898"></a>
-<span class="sourceLineNo">899</span>    public 
StreamLacksCapabilityException(String message, Throwable cause) {<a 
name="line.899"></a>
-<span class="sourceLineNo">900</span>      super(message, cause);<a 
name="line.900"></a>
-<span class="sourceLineNo">901</span>    }<a name="line.901"></a>
-<span class="sourceLineNo">902</span>    public 
StreamLacksCapabilityException(String message) {<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      super(message);<a 
name="line.903"></a>
-<span class="sourceLineNo">904</span>    }<a name="line.904"></a>
-<span class="sourceLineNo">905</span>  }<a name="line.905"></a>
-<span class="sourceLineNo">906</span><a name="line.906"></a>
-<span class="sourceLineNo">907</span>}<a name="line.907"></a>
+<span class="sourceLineNo">880</span>          Object builder;<a 
name="line.880"></a>
+<span class="sourceLineNo">881</span><a name="line.881"></a>
+<span class="sourceLineNo">882</span>          builder = 
createMethod.invoke(fs, path);<a name="line.882"></a>
+<span class="sourceLineNo">883</span>          builder = 
overwriteMethod.invoke(builder, overwritable);<a name="line.883"></a>
+<span class="sourceLineNo">884</span>          builder = 
bufferSizeMethod.invoke(builder, bufferSize);<a name="line.884"></a>
+<span class="sourceLineNo">885</span>          builder = 
blockSizeMethod.invoke(builder, blockSize);<a name="line.885"></a>
+<span class="sourceLineNo">886</span>          if (isRecursive) {<a 
name="line.886"></a>
+<span class="sourceLineNo">887</span>            builder = 
recursiveMethod.invoke(builder);<a name="line.887"></a>
+<span class="sourceLineNo">888</span>          }<a name="line.888"></a>
+<span class="sourceLineNo">889</span>          builder = 
replicateMethod.invoke(builder);<a name="line.889"></a>
+<span class="sourceLineNo">890</span>          builder = 
replicationMethod.invoke(builder, replication);<a name="line.890"></a>
+<span class="sourceLineNo">891</span>          return (FSDataOutputStream) 
buildMethod.invoke(builder);<a name="line.891"></a>
+<span class="sourceLineNo">892</span>        } catch (IllegalAccessException | 
InvocationTargetException e) {<a name="line.892"></a>
+<span class="sourceLineNo">893</span>          // Should have caught this 
failure during initialization, so log full trace here<a name="line.893"></a>
+<span class="sourceLineNo">894</span>          LOG.warn("Couldn't use 
reflection with builder API", e);<a name="line.894"></a>
+<span class="sourceLineNo">895</span>        }<a name="line.895"></a>
+<span class="sourceLineNo">896</span>      }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>      if (isRecursive) {<a 
name="line.898"></a>
+<span class="sourceLineNo">899</span>        return fs.create(path, 
overwritable, bufferSize, replication, blockSize, null);<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      }<a name="line.900"></a>
+<span class="sourceLineNo">901</span>      return fs.createNonRecursive(path, 
overwritable, bufferSize, replication, blockSize, null);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    }<a name="line.902"></a>
+<span class="sourceLineNo">903</span><a name="line.903"></a>
+<span class="sourceLineNo">904</span>    /**<a name="line.904"></a>
+<span class="sourceLineNo">905</span>     * Attempt to use builder API via 
reflection to create a file with the given parameters and<a name="line.905"></a>
+<span class="sourceLineNo">906</span>     * replication enabled.<a 
name="line.906"></a>
+<span class="sourceLineNo">907</span>     */<a name="line.907"></a>
+<span class="sourceLineNo">908</span>    static FSDataOutputStream 
createHelper(FileSystem fs, Path path, boolean overwritable)<a 
name="line.908"></a>
+<span class="sourceLineNo">909</span>        throws IOException {<a 
name="line.909"></a>
+<span class="sourceLineNo">910</span>      if (allMethodsPresent &amp;&amp; 
dfsClass.isInstance(fs)) {<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        try {<a name="line.911"></a>
+<span class="sourceLineNo">912</span>          Object builder;<a 
name="line.912"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>          builder = 
createMethod.invoke(fs, path);<a name="line.914"></a>
+<span class="sourceLineNo">915</span>          builder = 
overwriteMethod.invoke(builder, overwritable);<a name="line.915"></a>
+<span class="sourceLineNo">916</span>          builder = 
replicateMethod.invoke(builder);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>          return (FSDataOutputStream) 
buildMethod.invoke(builder);<a name="line.917"></a>
+<span class="sourceLineNo">918</span>        } catch (IllegalAccessException | 
InvocationTargetException e) {<a name="line.918"></a>
+<span class="sourceLineNo">919</span>          // Should have caught this 
failure during initialization, so log full trace here<a name="line.919"></a>
+<span class="sourceLineNo">920</span>          LOG.warn("Couldn't use 
reflection with builder API", e);<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        }<a name="line.921"></a>
+<span class="sourceLineNo">922</span>      }<a name="line.922"></a>
+<span class="sourceLineNo">923</span><a name="line.923"></a>
+<span class="sourceLineNo">924</span>      return fs.create(path, 
overwritable);<a name="line.924"></a>
+<span class="sourceLineNo">925</span>    }<a name="line.925"></a>
+<span class="sourceLineNo">926</span>  }<a name="line.926"></a>
+<span class="sourceLineNo">927</span><a name="line.927"></a>
+<span class="sourceLineNo">928</span>  /**<a name="line.928"></a>
+<span class="sourceLineNo">929</span>   * Attempt to use builder API via 
reflection to create a file with the given parameters and<a name="line.929"></a>
+<span class="sourceLineNo">930</span>   * replication enabled.<a 
name="line.930"></a>
+<span class="sourceLineNo">931</span>   * &lt;p&gt;<a name="line.931"></a>
+<span class="sourceLineNo">932</span>   * Will not attempt to enable 
replication when passed an HFileSystem.<a name="line.932"></a>
+<span class="sourceLineNo">933</span>   */<a name="line.933"></a>
+<span class="sourceLineNo">934</span>  public static FSDataOutputStream 
createForWal(FileSystem fs, Path path, boolean overwritable)<a 
name="line.934"></a>
+<span class="sourceLineNo">935</span>      throws IOException {<a 
name="line.935"></a>
+<span class="sourceLineNo">936</span>    return 
DfsBuilderUtility.createHelper(fs, path, overwritable);<a name="line.936"></a>
+<span class="sourceLineNo">937</span>  }<a name="line.937"></a>
+<span class="sourceLineNo">938</span><a name="line.938"></a>
+<span class="sourceLineNo">939</span>  /**<a name="line.939"></a>
+<span class="sourceLineNo">940</span>   * Attempt to use builder API via 
reflection to create a file with the given parameters and<a name="line.940"></a>
+<span class="sourceLineNo">941</span>   * replication enabled.<a 
name="line.941"></a>
+<span class="sourceLineNo">942</span>   * &lt;p&gt;<a name="line.942"></a>
+<span class="sourceLineNo">943</span>   * Will not attempt to enable 
replication when passed an HFileSystem.<a name="line.943"></a>
+<span class="sourceLineNo">944</span>   */<a name="line.944"></a>
+<span class="sourceLineNo">945</span>  public static FSDataOutputStream 
createForWal(FileSystem fs, Path path, boolean overwritable,<a 
name="line.945"></a>
+<span class="sourceLineNo">946</span>      int bufferSize, short replication, 
long blockSize, boolean isRecursive) throws IOException {<a name="line.946"></a>
+<span class="sourceLineNo">947</span>    return 
DfsBuilderUtility.createHelper(fs, path, overwritable, bufferSize, 
replication,<a name="line.947"></a>
+<span class="sourceLineNo">948</span>        blockSize, isRecursive);<a 
name="line.948"></a>
+<span class="sourceLineNo">949</span>  }<a name="line.949"></a>
+<span class="sourceLineNo">950</span><a name="line.950"></a>
+<span class="sourceLineNo">951</span>  // Holder singleton idiom. JVM spec 
ensures this will be run at most once per Classloader, and<a 
name="line.951"></a>
+<span class="sourceLineNo">952</span>  // not until we attempt to reference 
it.<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  private static class StreamCapabilities 
{<a name="line.953"></a>
+<span class="sourceLineNo">954</span>    public static final boolean 
PRESENT;<a name="line.954"></a>
+<span class="sourceLineNo">955</span>    public static final Class&lt;?&gt; 
CLASS;<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    public static final Method METHOD;<a 
name="line.956"></a>
+<span class="sourceLineNo">957</span>    static {<a name="line.957"></a>
+<span class="sourceLineNo">958</span>      boolean tmp = false;<a 
name="line.958"></a>
+<span class="sourceLineNo">959</span>      Class&lt;?&gt; clazz = null;<a 
name="line.959"></a>
+<span class="sourceLineNo">960</span>      Method method = null;<a 
name="line.960"></a>
+<span class="sourceLineNo">961</span>      try {<a name="line.961"></a>
+<span class="sourceLineNo">962</span>        clazz = 
Class.forName("org.apache.hadoop.fs.StreamCapabilities");<a name="line.962"></a>
+<span class="sourceLineNo">963</span>        method = 
clazz.getMethod("hasCapability", String.class);<a name="line.963"></a>
+<span class="sourceLineNo">964</span>        tmp = true;<a name="line.964"></a>
+<span class="sourceLineNo">965</span>      } 
catch(ClassNotFoundException|NoSuchMethodException|SecurityException exception) 
{<a name="line.965"></a>
+<span class="sourceLineNo">966</span>        LOG.warn("Your Hadoop 
installation does not include the StreamCapabilities class from " +<a 
name="line.966"></a>
+<span class="sourceLineNo">967</span>                 "HDFS-11644, so we will 
skip checking if any FSDataOutputStreams actually " +<a name="line.967"></a>
+<span class="sourceLineNo">968</span>                 "support hflush/hsync. 
If you are running on top of HDFS this probably just " +<a name="line.968"></a>
+<span class="sourceLineNo">969</span>                 "means you have an older 
version and this can be ignored. If you are running on " +<a 
name="line.969"></a>
+<span class="sourceLineNo">970</span>                 "top of an alternate 
FileSystem implementation you should manually verify that " +<a 
name="line.970"></a>
+<span class="sourceLineNo">971</span>                 "hflush and hsync are 
implemented; otherwise you risk data loss and hard to " +<a name="line.971"></a>
+<span class="sourceLineNo">972</span>                 "diagnose errors when 
our assumptions are violated.");<a name="line.972"></a>
+<span class="sourceLineNo">973</span>        LOG.debug("The first request to 
check for StreamCapabilities came from this stacktrace.",<a name="line.973"></a>
+<span class="sourceLineNo">974</span>            exception);<a 
name="line.974"></a>
+<span class="sourceLineNo">975</span>      } finally {<a name="line.975"></a>
+<span class="sourceLineNo">976</span>        PRESENT = tmp;<a 
name="line.976"></a>
+<span class="sourceLineNo">977</span>        CLASS = clazz;<a 
name="line.977"></a>
+<span class="sourceLineNo">978</span>        METHOD = method;<a 
name="line.978"></a>
+<span class="sourceLineNo">979</span>      }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>    }<a name="line.980"></a>
+<span class="sourceLineNo">981</span>  }<a name="line.981"></a>
+<span class="sourceLineNo">982</span><a name="line.982"></a>
+<span class="sourceLineNo">983</span>  /**<a name="line.983"></a>
+<span class="sourceLineNo">984</span>   * If our FileSystem version includes 
the StreamCapabilities class, check if<a name="line.984"></a>
+<span class="sourceLineNo">985</span>   * the given stream has a particular 
capability.<a name="line.985"></a>
+<span class="sourceLineNo">986</span>   * @param stream capabilities are 
per-stream instance, so check this one specifically. must not be<a 
name="line.986"></a>
+<span class="sourceLineNo">987</span>   *        null<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   * @param capability what to look for, 
per Hadoop Common's FileSystem docs<a name="line.988"></a>
+<span class="sourceLineNo">989</span>   * @return true if there are no 
StreamCapabilities. false if there are, but this stream doesn't<a 
name="line.989"></a>
+<span class="sourceLineNo">990</span>   *         implement it. return result 
of asking the stream otherwise.<a name="line.990"></a>
+<span class="sourceLineNo">991</span>   */<a name="line.991"></a>
+<span class="sourceLineNo">992</span>  public static boolean 
hasCapability(FSDataOutputStream stream, String capability) {<a 
name="line.992"></a>
+<span class="sourceLineNo">993</span>    // be consistent whether or not 
StreamCapabilities is present<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    if (stream == null) {<a 
name="line.994"></a>
+<span class="sourceLineNo">995</span>      throw new 
NullPointerException("stream parameter must not be null.");<a 
name="line.995"></a>
+<span class="sourceLineNo">996</span>    }<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    // If o.a.h.fs.StreamCapabilities 
doesn't exist, assume everyone does everything<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    // otherwise old versions of Hadoop 
will break.<a name="line.998"></a>
+<span class="sourceLineNo">999</span>    boolean result = true;<a 
name="line.999"></a>
+<span class="sourceLineNo">1000</span>    if (StreamCapabilities.PRESENT) {<a 
name="line.1000"></a>
+<span class="sourceLineNo">1001</span>      // if StreamCapabilities is 
present, but the stream doesn't implement it<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>      // or we run into a problem 
invoking the method,<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>      // we treat that as equivalent to 
not declaring anything<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      result = false;<a 
name="line.1004"></a>
+<span class="sourceLineNo">1005</span>      if 
(StreamCapabilities.CLASS.isAssignableFrom(stream.getClass())) {<a 
name="line.1005"></a>
+<span class="sourceLineNo">1006</span>        try {<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>          result = 
((Boolean)StreamCapabilities.METHOD.invoke(stream, 
capability)).booleanValue();<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span>        } catch 
(IllegalAccessException|IllegalArgumentException|InvocationTargetException<a 
name="line.1008"></a>
+<span class="sourceLineNo">1009</span>            exception) {<a 
name="line.1009"></a>
+<span class="sourceLineNo">1010</span>          LOG.warn("Your Hadoop 
installation's StreamCapabilities implementation doesn't match " +<a 
name="line.1010"></a>
+<span class="sourceLineNo">1011</span>              "our understanding of how 
it's supposed to work. Please file a JIRA and include " +<a 
name="line.1011"></a>
+<span class="sourceLineNo">1012</span>              "the following stack 
trace. In the mean time we're interpreting this behavior " +<a 
name="line.1012"></a>
+<span class="sourceLineNo">1013</span>              "difference as a lack of 
capability support, which will probably cause a failure.",<a 
name="line.1013"></a>
+<span class="sourceLineNo">1014</span>              exception);<a 
name="line.1014"></a>
+<span class="sourceLineNo">1015</span>        }<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>      }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span>    }<a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>    return result;<a 
name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  }<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span><a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  /**<a name="line.1021"></a>
+<span class="sourceLineNo">1022</span>   * Helper exception for those cases 
where the place where we need to check a stream capability<a 
name="line.1022"></a>
+<span class="sourceLineNo">1023</span>   * is not where we have the needed 
context to explain the impact and mitigation for a lack.<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>   */<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  public static class 
StreamLacksCapabilityException extends Exception {<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>    public 
StreamLacksCapabilityException(String message, Throwable cause) {<a 
name="line.1026"></a>
+<span class="sourceLineNo">1027</span>      super(message, cause);<a 
name="line.1027"></a>
+<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    public 
StreamLacksCapabilityException(String message) {<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>      super(message);<a 
name="line.1030"></a>
+<span class="sourceLineNo">1031</span>    }<a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>  }<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span><a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>}<a name="line.1034"></a>
 
 
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/e10887fe/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamLacksCapabilityException.html
----------------------------------------------------------------------
diff --git 
a/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamLacksCapabilityException.html
 
b/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamLacksCapabilityException.html
index c6bfdca..cae3d07 100644
--- 
a/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamLacksCapabilityException.html
+++ 
b/devapidocs/src-html/org/apache/hadoop/hbase/util/CommonFSUtils.StreamLacksCapabilityException.html
@@ -829,90 +829,217 @@
 <span class="sourceLineNo">821</span>    conf.setIfUnset(dfsKey, 
Integer.toString(hbaseSize));<a name="line.821"></a>
 <span class="sourceLineNo">822</span>  }<a name="line.822"></a>
 <span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>  // Holder singleton idiom. JVM spec 
ensures this will be run at most once per Classloader, and<a 
name="line.824"></a>
-<span class="sourceLineNo">825</span>  // not until we attempt to reference 
it.<a name="line.825"></a>
-<span class="sourceLineNo">826</span>  private static class StreamCapabilities 
{<a name="line.826"></a>
-<span class="sourceLineNo">827</span>    public static final boolean 
PRESENT;<a name="line.827"></a>
-<span class="sourceLineNo">828</span>    public static final Class&lt;?&gt; 
CLASS;<a name="line.828"></a>
-<span class="sourceLineNo">829</span>    public static final Method METHOD;<a 
name="line.829"></a>
-<span class="sourceLineNo">830</span>    static {<a name="line.830"></a>
-<span class="sourceLineNo">831</span>      boolean tmp = false;<a 
name="line.831"></a>
-<span class="sourceLineNo">832</span>      Class&lt;?&gt; clazz = null;<a 
name="line.832"></a>
-<span class="sourceLineNo">833</span>      Method method = null;<a 
name="line.833"></a>
-<span class="sourceLineNo">834</span>      try {<a name="line.834"></a>
-<span class="sourceLineNo">835</span>        clazz = 
Class.forName("org.apache.hadoop.fs.StreamCapabilities");<a name="line.835"></a>
-<span class="sourceLineNo">836</span>        method = 
clazz.getMethod("hasCapability", String.class);<a name="line.836"></a>
-<span class="sourceLineNo">837</span>        tmp = true;<a name="line.837"></a>
-<span class="sourceLineNo">838</span>      } 
catch(ClassNotFoundException|NoSuchMethodException|SecurityException exception) 
{<a name="line.838"></a>
-<span class="sourceLineNo">839</span>        LOG.warn("Your Hadoop 
installation does not include the StreamCapabilities class from " +<a 
name="line.839"></a>
-<span class="sourceLineNo">840</span>                 "HDFS-11644, so we will 
skip checking if any FSDataOutputStreams actually " +<a name="line.840"></a>
-<span class="sourceLineNo">841</span>                 "support hflush/hsync. 
If you are running on top of HDFS this probably just " +<a name="line.841"></a>
-<span class="sourceLineNo">842</span>                 "means you have an older 
version and this can be ignored. If you are running on " +<a 
name="line.842"></a>
-<span class="sourceLineNo">843</span>                 "top of an alternate 
FileSystem implementation you should manually verify that " +<a 
name="line.843"></a>
-<span class="sourceLineNo">844</span>                 "hflush and hsync are 
implemented; otherwise you risk data loss and hard to " +<a name="line.844"></a>
-<span class="sourceLineNo">845</span>                 "diagnose errors when 
our assumptions are violated.");<a name="line.845"></a>
-<span class="sourceLineNo">846</span>        LOG.debug("The first request to 
check for StreamCapabilities came from this stacktrace.",<a name="line.846"></a>
-<span class="sourceLineNo">847</span>            exception);<a 
name="line.847"></a>
-<span class="sourceLineNo">848</span>      } finally {<a name="line.848"></a>
-<span class="sourceLineNo">849</span>        PRESENT = tmp;<a 
name="line.849"></a>
-<span class="sourceLineNo">850</span>        CLASS = clazz;<a 
name="line.850"></a>
-<span class="sourceLineNo">851</span>        METHOD = method;<a 
name="line.851"></a>
-<span class="sourceLineNo">852</span>      }<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span>  }<a name="line.854"></a>
-<span class="sourceLineNo">855</span><a name="line.855"></a>
-<span class="sourceLineNo">856</span>  /**<a name="line.856"></a>
-<span class="sourceLineNo">857</span>   * If our FileSystem version includes 
the StreamCapabilities class, check if<a name="line.857"></a>
-<span class="sourceLineNo">858</span>   * the given stream has a particular 
capability.<a name="line.858"></a>
-<span class="sourceLineNo">859</span>   * @param stream capabilities are 
per-stream instance, so check this one specifically. must not be<a 
name="line.859"></a>
-<span class="sourceLineNo">860</span>   *        null<a name="line.860"></a>
-<span class="sourceLineNo">861</span>   * @param capability what to look for, 
per Hadoop Common's FileSystem docs<a name="line.861"></a>
-<span class="sourceLineNo">862</span>   * @return true if there are no 
StreamCapabilities. false if there are, but this stream doesn't<a 
name="line.862"></a>
-<span class="sourceLineNo">863</span>   *         implement it. return result 
of asking the stream otherwise.<a name="line.863"></a>
-<span class="sourceLineNo">864</span>   */<a name="line.864"></a>
-<span class="sourceLineNo">865</span>  public static boolean 
hasCapability(FSDataOutputStream stream, String capability) {<a 
name="line.865"></a>
-<span class="sourceLineNo">866</span>    // be consistent whether or not 
StreamCapabilities is present<a name="line.866"></a>
-<span class="sourceLineNo">867</span>    if (stream == null) {<a 
name="line.867"></a>
-<span class="sourceLineNo">868</span>      throw new 
NullPointerException("stream parameter must not be null.");<a 
name="line.868"></a>
-<span class="sourceLineNo">869</span>    }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    // If o.a.h.fs.StreamCapabilities 
doesn't exist, assume everyone does everything<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    // otherwise old versions of Hadoop 
will break.<a name="line.871"></a>
-<span class="sourceLineNo">872</span>    boolean result = true;<a 
name="line.872"></a>
-<span class="sourceLineNo">873</span>    if (StreamCapabilities.PRESENT) {<a 
name="line.873"></a>
-<span class="sourceLineNo">874</span>      // if StreamCapabilities is 
present, but the stream doesn't implement it<a name="line.874"></a>
-<span class="sourceLineNo">875</span>      // or we run into a problem 
invoking the method,<a name="line.875"></a>
-<span class="sourceLineNo">876</span>      // we treat that as equivalent to 
not declaring anything<a name="line.876"></a>
-<span class="sourceLineNo">877</span>      result = false;<a 
name="line.877"></a>
-<span class="sourceLineNo">878</span>      if 
(StreamCapabilities.CLASS.isAssignableFrom(stream.getClass())) {<a 
name="line.878"></a>
+<span class="sourceLineNo">824</span>  private static class DfsBuilderUtility 
{<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    static Class&lt;?&gt; dfsClass = 
null;<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    static Method createMethod;<a 
name="line.826"></a>
+<span class="sourceLineNo">827</span>    static Method overwriteMethod;<a 
name="line.827"></a>
+<span class="sourceLineNo">828</span>    static Method bufferSizeMethod;<a 
name="line.828"></a>
+<span class="sourceLineNo">829</span>    static Method blockSizeMethod;<a 
name="line.829"></a>
+<span class="sourceLineNo">830</span>    static Method recursiveMethod;<a 
name="line.830"></a>
+<span class="sourceLineNo">831</span>    static Method replicateMethod;<a 
name="line.831"></a>
+<span class="sourceLineNo">832</span>    static Method replicationMethod;<a 
name="line.832"></a>
+<span class="sourceLineNo">833</span>    static Method buildMethod;<a 
name="line.833"></a>
+<span class="sourceLineNo">834</span>    static boolean allMethodsPresent = 
false;<a name="line.834"></a>
+<span class="sourceLineNo">835</span><a name="line.835"></a>
+<span class="sourceLineNo">836</span>    static {<a name="line.836"></a>
+<span class="sourceLineNo">837</span>      String dfsName = 
"org.apache.hadoop.hdfs.DistributedFileSystem";<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      String builderName = dfsName + 
"$HdfsDataOutputStreamBuilder";<a name="line.838"></a>
+<span class="sourceLineNo">839</span>      Class&lt;?&gt; builderClass = 
null;<a name="line.839"></a>
+<span class="sourceLineNo">840</span><a name="line.840"></a>
+<span class="sourceLineNo">841</span>      try {<a name="line.841"></a>
+<span class="sourceLineNo">842</span>        dfsClass = 
Class.forName(dfsName);<a name="line.842"></a>
+<span class="sourceLineNo">843</span>      } catch (ClassNotFoundException e) 
{<a name="line.843"></a>
+<span class="sourceLineNo">844</span>        LOG.debug("{} not available, will 
not use builder API for file creation.", dfsName);<a name="line.844"></a>
+<span class="sourceLineNo">845</span>      }<a name="line.845"></a>
+<span class="sourceLineNo">846</span>      try {<a name="line.846"></a>
+<span class="sourceLineNo">847</span>        builderClass = 
Class.forName(builderName);<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      } catch (ClassNotFoundException e) 
{<a name="line.848"></a>
+<span class="sourceLineNo">849</span>        LOG.debug("{} not available, will 
not use builder API for file creation.", builderName);<a name="line.849"></a>
+<span class="sourceLineNo">850</span>      }<a name="line.850"></a>
+<span class="sourceLineNo">851</span><a name="line.851"></a>
+<span class="sourceLineNo">852</span>      if (dfsClass != null &amp;&amp; 
builderClass != null) {<a name="line.852"></a>
+<span class="sourceLineNo">853</span>        try {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>          createMethod = 
dfsClass.getMethod("createFile", Path.class);<a name="line.854"></a>
+<span class="sourceLineNo">855</span>          overwriteMethod = 
builderClass.getMethod("overwrite", boolean.class);<a name="line.855"></a>
+<span class="sourceLineNo">856</span>          bufferSizeMethod = 
builderClass.getMethod("bufferSize", int.class);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>          blockSizeMethod = 
builderClass.getMethod("blockSize", long.class);<a name="line.857"></a>
+<span class="sourceLineNo">858</span>          recursiveMethod = 
builderClass.getMethod("recursive");<a name="line.858"></a>
+<span class="sourceLineNo">859</span>          replicateMethod = 
builderClass.getMethod("replicate");<a name="line.859"></a>
+<span class="sourceLineNo">860</span>          replicationMethod = 
builderClass.getMethod("replication", short.class);<a name="line.860"></a>
+<span class="sourceLineNo">861</span>          buildMethod = 
builderClass.getMethod("build");<a name="line.861"></a>
+<span class="sourceLineNo">862</span><a name="line.862"></a>
+<span class="sourceLineNo">863</span>          allMethodsPresent = true;<a 
name="line.863"></a>
+<span class="sourceLineNo">864</span>          LOG.debug("Using builder API 
via reflection for DFS file creation.");<a name="line.864"></a>
+<span class="sourceLineNo">865</span>        } catch (NoSuchMethodException e) 
{<a name="line.865"></a>
+<span class="sourceLineNo">866</span>          LOG.debug("Could not find 
method on builder; will use old DFS API for file creation {}",<a 
name="line.866"></a>
+<span class="sourceLineNo">867</span>              e.getMessage());<a 
name="line.867"></a>
+<span class="sourceLineNo">868</span>        }<a name="line.868"></a>
+<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
+<span class="sourceLineNo">871</span><a name="line.871"></a>
+<span class="sourceLineNo">872</span>    /**<a name="line.872"></a>
+<span class="sourceLineNo">873</span>     * Attempt to use builder API via 
reflection to create a file with the given parameters and<a name="line.873"></a>
+<span class="sourceLineNo">874</span>     * replication enabled.<a 
name="line.874"></a>
+<span class="sourceLineNo">875</span>     */<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    static FSDataOutputStream 
createHelper(FileSystem fs, Path path, boolean overwritable,<a 
name="line.876"></a>
+<span class="sourceLineNo">877</span>        int bufferSize, short 
replication, long blockSize, boolean isRecursive) throws IOException {<a 
name="line.877"></a>
+<span class="sourceLineNo">878</span>      if (allMethodsPresent &amp;&amp; 
dfsClass.isInstance(fs)) {<a name="line.878"></a>
 <span class="sourceLineNo">879</span>        try {<a name="line.879"></a>
-<span class="sourceLineNo">880</span>          result = 
((Boolean)StreamCapabilities.METHOD.invoke(stream, 
capability)).booleanValue();<a name="line.880"></a>
-<span class="sourceLineNo">881</span>        } catch 
(IllegalAccessException|IllegalArgumentException|InvocationTargetException<a 
name="line.881"></a>
-<span class="sourceLineNo">882</span>            exception) {<a 
name="line.882"></a>
-<span class="sourceLineNo">883</span>          LOG.warn("Your Hadoop 
installation's StreamCapabilities implementation doesn't match " +<a 
name="line.883"></a>
-<span class="sourceLineNo">884</span>              "our understanding of how 
it's supposed to work. Please file a JIRA and include " +<a name="line.884"></a>
-<span class="sourceLineNo">885</span>              "the following stack trace. 
In the mean time we're interpreting this behavior " +<a name="line.885"></a>
-<span class="sourceLineNo">886</span>              "difference as a lack of 
capability support, which will probably cause a failure.",<a 
name="line.886"></a>
-<span class="sourceLineNo">887</span>              exception);<a 
name="line.887"></a>
-<span class="sourceLineNo">888</span>        }<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      }<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
-<span class="sourceLineNo">891</span>    return result;<a name="line.891"></a>
-<span class="sourceLineNo">892</span>  }<a name="line.892"></a>
-<span class="sourceLineNo">893</span><a name="line.893"></a>
-<span class="sourceLineNo">894</span>  /**<a name="line.894"></a>
-<span class="sourceLineNo">895</span>   * Helper exception for those cases 
where the place where we need to check a stream capability<a 
name="line.895"></a>
-<span class="sourceLineNo">896</span>   * is not where we have the needed 
context to explain the impact and mitigation for a lack.<a name="line.896"></a>
-<span class="sourceLineNo">897</span>   */<a name="line.897"></a>
-<span class="sourceLineNo">898</span>  public static class 
StreamLacksCapabilityException extends Exception {<a name="line.898"></a>
-<span class="sourceLineNo">899</span>    public 
StreamLacksCapabilityException(String message, Throwable cause) {<a 
name="line.899"></a>
-<span class="sourceLineNo">900</span>      super(message, cause);<a 
name="line.900"></a>
-<span class="sourceLineNo">901</span>    }<a name="line.901"></a>
-<span class="sourceLineNo">902</span>    public 
StreamLacksCapabilityException(String message) {<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      super(message);<a 
name="line.903"></a>
-<span class="sourceLineNo">904</span>    }<a name="line.904"></a>
-<span class="sourceLineNo">905</span>  }<a name="line.905"></a>
-<span class="sourceLineNo">906</span><a name="line.906"></a>
-<span class="sourceLineNo">907</span>}<a name="line.907"></a>
+<span class="sourceLineNo">880</span>          Object builder;<a 
name="line.880"></a>
+<span class="sourceLineNo">881</span><a name="line.881"></a>
+<span class="sourceLineNo">882</span>          builder = 
createMethod.invoke(fs, path);<a name="line.882"></a>
+<span class="sourceLineNo">883</span>          builder = 
overwriteMethod.invoke(builder, overwritable);<a name="line.883"></a>
+<span class="sourceLineNo">884</span>          builder = 
bufferSizeMethod.invoke(builder, bufferSize);<a name="line.884"></a>
+<span class="sourceLineNo">885</span>          builder = 
blockSizeMethod.invoke(builder, blockSize);<a name="line.885"></a>
+<span class="sourceLineNo">886</span>          if (isRecursive) {<a 
name="line.886"></a>
+<span class="sourceLineNo">887</span>            builder = 
recursiveMethod.invoke(builder);<a name="line.887"></a>
+<span class="sourceLineNo">888</span>          }<a name="line.888"></a>
+<span class="sourceLineNo">889</span>          builder = 
replicateMethod.invoke(builder);<a name="line.889"></a>
+<span class="sourceLineNo">890</span>          builder = 
replicationMethod.invoke(builder, replication);<a name="line.890"></a>
+<span class="sourceLineNo">891</span>          return (FSDataOutputStream) 
buildMethod.invoke(builder);<a name="line.891"></a>
+<span class="sourceLineNo">892</span>        } catch (IllegalAccessException | 
InvocationTargetException e) {<a name="line.892"></a>
+<span class="sourceLineNo">893</span>          // Should have caught this 
failure during initialization, so log full trace here<a name="line.893"></a>
+<span class="sourceLineNo">894</span>          LOG.warn("Couldn't use 
reflection with builder API", e);<a name="line.894"></a>
+<span class="sourceLineNo">895</span>        }<a name="line.895"></a>
+<span class="sourceLineNo">896</span>      }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>      if (isRecursive) {<a 
name="line.898"></a>
+<span class="sourceLineNo">899</span>        return fs.create(path, 
overwritable, bufferSize, replication, blockSize, null);<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      }<a name="line.900"></a>
+<span class="sourceLineNo">901</span>      return fs.createNonRecursive(path, 
overwritable, bufferSize, replication, blockSize, null);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    }<a name="line.902"></a>
+<span class="sourceLineNo">903</span><a name="line.903"></a>
+<span class="sourceLineNo">904</span>    /**<a name="line.904"></a>
+<span class="sourceLineNo">905</span>     * Attempt to use builder API via 
reflection to create a file with the given parameters and<a name="line.905"></a>
+<span class="sourceLineNo">906</span>     * replication enabled.<a 
name="line.906"></a>
+<span class="sourceLineNo">907</span>     */<a name="line.907"></a>
+<span class="sourceLineNo">908</span>    static FSDataOutputStream 
createHelper(FileSystem fs, Path path, boolean overwritable)<a 
name="line.908"></a>
+<span class="sourceLineNo">909</span>        throws IOException {<a 
name="line.909"></a>
+<span class="sourceLineNo">910</span>      if (allMethodsPresent &amp;&amp; 
dfsClass.isInstance(fs)) {<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        try {<a name="line.911"></a>
+<span class="sourceLineNo">912</span>          Object builder;<a 
name="line.912"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>          builder = 
createMethod.invoke(fs, path);<a name="line.914"></a>
+<span class="sourceLineNo">915</span>          builder = 
overwriteMethod.invoke(builder, overwritable);<a name="line.915"></a>
+<span class="sourceLineNo">916</span>          builder = 
replicateMethod.invoke(builder);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>          return (FSDataOutputStream) 
buildMethod.invoke(builder);<a name="line.917"></a>
+<span class="sourceLineNo">918</span>        } catch (IllegalAccessException | 
InvocationTargetException e) {<a name="line.918"></a>
+<span class="sourceLineNo">919</span>          // Should have caught this 
failure during initialization, so log full trace here<a name="line.919"></a>
+<span class="sourceLineNo">920</span>          LOG.warn("Couldn't use 
reflection with builder API", e);<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        }<a name="line.921"></a>
+<span class="sourceLineNo">922</span>      }<a name="line.922"></a>
+<span class="sourceLineNo">923</span><a name="line.923"></a>
+<span class="sourceLineNo">924</span>      return fs.create(path, 
overwritable);<a name="line.924"></a>
+<span class="sourceLineNo">925</span>    }<a name="line.925"></a>
+<span class="sourceLineNo">926</span>  }<a name="line.926"></a>
+<span class="sourceLineNo">927</span><a name="line.927"></a>
+<span class="sourceLineNo">928</span>  /**<a name="line.928"></a>
+<span class="sourceLineNo">929</span>   * Attempt to use builder API via 
reflection to create a file with the given parameters and<a name="line.929"></a>
+<span class="sourceLineNo">930</span>   * replication enabled.<a 
name="line.930"></a>
+<span class="sourceLineNo">931</span>   * &lt;p&gt;<a name="line.931"></a>
+<span class="sourceLineNo">932</span>   * Will not attempt to enable 
replication when passed an HFileSystem.<a name="line.932"></a>
+<span class="sourceLineNo">933</span>   */<a name="line.933"></a>
+<span class="sourceLineNo">934</span>  public static FSDataOutputStream 
createForWal(FileSystem fs, Path path, boolean overwritable)<a 
name="line.934"></a>
+<span class="sourceLineNo">935</span>      throws IOException {<a 
name="line.935"></a>
+<span class="sourceLineNo">936</span>    return 
DfsBuilderUtility.createHelper(fs, path, overwritable);<a name="line.936"></a>
+<span class="sourceLineNo">937</span>  }<a name="line.937"></a>
+<span class="sourceLineNo">938</span><a name="line.938"></a>
+<span class="sourceLineNo">939</span>  /**<a name="line.939"></a>
+<span class="sourceLineNo">940</span>   * Attempt to use builder API via 
reflection to create a file with the given parameters and<a name="line.940"></a>
+<span class="sourceLineNo">941</span>   * replication enabled.<a 
name="line.941"></a>
+<span class="sourceLineNo">942</span>   * &lt;p&gt;<a name="line.942"></a>
+<span class="sourceLineNo">943</span>   * Will not attempt to enable 
replication when passed an HFileSystem.<a name="line.943"></a>
+<span class="sourceLineNo">944</span>   */<a name="line.944"></a>
+<span class="sourceLineNo">945</span>  public static FSDataOutputStream 
createForWal(FileSystem fs, Path path, boolean overwritable,<a 
name="line.945"></a>
+<span class="sourceLineNo">946</span>      int bufferSize, short replication, 
long blockSize, boolean isRecursive) throws IOException {<a name="line.946"></a>
+<span class="sourceLineNo">947</span>    return 
DfsBuilderUtility.createHelper(fs, path, overwritable, bufferSize, 
replication,<a name="line.947"></a>
+<span class="sourceLineNo">948</span>        blockSize, isRecursive);<a 
name="line.948"></a>
+<span class="sourceLineNo">949</span>  }<a name="line.949"></a>
+<span class="sourceLineNo">950</span><a name="line.950"></a>
+<span class="sourceLineNo">951</span>  // Holder singleton idiom. JVM spec 
ensures this will be run at most once per Classloader, and<a 
name="line.951"></a>
+<span class="sourceLineNo">952</span>  // not until we attempt to reference 
it.<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  private static class StreamCapabilities 
{<a name="line.953"></a>
+<span class="sourceLineNo">954</span>    public static final boolean 
PRESENT;<a name="line.954"></a>
+<span class="sourceLineNo">955</span>    public static final Class&lt;?&gt; 
CLASS;<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    public static final Method METHOD;<a 
name="line.956"></a>
+<span class="sourceLineNo">957</span>    static {<a name="line.957"></a>
+<span class="sourceLineNo">958</span>      boolean tmp = false;<a 
name="line.958"></a>
+<span class="sourceLineNo">959</span>      Class&lt;?&gt; clazz = null;<a 
name="line.959"></a>
+<span class="sourceLineNo">960</span>      Method method = null;<a 
name="line.960"></a>
+<span class="sourceLineNo">961</span>      try {<a name="line.961"></a>
+<span class="sourceLineNo">962</span>        clazz = 
Class.forName("org.apache.hadoop.fs.StreamCapabilities");<a name="line.962"></a>
+<span class="sourceLineNo">963</span>        method = 
clazz.getMethod("hasCapability", String.class);<a name="line.963"></a>
+<span class="sourceLineNo">964</span>        tmp = true;<a name="line.964"></a>
+<span class="sourceLineNo">965</span>      } 
catch(ClassNotFoundException|NoSuchMethodException|SecurityException exception) 
{<a name="line.965"></a>
+<span class="sourceLineNo">966</span>        LOG.warn("Your Hadoop 
installation does not include the StreamCapabilities class from " +<a 
name="line.966"></a>
+<span class="sourceLineNo">967</span>                 "HDFS-11644, so we will 
skip checking if any FSDataOutputStreams actually " +<a name="line.967"></a>
+<span class="sourceLineNo">968</span>                 "support hflush/hsync. 
If you are running on top of HDFS this probably just " +<a name="line.968"></a>
+<span class="sourceLineNo">969</span>                 "means you have an older 
version and this can be ignored. If you are running on " +<a 
name="line.969"></a>
+<span class="sourceLineNo">970</span>                 "top of an alternate 
FileSystem implementation you should manually verify that " +<a 
name="line.970"></a>
+<span class="sourceLineNo">971</span>                 "hflush and hsync are 
implemented; otherwise you risk data loss and hard to " +<a name="line.971"></a>
+<span class="sourceLineNo">972</span>                 "diagnose errors when 
our assumptions are violated.");<a name="line.972"></a>
+<span class="sourceLineNo">973</span>        LOG.debug("The first request to 
check for StreamCapabilities came from this stacktrace.",<a name="line.973"></a>
+<span class="sourceLineNo">974</span>            exception);<a 
name="line.974"></a>
+<span class="sourceLineNo">975</span>      } finally {<a name="line.975"></a>
+<span class="sourceLineNo">976</span>        PRESENT = tmp;<a 
name="line.976"></a>
+<span class="sourceLineNo">977</span>        CLASS = clazz;<a 
name="line.977"></a>
+<span class="sourceLineNo">978</span>        METHOD = method;<a 
name="line.978"></a>
+<span class="sourceLineNo">979</span>      }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>    }<a name="line.980"></a>
+<span class="sourceLineNo">981</span>  }<a name="line.981"></a>
+<span class="sourceLineNo">982</span><a name="line.982"></a>
+<span class="sourceLineNo">983</span>  /**<a name="line.983"></a>
+<span class="sourceLineNo">984</span>   * If our FileSystem version includes 
the StreamCapabilities class, check if<a name="line.984"></a>
+<span class="sourceLineNo">985</span>   * the given stream has a particular 
capability.<a name="line.985"></a>
+<span class="sourceLineNo">986</span>   * @param stream capabilities are 
per-stream instance, so check this one specifically. must not be<a 
name="line.986"></a>
+<span class="sourceLineNo">987</span>   *        null<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   * @param capability what to look for, 
per Hadoop Common's FileSystem docs<a name="line.988"></a>
+<span class="sourceLineNo">989</span>   * @return true if there are no 
StreamCapabilities. false if there are, but this stream doesn't<a 
name="line.989"></a>
+<span class="sourceLineNo">990</span>   *         implement it. return result 
of asking the stream otherwise.<a name="line.990"></a>
+<span class="sourceLineNo">991</span>   */<a name="line.991"></a>
+<span class="sourceLineNo">992</span>  public static boolean 
hasCapability(FSDataOutputStream stream, String capability) {<a 
name="line.992"></a>
+<span class="sourceLineNo">993</span>    // be consistent whether or not 
StreamCapabilities is present<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    if (stream == null) {<a 
name="line.994"></a>
+<span class="sourceLineNo">995</span>      throw new 
NullPointerException("stream parameter must not be null.");<a 
name="line.995"></a>
+<span class="sourceLineNo">996</span>    }<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    // If o.a.h.fs.StreamCapabilities 
doesn't exist, assume everyone does everything<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    // otherwise old versions of Hadoop 
will break.<a name="line.998"></a>
+<span class="sourceLineNo">999</span>    boolean result = true;<a 
name="line.999"></a>
+<span class="sourceLineNo">1000</span>    if (StreamCapabilities.PRESENT) {<a 
name="line.1000"></a>
+<span class="sourceLineNo">1001</span>      // if StreamCapabilities is 
present, but the stream doesn't implement it<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>      // or we run into a problem 
invoking the method,<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>      // we treat that as equivalent to 
not declaring anything<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      result = false;<a 
name="line.1004"></a>
+<span class="sourceLineNo">1005</span>      if 
(StreamCapabilities.CLASS.isAssignableFrom(stream.getClass())) {<a 
name="line.1005"></a>
+<span class="sourceLineNo">1006</span>        try {<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>          result = 
((Boolean)StreamCapabilities.METHOD.invoke(stream, 
capability)).booleanValue();<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span>        } catch 
(IllegalAccessException|IllegalArgumentException|InvocationTargetException<a 
name="line.1008"></a>
+<span class="sourceLineNo">1009</span>            exception) {<a 
name="line.1009"></a>
+<span class="sourceLineNo">1010</span>          LOG.warn("Your Hadoop 
installation's StreamCapabilities implementation doesn't match " +<a 
name="line.1010"></a>
+<span class="sourceLineNo">1011</span>              "our understanding of how 
it's supposed to work. Please file a JIRA and include " +<a 
name="line.1011"></a>
+<span class="sourceLineNo">1012</span>              "the following stack 
trace. In the mean time we're interpreting this behavior " +<a 
name="line.1012"></a>
+<span class="sourceLineNo">1013</span>              "difference as a lack of 
capability support, which will probably cause a failure.",<a 
name="line.1013"></a>
+<span class="sourceLineNo">1014</span>              exception);<a 
name="line.1014"></a>
+<span class="sourceLineNo">1015</span>        }<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>      }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span>    }<a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>    return result;<a 
name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  }<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span><a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  /**<a name="line.1021"></a>
+<span class="sourceLineNo">1022</span>   * Helper exception for those cases 
where the place where we need to check a stream capability<a 
name="line.1022"></a>
+<span class="sourceLineNo">1023</span>   * is not where we have the needed 
context to explain the impact and mitigation for a lack.<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>   */<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  public static class 
StreamLacksCapabilityException extends Exception {<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>    public 
StreamLacksCapabilityException(String message, Throwable cause) {<a 
name="line.1026"></a>
+<span class="sourceLineNo">1027</span>      super(message, cause);<a 
name="line.1027"></a>
+<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    public 
StreamLacksCapabilityException(String message) {<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>      super(message);<a 
name="line.1030"></a>
+<span class="sourceLineNo">1031</span>    }<a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>  }<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span><a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>}<a name="line.1034"></a>
 
 
 

Reply via email to