You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by sy...@apache.org on 2016/02/22 23:20:43 UTC

[15/22] hbase git commit: HBASE-14877 maven archetype: client application (Daniel Vimont)

HBASE-14877 maven archetype: client application (Daniel Vimont)


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/afa63a91
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/afa63a91
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/afa63a91

Branch: refs/heads/hbase-12439
Commit: afa63a91d6500076178312e86288ac2393800145
Parents: 8eedc96
Author: Jonathan M Hsieh <jm...@apache.org>
Authored: Fri Feb 19 06:39:43 2016 -0800
Committer: Jonathan M Hsieh <jm...@apache.org>
Committed: Fri Feb 19 06:39:43 2016 -0800

----------------------------------------------------------------------
 hbase-archetypes/README.md                      | 142 ++++++++++++
 .../hbase-archetype-builder/createArchetypes.sh |  30 +++
 .../installArchetypes.sh                        |  31 +++
 .../modify_archetype_pom.xsl                    |  53 +++++
 .../modify_exemplar_pom.xsl                     |  48 ++++
 .../hbase-archetype-builder/pom.xml             | 226 +++++++++++++++++++
 hbase-archetypes/hbase-client-project/pom.xml   |  76 +++++++
 .../archetypes/exemplars/client/HelloHBase.java | 226 +++++++++++++++++++
 .../exemplars/client/package-info.java          |  25 ++
 .../src/main/resources/log4j.properties         | 111 +++++++++
 .../exemplars/client/TestHelloHBase.java        | 131 +++++++++++
 hbase-archetypes/pom.xml                        |  82 +++++++
 pom.xml                                         |   1 +
 src/main/asciidoc/_chapters/developer.adoc      |   9 +
 14 files changed, 1191 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/README.md
----------------------------------------------------------------------
diff --git a/hbase-archetypes/README.md b/hbase-archetypes/README.md
new file mode 100644
index 0000000..3af1f8b
--- /dev/null
+++ b/hbase-archetypes/README.md
@@ -0,0 +1,142 @@
+<!---
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+#hbase-archetypes
+
+##Overview
+The hbase-archetypes subproject of hbase provides an infrastructure for
+creation and maintenance of Maven archetypes<sup id="a1">[1](#f1)</sup>
+pertinent to HBase. Upon deployment to the archetype
+catalog<sup id="a2">[2](#f2)</sup> of the central Maven
+repository<sup id="a3">[3](#f3)</sup>, these archetypes may be used by
+end-user developers to autogenerate completely configured Maven projects
+(including fully-functioning sample code) through invocation of the
+`archetype:generate` goal of the
+maven-archetype-plugin<sup id="a4">[4](#f4)</sup>.
+
+##Notes for contributors and committers to the HBase project
+
+####The structure of hbase-archetypes
+The hbase-archetypes project contains a separate subproject for each archetype.
+The top level components of such a subproject comprise a complete, standalone
+exemplar Maven project containing:
+
+- a `src` directory with sample, fully-functioning code in the `./main` and
+`./test` subdirectories,
+- a `pom.xml` file defining all required dependencies, and
+- any additional resources required by the exemplar project.
+
+For example, the components of the hbase-client-project consist of (a) sample
+code `./src/main/.../HelloHBase.java` and `./src/test/.../TestHelloHBase.java`,
+(b) a `pom.xml` file establishing dependency upon hbase-client and test-scope
+dependency upon hbase-testing-util, and (c) a `log4j.properties` resource file.
+
+####How archetypes are created during the hbase install process
+During the `mvn install` process, all standalone exemplar projects in the
+`hbase-archetypes` subdirectory are first packaged/tested/installed, and then
+the following steps are executed in `hbase-archetypes/hbase-archetype-builder`
+(via the `pom.xml`, bash scripts, and xsl templates in that subdirectory):
+
+1. For each exemplar project, resources are copied (via
+maven-resources-plugin) and transformed (via xml-maven-plugin xslt
+functionality) to the exemplar project's `./target/build-archetype`
+subdirectory<sup id="a5">[5](#f5)</sup>.
+2. The script `createArchetypes.sh` is executed to invoke the
+maven-archetype-plugin's `create-from-project` goal within each exemplar
+project's `./target/build-archetype` subdirectory. For each exemplar
+project, this creates a corresponding Maven archetype in the
+`./target/build-archetype/target/generate-sources/archetype` subdirectory.
+(Note that this step always issues two platform-encoding warnings per
+archetype, due to hard-wired behavior of the
+maven-archetype-plugin<sup id="a6">[6](#f6)</sup>.)
+3. The `pom.xml` file of each newly-created archetype is copied (via
+maven-resources-plugin) and transformed (via xml-maven-plugin xslt
+functionality)<sup id="a7">[7](#f7)</sup>.
+4. The script `installArchetypes.sh` is executed to install each archetype
+into the local Maven repository, ready for deployment to the central Maven
+repository. (Note that installation of an archetype automatically includes
+invocation of integration-testing prior to install, which performs a test
+generation of a project from the archetype.)
+
+####How to add a new archetype to the hbase-archetypes collection
+1. Create a new subdirectory in `hbase-archetypes`, populated with a
+completely configured Maven project, which will serve as the exemplar project
+of the new archetype. (It may be most straightforward to simply copy the `src`
+and `pom.xml` components from one of the existing exemplar projects, replace
+the `src/main` and `src/test` code, and modify the `pom.xml` file's
+`<dependencies>`, `<artifactId>`,` <name>`, and `<description>` elements.)
+2. Modify the `hbase-archetype-builder/pom.xml` file: (a) add the new exemplar
+project to the `<modules>` element, and (b) add appropriate `<execution>`
+elements and `<transformationSet>` elements within the `<plugin>` elements
+(using the existing entries from already-existing exemplar projects as a guide).
+3. Add appropriate entries for the new exemplar project to the
+`createArchetypes.sh` and `installArchetypes.sh` scripts in the
+`hbase-archetype-builder` subdirectory (using the existing entries as a guide).
+
+####How to do additional testing/inspection of an archetype in this collection
+Although integration-testing (which is automatically performed for each
+archetype during the install process) already performs test generation of a
+project from an archetype, it may often be advisable to do further manual
+testing of a newly built and installed archetype, particularly to examine and
+test a project generated from the archetype (emulating the end-user experience
+of utilizing the archetype). Upon completion of the install process outlined
+above, all archetypes will have been installed in the local Maven repository
+and can be tested locally by executing the following:
+    `mvn archetype:generate -DarchetypeCatalog=local`
+This displays a numbered list of all locally-installed archetypes for the user
+to choose from for generation of a new Maven project.
+
+##Footnotes:
+<b id="f1">1</b> -- [Maven Archetype
+](http://maven.apache.org/archetype/index.html) ("About" page).
+-- [↩](#a1)
+
+<b id="f2">2</b> -- [Maven Archetype Catalog
+](http://repo1.maven.org/maven2/archetype-catalog.xml) (4MB+ xml file).
+-- [↩](#a2)
+
+<b id="f3">3</b> -- [Maven Central Repository](http://search.maven.org/)
+(search engine).
+-- [↩](#a3)
+
+<b id="f4">4</b> -- [Maven Archetype Plugin - archetype:generate
+](http://maven.apache.org/archetype/maven-archetype-plugin/generate-mojo.html).
+-- [↩](#a4)
+
+<b id="f5">5</b> -- Prior to archetype creation, each exemplar project's
+    `pom.xml` is transformed as follows to make it into a standalone project:
+    RESOURCE FILTERING (a) replaces `${project.version}` with the literal value
+    of the current project.version and (b) replaces `${compileSource}` with the
+    literal value of the version of Java that is being used for compilation;
+    XSLT TRANSFORMATION (a) copies `<groupId>` and `<version>` subelements of
+    `<parent>` to make them child elements of the root element, and (b) removes
+    the `<parent>` and `<description>` elements.
+    -- [↩](#a5)
+
+<b id="f6">6</b> -- For an explanation of the platform-encoding warning issued
+    during maven-archetype-plugin processing, see the first answer to [this
+    stackoverflow posting](http://stackoverflow.com/a/24161287/4112172).
+    -- [↩](#a6)
+
+<b id="f7">7</b> -- Prior to archetype installation, each archetype's `pom.xml`
+    is transformed as follows: a `<project.build.sourceEncoding>` subelement
+    with value 'UTF-8' is added to the `<properties>` element. This prevents
+    platform-encoding warnings from being issued when an end-user generates
+    a project from the archetype.
+    -- [↩](#a7)

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-archetype-builder/createArchetypes.sh
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-archetype-builder/createArchetypes.sh b/hbase-archetypes/hbase-archetype-builder/createArchetypes.sh
new file mode 100755
index 0000000..3aeb1c3
--- /dev/null
+++ b/hbase-archetypes/hbase-archetype-builder/createArchetypes.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -e      # exit if any step of this script fails
+workingDir=$(pwd)
+buildArchetypeSubdir=target/build-archetype
+
+# CREATE hbase-client archetype
+cd /"$workingDir"/../hbase-client-project/$buildArchetypeSubdir
+mvn archetype:create-from-project
+
+# add entries for additional archetypes above this comment (modeled on entries above)
+
+cd "$workingDir"

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-archetype-builder/installArchetypes.sh
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-archetype-builder/installArchetypes.sh b/hbase-archetypes/hbase-archetype-builder/installArchetypes.sh
new file mode 100755
index 0000000..74f118e
--- /dev/null
+++ b/hbase-archetypes/hbase-archetype-builder/installArchetypes.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -e      # exit if any step of this script fails
+workingDir=$(pwd)
+buildArchetypeSubdir=target/build-archetype
+archetypeSourceSubdir=target/generated-sources/archetype
+
+# INSTALL hbase-client archetype
+cd /"$workingDir"/../hbase-client-project/$buildArchetypeSubdir/$archetypeSourceSubdir
+mvn install
+
+# add entries for additional archetypes above this comment (modeled on entries above)
+
+cd "$workingDir"

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-archetype-builder/modify_archetype_pom.xsl
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-archetype-builder/modify_archetype_pom.xsl b/hbase-archetypes/hbase-archetype-builder/modify_archetype_pom.xsl
new file mode 100644
index 0000000..e27e51d
--- /dev/null
+++ b/hbase-archetypes/hbase-archetype-builder/modify_archetype_pom.xsl
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:pom="http://maven.apache.org/POM/4.0.0"
+    exclude-result-prefixes="pom">
+  <!--
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+  <xsl:output indent="yes"/>
+
+  <!-- copy all items from source to target with standard 'identity' template -->
+  <xsl:template match="@*|node()">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <!-- if properties element doesn't exist, insert it with sourceEncoding subelement -->
+  <xsl:template match="pom:project[not(pom:properties)]">
+    <xsl:copy>
+      <xsl:apply-templates select="@*"/>
+      <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+      </properties>
+      <xsl:apply-templates select="node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <!-- if properties element exists without sourceEncoding subelement, insert it -->
+  <xsl:template match="pom:properties[not(pom:project.build.sourceEncoding)]">
+    <xsl:copy>
+      <xsl:apply-templates select="@*"/>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+      <xsl:apply-templates select="node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+</xsl:transform>

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-archetype-builder/modify_exemplar_pom.xsl
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-archetype-builder/modify_exemplar_pom.xsl b/hbase-archetypes/hbase-archetype-builder/modify_exemplar_pom.xsl
new file mode 100644
index 0000000..0d7414f
--- /dev/null
+++ b/hbase-archetypes/hbase-archetype-builder/modify_exemplar_pom.xsl
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:pom="http://maven.apache.org/POM/4.0.0">
+  <!--
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+  <xsl:output indent="yes"/>
+
+  <!-- copy all items from source to target with standard 'identity' template;  -->
+   <xsl:template match="@*|node()">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <!-- copy groupId and version elements from parent element to top-level -->
+  <xsl:template match="pom:project[not(pom:groupId)]">
+    <xsl:copy>
+      <xsl:apply-templates select="@*"/>
+      <xsl:copy-of select="pom:parent/pom:groupId"/>
+      <xsl:copy-of select="pom:parent/pom:version"/>
+      <xsl:apply-templates select="node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <!-- find 'parent' element, and replace it with nothing (i.e. remove it) -->
+  <xsl:template match="pom:parent"/>
+
+  <!-- find 'description' element, and replace it with nothing (i.e. remove it) -->
+  <xsl:template match="pom:description"/>
+
+</xsl:transform>

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-archetype-builder/pom.xml
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-archetype-builder/pom.xml b/hbase-archetypes/hbase-archetype-builder/pom.xml
new file mode 100644
index 0000000..00a1305
--- /dev/null
+++ b/hbase-archetypes/hbase-archetype-builder/pom.xml
@@ -0,0 +1,226 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!--
+  /**
+   * Licensed to the Apache Software Foundation (ASF) under one
+   * or more contributor license agreements.  See the NOTICE file
+   * distributed with this work for additional information
+   * regarding copyright ownership.  The ASF licenses this file
+   * to you under the Apache License, Version 2.0 (the
+   * "License"); you may not use this file except in compliance
+   * with the License.  You may obtain a copy of the License at
+   *
+   *     http://www.apache.org/licenses/LICENSE-2.0
+   *
+   * Unless required by applicable law or agreed to in writing, software
+   * distributed under the License is distributed on an "AS IS" BASIS,
+   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   * See the License for the specific language governing permissions and
+   * limitations under the License.
+   */
+  -->
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <artifactId>hbase-archetypes</artifactId>
+    <groupId>org.apache.hbase</groupId>
+    <version>2.0.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <artifactId>hbase-archetype-builder</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Apache HBase - Archetype builder</name>
+  <description>Manager of plugins for building Maven archetypes from exemplars</description>
+
+  <properties>
+    <build.archetype.subdir>target/build-archetype</build.archetype.subdir>
+    <archetype.source.subdir>target/generated-sources/archetype</archetype.source.subdir>
+    <temp.exemplar.subdir>target/temp</temp.exemplar.subdir>
+    <temp.archetype.subdir>target/temp-arch</temp.archetype.subdir>
+    <hbase-client.dir>hbase-client-project</hbase-client.dir>
+    <!-- For new archetype, add corresponding *.dir property above this comment.
+         (See hbase-archetypes/README.txt for details on adding new archetype.) -->
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>2.7</version>
+        <executions>
+          <!-- maven-resources-plugin copies each exemplar project's src directory to
+            ${build.archetype.subdir} subdirectory, and copy each project's pom.xml file
+            to ${temp.exemplar.subdir} subdirectory. (Filtering during copy replaces
+            ${project-version} with literal value). The pom.xml files are processed
+            further using xml-maven-plugin for xslt transformation, below. -->
+          <execution>
+            <id>hbase-client__copy-src-to-build-archetype-subdir</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>/${project.basedir}/../${hbase-client.dir}/${build.archetype.subdir}</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>/${project.basedir}/../${hbase-client.dir}</directory>
+                  <includes>
+                    <include>src/**</include>
+                  </includes>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+          <execution>
+            <id>hbase-client__copy-pom-to-temp-for-xslt-processing</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>/${project.basedir}/../${hbase-client.dir}/${temp.exemplar.subdir}</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>/${project.basedir}/../${hbase-client.dir}</directory>
+                  <filtering>true</filtering> <!-- filtering replaces ${project.version} with literal -->
+                  <includes>
+                    <include>pom.xml</include>
+                  </includes>
+                 </resource>
+              </resources>
+            </configuration>
+          </execution>
+          <!-- For new archetype, add pair of <execution> elements (modeled on existing elements) above this comment. -->
+
+          <!-- maven-resources-plugin copies each archetype project's pom.xml file
+            to target/temp-arch directory. The pom.xml files are processed further
+            using xml-maven-plugin for xslt transformation, below.  -->
+          <execution>
+            <id>hbase-client-ARCHETYPE__copy-pom-to-temp-for-xslt-processing</id>
+            <phase>prepare-package</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>/${project.basedir}/../${hbase-client.dir}/${temp.archetype.subdir}</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>/${project.basedir}/../${hbase-client.dir}/${build.archetype.subdir}/${archetype.source.subdir}</directory>
+                  <includes>
+                    <include>pom.xml</include>
+                  </includes>
+                 </resource>
+              </resources>
+            </configuration>
+          </execution>
+          <!-- For new archetype, add <execution> element (modeled on existing elements) above this comment. -->
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>xml-maven-plugin</artifactId>
+        <version>1.0.1</version>
+        <executions>
+          <!-- xml-maven-plugin modifies each exemplar project's pom.xml file to convert to standalone project. -->
+          <execution>
+            <id>modify-exemplar-pom-files-via-xslt</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>transform</goal>
+            </goals>
+            <configuration>
+              <transformationSets>
+                <transformationSet>
+                  <dir>/${project.basedir}/../${hbase-client.dir}/${temp.exemplar.subdir}</dir>
+                  <includes>
+                    <include>pom.xml</include>
+                  </includes>
+                  <outputDir>/${project.basedir}/../${hbase-client.dir}/${build.archetype.subdir}</outputDir>
+                  <stylesheet>modify_exemplar_pom.xsl</stylesheet>
+                </transformationSet>
+                <!-- For new archetype, add <transformationSet> element (modeled on existing elements) above this comment. -->
+              </transformationSets>
+            </configuration>
+          </execution>
+          <!-- xml-maven-plugin modifies each archetype project's pom.xml file, inserting sourceEncoding element to
+               prevent warnings when project is generated from archetype.  -->
+          <execution>
+            <id>modify-archetype-pom-files-via-xslt</id>
+            <phase>package</phase>
+            <goals>
+              <goal>transform</goal>
+            </goals>
+            <configuration>
+              <transformationSets>
+                <transformationSet>
+                  <dir>/${project.basedir}/../${hbase-client.dir}/${temp.archetype.subdir}</dir>
+                  <includes>
+                    <include>pom.xml</include>
+                  </includes>
+                  <outputDir>/${project.basedir}/../${hbase-client.dir}/${build.archetype.subdir}/${archetype.source.subdir}</outputDir>
+                  <stylesheet>modify_archetype_pom.xsl</stylesheet>
+                </transformationSet>
+                <!-- For new archetype, add <transformationSet> element (modeled on existing elements) above this comment. -->
+              </transformationSets>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <version>1.4.0</version>
+        <executions>
+          <!-- exec-maven-plugin executes chmod to make scripts executable -->
+          <execution>
+            <id>make-scripts-executable</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>chmod</executable>
+              <arguments>
+                <argument>+x</argument>
+                <argument>/${project.basedir}/createArchetypes.sh</argument>
+                <argument>/${project.basedir}/installArchetypes.sh</argument>
+              </arguments>
+            </configuration>
+          </execution>
+          <!-- exec-maven-plugin executes script which invokes 'archetype:create-from-project'
+               to derive archetypes from exemplar projects. -->
+          <execution>
+            <id>run-createArchetypes-script</id>
+            <phase>compile</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>/${project.basedir}/createArchetypes.sh</executable>
+            </configuration>
+          </execution>
+          <!-- exec-maven-plugin executes script which invokes 'install' to install each
+               archetype into the local Maven repository (ready for deployment to central
+               Maven repository).
+               Note that 'install' of archetype automatically includes integration-test,
+               which does test generation of a project based on the archetype. -->
+          <execution>
+            <id>run-installArchetypes-script</id>
+            <phase>install</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>/${project.basedir}/installArchetypes.sh</executable>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-client-project/pom.xml
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-client-project/pom.xml b/hbase-archetypes/hbase-client-project/pom.xml
new file mode 100644
index 0000000..486f3ee
--- /dev/null
+++ b/hbase-archetypes/hbase-client-project/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation=
+           "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!--
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>hbase-archetypes</artifactId>
+    <groupId>org.apache.hbase</groupId>
+    <version>2.0.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>hbase-client-project</artifactId>
+  <packaging>jar</packaging>
+  <name>Apache HBase - Exemplar for hbase-client archetype</name>
+  <description>Exemplar project for archetype with hbase-client dependency</description>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.source>${compileSource}</maven.compiler.source>
+    <maven.compiler.target>${compileSource}</maven.compiler.target>
+    <surefire.version>2.19</surefire.version>
+    <junit.version>4.12</junit.version>
+  </properties>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <version>${surefire.version}</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <dependencies>
+    <!-- Dependency for hbase-testing-util must precede compile-scoped dependencies. -->
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-testing-util</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-client</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>${junit.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-client-project/src/main/java/org/apache/hbase/archetypes/exemplars/client/HelloHBase.java
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-client-project/src/main/java/org/apache/hbase/archetypes/exemplars/client/HelloHBase.java b/hbase-archetypes/hbase-client-project/src/main/java/org/apache/hbase/archetypes/exemplars/client/HelloHBase.java
new file mode 100644
index 0000000..c5b1b6a
--- /dev/null
+++ b/hbase-archetypes/hbase-client-project/src/main/java/org/apache/hbase/archetypes/exemplars/client/HelloHBase.java
@@ -0,0 +1,226 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hbase.archetypes.exemplars.client;
+
+import java.io.IOException;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.NamespaceNotFoundException;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.util.Bytes;
+
+/**
+ * Successful running of this application requires access to an active instance
+ * of HBase. For install instructions for a standalone instance of HBase, please
+ * refer to https://hbase.apache.org/book.html#quickstart
+ */
+public final class HelloHBase {
+
+  protected static final String MY_NAMESPACE_NAME = "myTestNamespace";
+  static final TableName MY_TABLE_NAME = TableName.valueOf("myTestTable");
+  static final byte[] MY_COLUMN_FAMILY_NAME = Bytes.toBytes("cf");
+  static final byte[] MY_FIRST_COLUMN_QUALIFIER
+          = Bytes.toBytes("myFirstColumn");
+  static final byte[] MY_SECOND_COLUMN_QUALIFIER
+          = Bytes.toBytes("mySecondColumn");
+  static final byte[] MY_ROW_ID = Bytes.toBytes("rowId01");
+
+  // Private constructor included here to avoid checkstyle warnings
+  private HelloHBase() {
+  }
+
+  public static void main(final String[] args) throws IOException {
+    final boolean deleteAllAtEOJ = true;
+
+    /**
+     * ConnectionFactory#createConnection() automatically looks for
+     * hbase-site.xml (HBase configuration parameters) on the system's
+     * CLASSPATH, to enable creation of Connection to HBase via Zookeeper.
+     */
+    try (Connection connection = ConnectionFactory.createConnection();
+            Admin admin = connection.getAdmin()) {
+
+      admin.getClusterStatus(); // assure connection successfully established
+      System.out.println("\n*** Hello HBase! -- Connection has been "
+              + "established via Zookeeper!!\n");
+
+      createNamespaceAndTable(admin);
+
+      System.out.println("Getting a Table object for [" + MY_TABLE_NAME
+              + "] with which to perform CRUD operations in HBase.");
+      try (Table table = connection.getTable(MY_TABLE_NAME)) {
+
+        putRowToTable(table);
+        getAndPrintRowContents(table);
+
+        if (deleteAllAtEOJ) {
+          deleteRow(table);
+        }
+      }
+
+      if (deleteAllAtEOJ) {
+        deleteNamespaceAndTable(admin);
+      }
+    }
+  }
+
+  /**
+   * Invokes Admin#createNamespace and Admin#createTable to create a namespace
+   * with a table that has one column-family.
+   *
+   * @param admin Standard Admin object
+   * @throws IOException If IO problem encountered
+   */
+  static void createNamespaceAndTable(final Admin admin) throws IOException {
+
+    if (!namespaceExists(admin, MY_NAMESPACE_NAME)) {
+      System.out.println("Creating Namespace [" + MY_NAMESPACE_NAME + "].");
+
+      admin.createNamespace(NamespaceDescriptor
+              .create(MY_NAMESPACE_NAME).build());
+    }
+    if (!admin.tableExists(MY_TABLE_NAME)) {
+      System.out.println("Creating Table [" + MY_TABLE_NAME.getNameAsString()
+              + "], with one Column Family ["
+              + Bytes.toString(MY_COLUMN_FAMILY_NAME) + "].");
+
+      admin.createTable(new HTableDescriptor(MY_TABLE_NAME)
+              .addFamily(new HColumnDescriptor(MY_COLUMN_FAMILY_NAME)));
+    }
+  }
+
+  /**
+   * Invokes Table#put to store a row (with two new columns created 'on the
+   * fly') into the table.
+   *
+   * @param table Standard Table object (used for CRUD operations).
+   * @throws IOException If IO problem encountered
+   */
+  static void putRowToTable(final Table table) throws IOException {
+
+    table.put(new Put(MY_ROW_ID).addColumn(MY_COLUMN_FAMILY_NAME,
+            MY_FIRST_COLUMN_QUALIFIER,
+            Bytes.toBytes("Hello")).addColumn(MY_COLUMN_FAMILY_NAME,
+                    MY_SECOND_COLUMN_QUALIFIER,
+                    Bytes.toBytes("World!")));
+
+    System.out.println("Row [" + Bytes.toString(MY_ROW_ID)
+            + "] was put into Table ["
+            + table.getName().getNameAsString() + "] in HBase;\n"
+            + "  the row's two columns (created 'on the fly') are: ["
+            + Bytes.toString(MY_COLUMN_FAMILY_NAME) + ":"
+            + Bytes.toString(MY_FIRST_COLUMN_QUALIFIER)
+            + "] and [" + Bytes.toString(MY_COLUMN_FAMILY_NAME) + ":"
+            + Bytes.toString(MY_SECOND_COLUMN_QUALIFIER) + "]");
+  }
+
+  /**
+   * Invokes Table#get and prints out the contents of the retrieved row.
+   *
+   * @param table Standard Table object
+   * @throws IOException If IO problem encountered
+   */
+  static void getAndPrintRowContents(final Table table) throws IOException {
+
+    Result row = table.get(new Get(MY_ROW_ID));
+
+    System.out.println("Row [" + Bytes.toString(row.getRow())
+            + "] was retrieved from Table ["
+            + table.getName().getNameAsString()
+            + "] in HBase, with the following content:");
+
+    for (Entry<byte[], NavigableMap<byte[], byte[]>> colFamilyEntry
+            : row.getNoVersionMap().entrySet()) {
+      String columnFamilyName = Bytes.toString(colFamilyEntry.getKey());
+
+      System.out.println("  Columns in Column Family [" + columnFamilyName
+              + "]:");
+
+      for (Entry<byte[], byte[]> columnNameAndValueMap
+              : colFamilyEntry.getValue().entrySet()) {
+
+        System.out.println("    Value of Column [" + columnFamilyName + ":"
+                + Bytes.toString(columnNameAndValueMap.getKey()) + "] == "
+                + Bytes.toString(columnNameAndValueMap.getValue()));
+      }
+    }
+  }
+
+  /**
+   * Checks to see whether a namespace exists.
+   *
+   * @param admin Standard Admin object
+   * @param namespaceName Name of namespace
+   * @return true If namespace exists
+   * @throws IOException If IO problem encountered
+   */
+  static boolean namespaceExists(final Admin admin, final String namespaceName)
+          throws IOException {
+    try {
+      admin.getNamespaceDescriptor(namespaceName);
+    } catch (NamespaceNotFoundException e) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Invokes Table#delete to delete test data (i.e. the row)
+   *
+   * @param table Standard Table object
+   * @throws IOException If IO problem is encountered
+   */
+  static void deleteRow(final Table table) throws IOException {
+    System.out.println("Deleting row [" + Bytes.toString(MY_ROW_ID)
+            + "] from Table ["
+            + table.getName().getNameAsString() + "].");
+    table.delete(new Delete(MY_ROW_ID));
+  }
+
+  /**
+   * Invokes Admin#disableTable, Admin#deleteTable, and Admin#deleteNamespace to
+   * disable/delete Table and delete Namespace.
+   *
+   * @param admin Standard Admin object
+   * @throws IOException If IO problem is encountered
+   */
+  static void deleteNamespaceAndTable(final Admin admin) throws IOException {
+    if (admin.tableExists(MY_TABLE_NAME)) {
+      System.out.println("Disabling/deleting Table ["
+              + MY_TABLE_NAME.getNameAsString() + "].");
+      admin.disableTable(MY_TABLE_NAME); // Disable a table before deleting it.
+      admin.deleteTable(MY_TABLE_NAME);
+    }
+    if (namespaceExists(admin, MY_NAMESPACE_NAME)) {
+      System.out.println("Deleting Namespace [" + MY_NAMESPACE_NAME + "].");
+      admin.deleteNamespace(MY_NAMESPACE_NAME);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-client-project/src/main/java/org/apache/hbase/archetypes/exemplars/client/package-info.java
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-client-project/src/main/java/org/apache/hbase/archetypes/exemplars/client/package-info.java b/hbase-archetypes/hbase-client-project/src/main/java/org/apache/hbase/archetypes/exemplars/client/package-info.java
new file mode 100644
index 0000000..554014e
--- /dev/null
+++ b/hbase-archetypes/hbase-client-project/src/main/java/org/apache/hbase/archetypes/exemplars/client/package-info.java
@@ -0,0 +1,25 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * This package provides fully-functional exemplar Java code demonstrating
+ * simple usage of the hbase-client API, for incorporation into a Maven
+ * archetype with hbase-client dependency.
+ */
+package org.apache.hbase.archetypes.exemplars.client;

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-client-project/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-client-project/src/main/resources/log4j.properties b/hbase-archetypes/hbase-client-project/src/main/resources/log4j.properties
new file mode 100644
index 0000000..d7c4552
--- /dev/null
+++ b/hbase-archetypes/hbase-client-project/src/main/resources/log4j.properties
@@ -0,0 +1,111 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Define some default values that can be overridden by system properties
+hbase.root.logger=INFO,console
+hbase.security.logger=INFO,console
+hbase.log.dir=.
+hbase.log.file=hbase.log
+
+# Define the root logger to the system property "hbase.root.logger".
+log4j.rootLogger=${hbase.root.logger}
+
+# Logging Threshold
+log4j.threshold=ALL
+
+#
+# Daily Rolling File Appender
+#
+log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.DRFA.File=${hbase.log.dir}/${hbase.log.file}
+
+# Rollver at midnight
+log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
+
+# 30-day backup
+#log4j.appender.DRFA.MaxBackupIndex=30
+log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout
+
+# Pattern format: Date LogLevel LoggerName LogMessage
+log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n
+
+# Rolling File Appender properties
+hbase.log.maxfilesize=256MB
+hbase.log.maxbackupindex=20
+
+# Rolling File Appender
+log4j.appender.RFA=org.apache.log4j.RollingFileAppender
+log4j.appender.RFA.File=${hbase.log.dir}/${hbase.log.file}
+
+log4j.appender.RFA.MaxFileSize=${hbase.log.maxfilesize}
+log4j.appender.RFA.MaxBackupIndex=${hbase.log.maxbackupindex}
+
+log4j.appender.RFA.layout=org.apache.log4j.PatternLayout
+log4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n
+
+#
+# Security audit appender
+#
+hbase.security.log.file=SecurityAuth.audit
+hbase.security.log.maxfilesize=256MB
+hbase.security.log.maxbackupindex=20
+log4j.appender.RFAS=org.apache.log4j.RollingFileAppender
+log4j.appender.RFAS.File=${hbase.log.dir}/${hbase.security.log.file}
+log4j.appender.RFAS.MaxFileSize=${hbase.security.log.maxfilesize}
+log4j.appender.RFAS.MaxBackupIndex=${hbase.security.log.maxbackupindex}
+log4j.appender.RFAS.layout=org.apache.log4j.PatternLayout
+log4j.appender.RFAS.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n
+log4j.category.SecurityLogger=${hbase.security.logger}
+log4j.additivity.SecurityLogger=false
+#log4j.logger.SecurityLogger.org.apache.hadoop.hbase.security.access.AccessController=TRACE
+#log4j.logger.SecurityLogger.org.apache.hadoop.hbase.security.visibility.VisibilityController=TRACE
+
+#
+# Null Appender
+#
+log4j.appender.NullAppender=org.apache.log4j.varia.NullAppender
+
+#
+# console
+# Add "console" to rootlogger above if you want to use this
+#
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n
+
+# Custom Logging levels
+
+log4j.logger.org.apache.zookeeper=INFO
+#log4j.logger.org.apache.hadoop.fs.FSNamesystem=DEBUG
+log4j.logger.org.apache.hadoop.hbase=INFO
+# Make these two classes INFO-level. Make them DEBUG to see more zk debug.
+log4j.logger.org.apache.hadoop.hbase.zookeeper.ZKUtil=INFO
+log4j.logger.org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher=INFO
+#log4j.logger.org.apache.hadoop.dfs=DEBUG
+# Set this class to log INFO only otherwise its OTT
+# Enable this to get detailed connection error/retry logging.
+# log4j.logger.org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation=TRACE
+
+
+# Uncomment this line to enable tracing on _every_ RPC call (this can be a lot of output)
+#log4j.logger.org.apache.hadoop.ipc.HBaseServer.trace=DEBUG
+
+# Uncomment the below if you want to remove logging of client region caching'
+# and scan of hbase:meta messages
+# log4j.logger.org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation=INFO
+# log4j.logger.org.apache.hadoop.hbase.client.MetaScanner=INFO

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/hbase-client-project/src/test/java/org/apache/hbase/archetypes/exemplars/client/TestHelloHBase.java
----------------------------------------------------------------------
diff --git a/hbase-archetypes/hbase-client-project/src/test/java/org/apache/hbase/archetypes/exemplars/client/TestHelloHBase.java b/hbase-archetypes/hbase-client-project/src/test/java/org/apache/hbase/archetypes/exemplars/client/TestHelloHBase.java
new file mode 100644
index 0000000..3d9dabd
--- /dev/null
+++ b/hbase-archetypes/hbase-client-project/src/test/java/org/apache/hbase/archetypes/exemplars/client/TestHelloHBase.java
@@ -0,0 +1,131 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hbase.archetypes.exemplars.client;
+
+import java.io.IOException;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.AfterClass;
+import static org.junit.Assert.assertEquals;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Unit testing for HelloHBase.
+ */
+@Category(MediumTests.class)
+public class TestHelloHBase {
+
+  private static final HBaseTestingUtility TEST_UTIL
+          = new HBaseTestingUtility();
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    TEST_UTIL.startMiniCluster(1);
+  }
+
+  @AfterClass
+  public static void afterClass() throws Exception {
+    TEST_UTIL.shutdownMiniCluster();
+  }
+
+  @Test
+  public void testNamespaceExists() throws Exception {
+    final String NONEXISTENT_NAMESPACE = "xyzpdq_nonexistent";
+    final String EXISTING_NAMESPACE = "pdqxyz_myExistingNamespace";
+    boolean exists;
+    Admin admin = TEST_UTIL.getHBaseAdmin();
+
+    exists = HelloHBase.namespaceExists(admin, NONEXISTENT_NAMESPACE);
+    assertEquals("#namespaceExists failed: found nonexistent namespace.",
+            false, exists);
+
+    admin.createNamespace
+        (NamespaceDescriptor.create(EXISTING_NAMESPACE).build());
+    exists = HelloHBase.namespaceExists(admin, EXISTING_NAMESPACE);
+    assertEquals("#namespaceExists failed: did NOT find existing namespace.",
+            true, exists);
+    admin.deleteNamespace(EXISTING_NAMESPACE);
+  }
+
+  @Test
+  public void testCreateNamespaceAndTable() throws Exception {
+    Admin admin = TEST_UTIL.getHBaseAdmin();
+    HelloHBase.createNamespaceAndTable(admin);
+
+    boolean namespaceExists
+            = HelloHBase.namespaceExists(admin, HelloHBase.MY_NAMESPACE_NAME);
+    assertEquals("#createNamespaceAndTable failed to create namespace.",
+            true, namespaceExists);
+
+    boolean tableExists = admin.tableExists(HelloHBase.MY_TABLE_NAME);
+    assertEquals("#createNamespaceAndTable failed to create table.",
+            true, tableExists);
+
+    admin.disableTable(HelloHBase.MY_TABLE_NAME);
+    admin.deleteTable(HelloHBase.MY_TABLE_NAME);
+    admin.deleteNamespace(HelloHBase.MY_NAMESPACE_NAME);
+  }
+
+  @Test
+  public void testPutRowToTable() throws IOException {
+    Admin admin = TEST_UTIL.getHBaseAdmin();
+    admin.createNamespace
+        (NamespaceDescriptor.create(HelloHBase.MY_NAMESPACE_NAME).build());
+    Table table
+            = TEST_UTIL.createTable
+                (HelloHBase.MY_TABLE_NAME, HelloHBase.MY_COLUMN_FAMILY_NAME);
+
+    HelloHBase.putRowToTable(table);
+    Result row = table.get(new Get(HelloHBase.MY_ROW_ID));
+    assertEquals("#putRowToTable failed to store row.", false, row.isEmpty());
+
+    TEST_UTIL.deleteTable(HelloHBase.MY_TABLE_NAME);
+    admin.deleteNamespace(HelloHBase.MY_NAMESPACE_NAME);
+  }
+
+  @Test
+  public void testDeleteRow() throws IOException {
+    Admin admin = TEST_UTIL.getHBaseAdmin();
+    admin.createNamespace
+        (NamespaceDescriptor.create(HelloHBase.MY_NAMESPACE_NAME).build());
+    Table table
+            = TEST_UTIL.createTable
+                (HelloHBase.MY_TABLE_NAME, HelloHBase.MY_COLUMN_FAMILY_NAME);
+
+    table.put(new Put(HelloHBase.MY_ROW_ID).
+            addColumn(HelloHBase.MY_COLUMN_FAMILY_NAME,
+                    HelloHBase.MY_FIRST_COLUMN_QUALIFIER,
+                    Bytes.toBytes("xyz")));
+    HelloHBase.deleteRow(table);
+    Result row = table.get(new Get(HelloHBase.MY_ROW_ID));
+    assertEquals("#deleteRow failed to delete row.", true, row.isEmpty());
+
+    TEST_UTIL.deleteTable(HelloHBase.MY_TABLE_NAME);
+    admin.deleteNamespace(HelloHBase.MY_NAMESPACE_NAME);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/hbase-archetypes/pom.xml
----------------------------------------------------------------------
diff --git a/hbase-archetypes/pom.xml b/hbase-archetypes/pom.xml
new file mode 100644
index 0000000..f011c2e
--- /dev/null
+++ b/hbase-archetypes/pom.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!--
+  /**
+   * Licensed to the Apache Software Foundation (ASF) under one
+   * or more contributor license agreements.  See the NOTICE file
+   * distributed with this work for additional information
+   * regarding copyright ownership.  The ASF licenses this file
+   * to you under the Apache License, Version 2.0 (the
+   * "License"); you may not use this file except in compliance
+   * with the License.  You may obtain a copy of the License at
+   *
+   *     http://www.apache.org/licenses/LICENSE-2.0
+   *
+   * Unless required by applicable law or agreed to in writing, software
+   * distributed under the License is distributed on an "AS IS" BASIS,
+   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   * See the License for the specific language governing permissions and
+   * limitations under the License.
+   */
+  -->
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>hbase</artifactId>
+    <groupId>org.apache.hbase</groupId>
+    <version>2.0.0-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <artifactId>hbase-archetypes</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Apache HBase - Archetypes</name>
+  <description>Maven archetypes for generation of fully-configured HBase client projects</description>
+
+  <modules>
+    <module>hbase-client-project</module>
+    <!-- For new archetype, add exemplar project above this comment.
+         (See hbase-archetypes/README.txt for details on adding new archetype.)  -->
+    <module>hbase-archetype-builder</module>
+  </modules>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <!-- This entry overrides the excludeFileFilter element in the findbugs
+             configuration of the hbase/pom.xml file. This override specifies that
+             the excluded-filter-file is found TWO levels up from a grandchild project. -->
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>findbugs-maven-plugin</artifactId>
+          <configuration>
+            <excludeFilterFile>${project.basedir}/../../dev-support/findbugs-exclude.xml</excludeFilterFile>
+            <findbugsXmlOutput>true</findbugsXmlOutput>
+            <xmlOutput>true</xmlOutput>
+            <effort>Max</effort>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <!-- Special configuration for findbugs just in the parent, emulating the setup in
+           hbase/pom.xml. Note that exclude-file-filter is found ONE level up from this project. -->
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <inherited>false</inherited>
+            <goals>
+              <goal>findbugs</goal>
+            </goals>
+            <configuration>
+              <excludeFilterFile>${project.basedir}/../dev-support/findbugs-exclude.xml</excludeFilterFile>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index af49452..82eff70 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,6 +70,7 @@
     <module>hbase-external-blockcache</module>
     <module>hbase-shaded</module>
     <module>hbase-spark</module>
+    <module>hbase-archetypes</module>
   </modules>
   <!--Add apache snapshots in case we want to use unreleased versions of plugins:
       e.g. surefire 2.18-SNAPSHOT-->

http://git-wip-us.apache.org/repos/asf/hbase/blob/afa63a91/src/main/asciidoc/_chapters/developer.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/_chapters/developer.adoc b/src/main/asciidoc/_chapters/developer.adoc
index d633569..ec02c43 100644
--- a/src/main/asciidoc/_chapters/developer.adoc
+++ b/src/main/asciidoc/_chapters/developer.adoc
@@ -2009,6 +2009,15 @@ However any substantive discussion (as with any off-list project-related discuss
 
 Misspellings and/or bad grammar is preferable to the disruption a JIRA comment edit causes: See the discussion at link:http://search-hadoop.com/?q=%5BReopened%5D+%28HBASE-451%29+Remove+HTableDescriptor+from+HRegionInfo&fc_project=HBase[Re:(HBASE-451) Remove HTableDescriptor from HRegionInfo]
 
+[[hbase.archetypes.development]]
+=== Development of HBase-related Maven archetypes
+
+The development of HBase-related Maven archetypes was begun with
+link:https://issues.apache.org/jira/browse/HBASE-14876[HBASE-14876].
+For an overview of the hbase-archetypes infrastructure and instructions
+for developing new HBase-related Maven archetypes, please see
+`hbase/hbase-archetypes/README.md`.
+
 ifdef::backend-docbook[]
 [index]
 == Index