You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by gi...@apache.org on 2025/12/12 14:57:21 UTC

(hbase-site) branch asf-site updated: Published site at 04b293ccf0c8359873c1cf42082b8d0b8fb06e61.

This is an automated email from the ASF dual-hosted git repository.

git-site-role pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hbase-site.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new eefb6d3dce0 Published site at 04b293ccf0c8359873c1cf42082b8d0b8fb06e61.
eefb6d3dce0 is described below

commit eefb6d3dce086b6706cc2dae05936dc6fe9e302c
Author: jenkins <bu...@apache.org>
AuthorDate: Fri Dec 12 14:56:31 2025 +0000

    Published site at 04b293ccf0c8359873c1cf42082b8d0b8fb06e61.
---
 apache_hbase_reference_guide.pdf                   |     4 +-
 apidocs/allclasses-index.html                      |    11 +
 apidocs/index-all.html                             |    83 +
 apidocs/member-search-index.js                     |     2 +-
 .../apache/hadoop/hbase/class-use/Coprocessor.html |    15 +-
 .../hbase/class-use/CoprocessorEnvironment.html    |    13 +-
 .../hadoop/hbase/class-use/HRegionLocation.html    |    49 +-
 .../apache/hadoop/hbase/class-use/ServerName.html  |    60 +
 .../class-use/ClientMetaCoprocessor.html           |   101 +
 .../ClientMetaCoprocessorEnvironment.html          |   153 +
 .../class-use/ClientMetaCoprocessorHost.html       |    87 +
 .../coprocessor/class-use/ClientMetaObserver.html  |    89 +
 .../coprocessor/class-use/CoprocessorHost.html     |    28 +-
 .../coprocessor/class-use/ObserverContext.html     |   909 +-
 .../hadoop/hbase/coprocessor/package-summary.html  |    11 +
 .../hadoop/hbase/coprocessor/package-tree.html     |     9 +-
 .../hadoop/hbase/coprocessor/package-use.html      |    26 +-
 apidocs/org/apache/hadoop/hbase/package-use.html   |    22 +-
 apidocs/overview-tree.html                         |     4 +
 .../apache/hadoop/hbase/HBaseRpcServicesBase.html  |   764 +-
 .../hbase/coprocessor/ClientMetaCoprocessor.html   |   110 +
 .../ClientMetaCoprocessorEnvironment.html          |   107 +
 .../coprocessor/ClientMetaCoprocessorHost.html     |   290 +
 .../hbase/coprocessor/ClientMetaObserver.html      |   231 +
 .../CoprocessorHost.ObserverGetter.html            |  1246 +-
 ...oprocessorHost.ObserverOperationWithResult.html |  1246 +-
 ...ocessorHost.ObserverOperationWithoutResult.html |  1246 +-
 .../hadoop/hbase/coprocessor/CoprocessorHost.html  |  1246 +-
 apidocs/type-search-index.js                       |     2 +-
 book.html                                          |     2 +-
 checkstyle-aggregate.html                          |    10 +-
 dependency-convergence.html                        |     4 +-
 dependency-info.html                               |     4 +-
 dependency-management.html                         |     4 +-
 devapidocs/allclasses-index.html                   | 12101 ++++++++++---------
 devapidocs/constant-values.html                    |    79 +-
 devapidocs/index-all.html                          |    93 +
 devapidocs/member-search-index.js                  |     2 +-
 .../org/apache/hadoop/hbase/Coprocessor.html       |     2 +-
 .../hadoop/hbase/CoprocessorEnvironment.html       |     4 +-
 .../apache/hadoop/hbase/HBaseRpcServicesBase.html  |   256 +-
 .../apache/hadoop/hbase/class-use/Coprocessor.html |    15 +-
 .../hbase/class-use/CoprocessorEnvironment.html    |    16 +-
 .../hadoop/hbase/class-use/HRegionLocation.html    |    57 +-
 .../apache/hadoop/hbase/class-use/ServerName.html  |    60 +
 .../hadoop/hbase/coprocessor/BaseEnvironment.html  |     2 +-
 .../hbase/coprocessor/ClientMetaCoprocessor.html   |   157 +
 .../ClientMetaCoprocessorEnvironment.html          |   108 +
 ...tMetaCoprocessorHost.ClientMetaEnvironment.html |   164 +
 .../coprocessor/ClientMetaCoprocessorHost.html     |   408 +
 .../hbase/coprocessor/ClientMetaObserver.html      |   359 +
 ...rocessorHost.EnvironmentPriorityComparator.html |     6 +-
 .../CoprocessorHost.ObserverGetter.html            |     2 +-
 .../CoprocessorHost.ObserverOperation.html         |    16 +-
 ...oprocessorHost.ObserverOperationWithResult.html |    18 +-
 ...ocessorHost.ObserverOperationWithoutResult.html |    12 +-
 .../hadoop/hbase/coprocessor/CoprocessorHost.html  |   171 +-
 .../coprocessor/class-use/BaseEnvironment.html     |    28 +-
 .../class-use/ClientMetaCoprocessor.html           |   122 +
 .../ClientMetaCoprocessorEnvironment.html          |   162 +
 ...tMetaCoprocessorHost.ClientMetaEnvironment.html |    62 +
 .../class-use/ClientMetaCoprocessorHost.html       |    96 +
 .../coprocessor/class-use/ClientMetaObserver.html  |    98 +
 .../class-use/CoprocessorHost.ObserverGetter.html  |     7 +-
 .../coprocessor/class-use/CoprocessorHost.html     |    28 +-
 .../coprocessor/class-use/ObserverContext.html     |   915 +-
 .../hadoop/hbase/coprocessor/package-summary.html  |   133 +-
 .../hadoop/hbase/coprocessor/package-tree.html     |    15 +-
 .../hadoop/hbase/coprocessor/package-use.html      |   104 +-
 .../hadoop/hbase/ipc/RpcCoprocessorHost.html       |     2 +-
 .../hadoop/hbase/master/MasterCoprocessorHost.html |     2 +-
 .../hadoop/hbase/master/MasterRpcServices.html     |     2 +-
 .../org/apache/hadoop/hbase/package-use.html       |    22 +-
 .../hadoop/hbase/regionserver/RSRpcServices.html   |     2 +-
 .../hbase/regionserver/RegionCoprocessorHost.html  |     2 +-
 .../regionserver/RegionServerCoprocessorHost.html  |     2 +-
 .../hbase/regionserver/wal/WALCoprocessorHost.html |     2 +-
 devapidocs/overview-tree.html                      |     5 +
 .../apache/hadoop/hbase/HBaseRpcServicesBase.html  |   764 +-
 .../hbase/coprocessor/ClientMetaCoprocessor.html   |   110 +
 .../ClientMetaCoprocessorEnvironment.html          |   107 +
 ...tMetaCoprocessorHost.ClientMetaEnvironment.html |   290 +
 .../coprocessor/ClientMetaCoprocessorHost.html     |   290 +
 .../hbase/coprocessor/ClientMetaObserver.html      |   231 +
 ...rocessorHost.EnvironmentPriorityComparator.html |  1246 +-
 .../CoprocessorHost.ObserverGetter.html            |  1246 +-
 .../CoprocessorHost.ObserverOperation.html         |  1246 +-
 ...oprocessorHost.ObserverOperationWithResult.html |  1246 +-
 ...ocessorHost.ObserverOperationWithoutResult.html |  1246 +-
 .../hadoop/hbase/coprocessor/CoprocessorHost.html  |  1246 +-
 devapidocs/type-search-index.js                    |     2 +-
 hbase-website/dependency-convergence.html          |     4 +-
 hbase-website/dependency-info.html                 |     4 +-
 hbase-website/dependency-management.html           |     4 +-
 hbase-website/index.html                           |     4 +-
 hbase-website/issue-management.html                |     4 +-
 hbase-website/licenses.html                        |     4 +-
 hbase-website/mailing-lists.html                   |     4 +-
 hbase-website/plugin-management.html               |     4 +-
 hbase-website/plugins.html                         |     4 +-
 hbase-website/project-info.html                    |     4 +-
 hbase-website/scm.html                             |     4 +-
 hbase-website/summary.html                         |     4 +-
 hbase-website/team.html                            |     4 +-
 issue-management.html                              |     4 +-
 licenses.html                                      |     4 +-
 mailing-lists.html                                 |     4 +-
 plugin-management.html                             |     4 +-
 plugins.html                                       |     4 +-
 project-info.html                                  |     4 +-
 project-reports.html                               |     4 +-
 scm.html                                           |     4 +-
 summary.html                                       |     4 +-
 team.html                                          |     4 +-
 testapidocs/allclasses-index.html                  |     7 +
 testapidocs/index-all.html                         |    33 +
 testapidocs/member-search-index.js                 |     2 +-
 .../hadoop/hbase/class-use/HBaseClassTestRule.html |    67 +-
 .../TestClientMetaCoprocessor.TestCoprocessor.html |    62 +
 .../class-use/TestClientMetaCoprocessor.html       |    62 +
 .../hadoop/hbase/coprocessor/package-summary.html  |     7 +
 .../hadoop/hbase/coprocessor/package-tree.html     |     2 +
 testapidocs/overview-tree.html                     |     2 +
 .../TestClientMetaCoprocessor.TestCoprocessor.html |   286 +
 .../coprocessor/TestClientMetaCoprocessor.html     |   286 +
 testapidocs/type-search-index.js                   |     2 +-
 testdevapidocs/allclasses-index.html               |     7 +
 testdevapidocs/index-all.html                      |    45 +
 testdevapidocs/member-search-index.js              |     2 +-
 ...lientOperationTimeout.DelayedRSRpcServices.html |     2 +-
 ...tyRpcControllerFactory.PriorityRpcServices.html |     2 +-
 .../hadoop/hbase/class-use/HBaseClassTestRule.html |    67 +-
 .../hadoop/hbase/class-use/HBaseTestingUtil.html   |    41 +-
 ...cThrottling.ThrottlingRSRpcServicesForTest.html |     2 +-
 ...annerTimeouts.RSRpcServicesWithScanTimeout.html |     2 +-
 .../client/TestMetaCache.FakeRSRpcServices.html    |     2 +-
 .../TestClientMetaCoprocessor.TestCoprocessor.html |    99 +-
 .../coprocessor/TestClientMetaCoprocessor.html     |   342 +
 ...TestCoprocessorHost.CoprocessorHostForTest.html |     2 +-
 .../TestClientMetaCoprocessor.TestCoprocessor.html |    87 +
 .../class-use/TestClientMetaCoprocessor.html       |    62 +
 .../hadoop/hbase/coprocessor/package-summary.html  |     7 +
 .../hadoop/hbase/coprocessor/package-tree.html     |     2 +
 .../hadoop/hbase/coprocessor/package-use.html      |    10 +-
 ...itializedRegionServer.RSRpcServicesForTest.html |     2 +-
 ...UpUnexpectedProcedure.RSRpcServicesForTest.html |     2 +-
 ...geTransactionOnCluster.MyMasterRpcServices.html |     2 +-
 ...aReplicationError.ErrorReplayRSRpcServices.html |     2 +-
 .../TestRegionServerScan.MyRSRpcServices.html      |     2 +-
 ...nnerHeartbeatMessages.HeartbeatRPCServices.html |     2 +-
 ...eCount.ScannerTrackingRSRpcServicesForTest.html |     2 +-
 ...PCScanMetrics.RSRPCServicesWithScanMetrics.html |     2 +-
 ...meoutHandling.RSRpcServicesWithScanTimeout.html |     2 +-
 ...itTransactionOnCluster.MyMasterRpcServices.html |     2 +-
 ...ionForFlushMarker.ErrorReplayRSRpcServices.html |     2 +-
 ...FlushConcurrently.ErrorReplayRSRpcServices.html |     2 +-
 testdevapidocs/overview-tree.html                  |     2 +
 .../TestClientMetaCoprocessor.TestCoprocessor.html |   286 +
 .../coprocessor/TestClientMetaCoprocessor.html     |   286 +
 testdevapidocs/type-search-index.js                |     2 +-
 160 files changed, 21207 insertions(+), 14463 deletions(-)

diff --git a/apache_hbase_reference_guide.pdf b/apache_hbase_reference_guide.pdf
index 0d5c3a02767..047dd1ff389 100644
--- a/apache_hbase_reference_guide.pdf
+++ b/apache_hbase_reference_guide.pdf
@@ -5,8 +5,8 @@
 /Author (Apache HBase Team)
 /Creator (Asciidoctor PDF 2.0.6, based on Prawn 2.4.0)
 /Producer (Apache HBase Team)
-/ModDate (D:20251210143146+00'00')
-/CreationDate (D:20251210144823+00'00')
+/ModDate (D:20251212143142+00'00')
+/CreationDate (D:20251212145033+00'00')
 >>
 endobj
 2 0 obj
diff --git a/apidocs/allclasses-index.html b/apidocs/allclasses-index.html
index 5a9f633a00e..8abceaa22a9 100644
--- a/apidocs/allclasses-index.html
+++ b/apidocs/allclasses-index.html
@@ -1228,6 +1228,17 @@ loadScripts(document, 'script');</script>
 <div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">A helper class used to access the package private field in o.a.h.h.client package.</div>
 </div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor</div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab1">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment</div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">&nbsp;</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab1">org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
+<div class="block">Defines coprocessor hooks for interacting operations for ClientMetaService which is responsible
+ for ZooKeeperless HBase service discovery.</div>
+</div>
 <div class="col-first even-row-color all-classes-table all-classes-table-tab2">org.apache.hadoop.hbase.ClientMetaTableAccessor</div>
 <div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">The (asynchronous) meta table accessor used at client side.</div>
diff --git a/apidocs/index-all.html b/apidocs/index-all.html
index 3a68560def1..5ec7e60b072 100644
--- a/apidocs/index-all.html
+++ b/apidocs/index-all.html
@@ -5984,6 +5984,8 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Check whether anything need to be done based on the current active set size.</div>
 </dd>
+<dt>checkAndGetInstance(Class&lt;?&gt;) - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
 <dt>checkAndGetInstance(Class&lt;?&gt;) - Method in class org.apache.hadoop.hbase.coprocessor.CoprocessorHost</dt>
 <dd>
 <div class="block">Called when a new Coprocessor class needs to be loaded.</div>
@@ -7093,6 +7095,8 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>CLIENT_COUNT - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
 <dd>&nbsp;</dd>
+<dt>CLIENT_META_COPROCESSOR_CONF_KEY - Static variable in class org.apache.hadoop.hbase.coprocessor.CoprocessorHost</dt>
+<dd>&nbsp;</dd>
 <dt>CLIENT_NONCES_ENABLED_KEY - Static variable in interface org.apache.hadoop.hbase.client.NonceGenerator</dt>
 <dd>&nbsp;</dd>
 <dt>CLIENT_PORT_STR - Static variable in class org.apache.hadoop.hbase.HConstants</dt>
@@ -7150,6 +7154,19 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>ClientInternalHelper() - Constructor for class org.apache.hadoop.hbase.client.ClientInternalHelper</dt>
 <dd>&nbsp;</dd>
+<dt>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor - Interface in <a href="org/apache/hadoop/hbase/coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a></dt>
+<dd>&nbsp;</dd>
+<dt>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment - Interface in <a href="org/apache/hadoop/hbase/coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a></dt>
+<dd>&nbsp;</dd>
+<dt>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost - Class in <a href="org/apache/hadoop/hbase/coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a></dt>
+<dd>&nbsp;</dd>
+<dt>ClientMetaCoprocessorHost(Configuration) - Constructor for class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>org.apache.hadoop.hbase.coprocessor.ClientMetaObserver - Interface in <a href="org/apache/hadoop/hbase/coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a></dt>
+<dd>
+<div class="block">Defines coprocessor hooks for interacting operations for ClientMetaService which is responsible
+ for ZooKeeperless HBase service discovery.</div>
+</dd>
 <dt>org.apache.hadoop.hbase.ClientMetaTableAccessor - Class in <a href="org/apache/hadoop/hbase/package-summary.html">org.apache.hadoop.hbase</a></dt>
 <dd>
 <div class="block">The (asynchronous) meta table accessor used at client side.</div>
@@ -11242,6 +11259,8 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Called when a new Coprocessor class is loaded</div>
 </dd>
+<dt>createEnvironment(ClientMetaCoprocessor, int, int, Configuration) - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
 <dt>createEnvironment(MasterCoprocessor, int, int, Configuration) - Method in class org.apache.hadoop.hbase.master.MasterCoprocessorHost</dt>
 <dd>&nbsp;</dd>
 <dt>createEnvironment(RegionCoprocessor, int, int, Configuration) - Method in class org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost</dt>
@@ -22092,6 +22111,10 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>getClientIdAuditPrefix() - Method in interface org.apache.hadoop.hbase.master.MasterServices</dt>
 <dd>&nbsp;</dd>
+<dt>getClientMetaCoprocessorHost() - Method in class org.apache.hadoop.hbase.HBaseRpcServicesBase</dt>
+<dd>&nbsp;</dd>
+<dt>getClientMetaObserver() - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor</dt>
+<dd>&nbsp;</dd>
 <dt>getClientMetrics() - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource</dt>
 <dd>
 <div class="block">Metrics collected at client level for a user(needed for reporting through clusterStatus and
@@ -53340,6 +53363,24 @@ service.</div>
 </dd>
 <dt>postGet(Get, List&lt;Cell&gt;) - Method in class org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost</dt>
 <dd>&nbsp;</dd>
+<dt>postGetActiveMaster(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;, ServerName) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called after we got the active master.</div>
+</dd>
+<dt>postGetActiveMaster(ServerName) - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>postGetBootstrapNodes(List&lt;ServerName&gt;) - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>postGetBootstrapNodes(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;, List&lt;ServerName&gt;) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called after we got bootstrap nodes.</div>
+</dd>
+<dt>postGetClusterId(String) - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>postGetClusterId(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;, String) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called after we got the cluster ID.</div>
+</dd>
 <dt>postGetClusterMetrics(ClusterMetrics) - Method in class org.apache.hadoop.hbase.master.MasterCoprocessorHost</dt>
 <dd>&nbsp;</dd>
 <dt>postGetClusterMetrics(ObserverContext&lt;MasterCoprocessorEnvironment&gt;, ClusterMetrics) - Method in interface org.apache.hadoop.hbase.coprocessor.MasterObserver</dt>
@@ -53358,6 +53399,18 @@ service.</div>
 <dd>
 <div class="block">Called after a getLocks request has been processed.</div>
 </dd>
+<dt>postGetMasters(Map&lt;ServerName, Boolean&gt;) - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>postGetMasters(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;, Map&lt;ServerName, Boolean&gt;) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called after we got the master servers.</div>
+</dd>
+<dt>postGetMetaLocations(List&lt;HRegionLocation&gt;) - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>postGetMetaLocations(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;, List&lt;HRegionLocation&gt;) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called after we got the meta region locations.</div>
+</dd>
 <dt>postGetNamespaceDescriptor(ObserverContext&lt;MasterCoprocessorEnvironment&gt;, NamespaceDescriptor) - Method in interface org.apache.hadoop.hbase.coprocessor.MasterObserver</dt>
 <dd>
 <div class="block">Called after a getNamespaceDescriptor request has been processed.</div>
@@ -54549,6 +54602,24 @@ service.</div>
 <dd>
 <div class="block">Supports Coprocessor 'bypass'.</div>
 </dd>
+<dt>preGetActiveMaster() - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>preGetActiveMaster(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called before getting the active master.</div>
+</dd>
+<dt>preGetBootstrapNodes() - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>preGetBootstrapNodes(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called before getting bootstrap nodes.</div>
+</dd>
+<dt>preGetClusterId() - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>preGetClusterId(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called before getting the cluster ID.</div>
+</dd>
 <dt>preGetClusterMetrics() - Method in class org.apache.hadoop.hbase.master.MasterCoprocessorHost</dt>
 <dd>&nbsp;</dd>
 <dt>preGetClusterMetrics(ObserverContext&lt;MasterCoprocessorEnvironment&gt;) - Method in interface org.apache.hadoop.hbase.coprocessor.MasterObserver</dt>
@@ -54567,6 +54638,18 @@ service.</div>
 <dd>
 <div class="block">Called before a getLocks request has been processed.</div>
 </dd>
+<dt>preGetMasters() - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>preGetMasters(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called before getting the master servers.</div>
+</dd>
+<dt>preGetMetaLocations() - Method in class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</dt>
+<dd>&nbsp;</dd>
+<dt>preGetMetaLocations(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt;) - Method in interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</dt>
+<dd>
+<div class="block">Called before getting the meta region locations.</div>
+</dd>
 <dt>preGetNamespaceDescriptor(String) - Method in class org.apache.hadoop.hbase.master.MasterCoprocessorHost</dt>
 <dd>&nbsp;</dd>
 <dt>preGetNamespaceDescriptor(ObserverContext&lt;MasterCoprocessorEnvironment&gt;, String) - Method in interface org.apache.hadoop.hbase.coprocessor.MasterObserver</dt>
diff --git a/apidocs/member-search-index.js b/apidocs/member-search-index.js
index bd4b5989a37..9839c30a7e1 100644
--- a/apidocs/member-search-index.js
+++ b/apidocs/member-search-index.js
@@ -1 +1 @@
-memberSearchIndex = [{"p":"org.apache.hadoop.hbase.filter","c":"ParseConstants","l":"A"},{"p":"org.apache.hadoop.hbase.master","c":"RegionState.State","l":"ABNORMALLY_CLOSED"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"CoprocessorHost","l":"ABORT_ON_ERROR_KEY"},{"p":"org.apache.hadoop.hdfs","c":"DummyDFSOutputStream","l":"abort()"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abort(String)","u":"abort(java.lang.String)"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abo [...]
\ No newline at end of file
+memberSearchIndex = [{"p":"org.apache.hadoop.hbase.filter","c":"ParseConstants","l":"A"},{"p":"org.apache.hadoop.hbase.master","c":"RegionState.State","l":"ABNORMALLY_CLOSED"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"CoprocessorHost","l":"ABORT_ON_ERROR_KEY"},{"p":"org.apache.hadoop.hdfs","c":"DummyDFSOutputStream","l":"abort()"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abort(String)","u":"abort(java.lang.String)"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abo [...]
\ No newline at end of file
diff --git a/apidocs/org/apache/hadoop/hbase/class-use/Coprocessor.html b/apidocs/org/apache/hadoop/hbase/class-use/Coprocessor.html
index 6fae2fdef1e..ea4ad876433 100644
--- a/apidocs/org/apache/hadoop/hbase/class-use/Coprocessor.html
+++ b/apidocs/org/apache/hadoop/hbase/class-use/Coprocessor.html
@@ -146,20 +146,23 @@ loadScripts(document, 'script');</script>
 <div class="table-header col-second">Interface</div>
 <div class="table-header col-last">Description</div>
 <div class="col-first even-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.MasterCoprocessor</code></div>
+<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
 <div class="col-first odd-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.RegionCoprocessor</code></div>
+<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.MasterCoprocessor</code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
 <div class="col-first even-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessor</code></div>
+<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.RegionCoprocessor</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
 <div class="col-first odd-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.RpcCoprocessor</code></div>
+<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessor</code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
 <div class="col-first even-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.WALCoprocessor</code></div>
-<div class="col-last even-row-color">
+<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.RpcCoprocessor</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>interface&nbsp;</code></div>
+<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.WALCoprocessor</code></div>
+<div class="col-last odd-row-color">
 <div class="block">WALCoprocessor don't support loading services using <code>getServices()</code>.</div>
 </div>
 </div>
diff --git a/apidocs/org/apache/hadoop/hbase/class-use/CoprocessorEnvironment.html b/apidocs/org/apache/hadoop/hbase/class-use/CoprocessorEnvironment.html
index ad1e52ab248..87b2f2303f0 100644
--- a/apidocs/org/apache/hadoop/hbase/class-use/CoprocessorEnvironment.html
+++ b/apidocs/org/apache/hadoop/hbase/class-use/CoprocessorEnvironment.html
@@ -129,20 +129,23 @@ loadScripts(document, 'script');</script>
 <div class="table-header col-second">Interface</div>
 <div class="table-header col-last">Description</div>
 <div class="col-first even-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment</code></div>
+<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
 <div class="col-first odd-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment</code></div>
+<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment</code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
 <div class="col-first even-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment</code></div>
+<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
 <div class="col-first odd-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.RpcCoprocessorEnvironment</code></div>
+<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment</code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
 <div class="col-first even-row-color"><code>interface&nbsp;</code></div>
-<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.WALCoprocessorEnvironment</code></div>
+<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.RpcCoprocessorEnvironment</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>interface&nbsp;</code></div>
+<div class="col-second odd-row-color"><code>org.apache.hadoop.hbase.coprocessor.WALCoprocessorEnvironment</code></div>
+<div class="col-last odd-row-color">&nbsp;</div>
 </div>
 <div class="caption"><span>Classes in <a href="../coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a> that implement org.apache.hadoop.hbase.CoprocessorEnvironment in  in </span></div>
 <div class="summary-table three-column-summary">
diff --git a/apidocs/org/apache/hadoop/hbase/class-use/HRegionLocation.html b/apidocs/org/apache/hadoop/hbase/class-use/HRegionLocation.html
index 86eeb887b92..5c184f8dbf9 100644
--- a/apidocs/org/apache/hadoop/hbase/class-use/HRegionLocation.html
+++ b/apidocs/org/apache/hadoop/hbase/class-use/HRegionLocation.html
@@ -61,14 +61,18 @@ loadScripts(document, 'script');</script>
 <div class="col-last odd-row-color">
 <div class="block">Provides HBase Client</div>
 </div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.master">org.apache.hadoop.hbase.master</a></div>
-<div class="col-last even-row-color">&nbsp;</div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.regionserver">org.apache.hadoop.hbase.regionserver</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.coprocessor">org.apache.hadoop.hbase.coprocessor</a></div>
+<div class="col-last even-row-color">
+<div class="block">Table of Contents</div>
+</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.master">org.apache.hadoop.hbase.master</a></div>
 <div class="col-last odd-row-color">&nbsp;</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.shaded.protobuf">org.apache.hadoop.hbase.shaded.protobuf</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.regionserver">org.apache.hadoop.hbase.regionserver</a></div>
 <div class="col-last even-row-color">&nbsp;</div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.snapshot">org.apache.hadoop.hbase.snapshot</a></div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.shaded.protobuf">org.apache.hadoop.hbase.shaded.protobuf</a></div>
 <div class="col-last odd-row-color">&nbsp;</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.snapshot">org.apache.hadoop.hbase.snapshot</a></div>
+<div class="col-last even-row-color">&nbsp;</div>
 </div>
 <section class="class-uses">
 <ul class="block-list">
@@ -312,6 +316,41 @@ loadScripts(document, 'script');</script>
 </section>
 </li>
 <li>
+<section class="detail" id="org.apache.hadoop.hbase.coprocessor">
+<h2>Uses of org.apache.hadoop.hbase.HRegionLocation in <a href="../coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a></h2>
+<div class="caption"><span>Methods in <a href="../coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a> that return types with arguments of type org.apache.hadoop.hbase.HRegionLocation in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>postGetMetaLocations<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;&nbsp;metaLocations)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetMetaLocations<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;&nbsp;metaLocations)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got the meta region locations.</div>
+</div>
+</div>
+<div class="caption"><span>Method parameters in <a href="../coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a> with type arguments of type org.apache.hadoop.hbase.HRegionLocation in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>postGetMetaLocations<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;&nbsp;metaLocations)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetMetaLocations<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;&nbsp;metaLocations)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got the meta region locations.</div>
+</div>
+</div>
+</section>
+</li>
+<li>
 <section class="detail" id="org.apache.hadoop.hbase.master">
 <h2>Uses of org.apache.hadoop.hbase.HRegionLocation in <a href="../master/package-summary.html">org.apache.hadoop.hbase.master</a></h2>
 <div class="caption"><span>Methods in <a href="../master/package-summary.html">org.apache.hadoop.hbase.master</a> that return types with arguments of type org.apache.hadoop.hbase.HRegionLocation in  in </span></div>
diff --git a/apidocs/org/apache/hadoop/hbase/class-use/ServerName.html b/apidocs/org/apache/hadoop/hbase/class-use/ServerName.html
index 3c804ad46ed..4cfa3f3aece 100644
--- a/apidocs/org/apache/hadoop/hbase/class-use/ServerName.html
+++ b/apidocs/org/apache/hadoop/hbase/class-use/ServerName.html
@@ -1390,12 +1390,54 @@ R&gt;&nbsp;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base
 <div class="col-last even-row-color">
 <div class="block">Returns Hosting Server's ServerName</div>
 </div>
+<div class="col-first odd-row-color"><code>org.apache.hadoop.hbase.ServerName</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>postGetActiveMaster<wbr>(org.apache.hadoop.hbase.ServerName&nbsp;serverName)</code></div>
+<div class="col-last odd-row-color">&nbsp;</div>
+<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.ServerName</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetActiveMaster<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.ServerName&nbsp;serverName)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called after we got the active master.</div>
+</div>
+</div>
+<div class="caption"><span>Methods in <a href="../coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a> that return types with arguments of type org.apache.hadoop.hbase.ServerName in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>postGetBootstrapNodes<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;&nbsp;bootstrapNodes)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetBootstrapNodes<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;&nbsp;bootstrapNodes)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got bootstrap nodes.</div>
+</div>
+<div class="col-first even-row-color"><code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>postGetMasters<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boole [...]
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetMasters<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;&nbsp;serverNames)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got the master servers.</div>
+</div>
 </div>
 <div class="caption"><span>Methods in <a href="../coprocessor/package-summary.html">org.apache.hadoop.hbase.coprocessor</a> with parameters of type org.apache.hadoop.hbase.ServerName in  in </span></div>
 <div class="summary-table three-column-summary">
 <div class="table-header col-first">Modifier and Type</div>
 <div class="table-header col-second">Method</div>
 <div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>org.apache.hadoop.hbase.ServerName</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>postGetActiveMaster<wbr>(org.apache.hadoop.hbase.ServerName&nbsp;serverName)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.ServerName</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetActiveMaster<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.ServerName&nbsp;serverName)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got the active master.</div>
+</div>
 <div class="col-first even-row-color"><code>default void</code></div>
 <div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postMove<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.RegionInfo&nbsp;region,
@@ -1446,6 +1488,24 @@ R&gt;&nbsp;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base
 <div class="col-last odd-row-color">
 <div class="block">Called after decommission region servers.</div>
 </div>
+<div class="col-first even-row-color"><code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>postGetBootstrapNodes<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;&nbsp;bootstrapNodes)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetBootstrapNodes<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;&nbsp;bootstrapNodes)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got bootstrap nodes.</div>
+</div>
+<div class="col-first even-row-color"><code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>postGetMasters<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boole [...]
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetMasters<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;&nbsp;serverNames)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got the master servers.</div>
+</div>
 <div class="col-first even-row-color"><code>default void</code></div>
 <div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preDecommissionRegionServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;&nbsp;servers,
diff --git a/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaCoprocessor.html b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaCoprocessor.html
new file mode 100644
index 00000000000..0c048d9a461
--- /dev/null
+++ b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaCoprocessor.html
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+<!-- Generated by javadoc (17) -->
+<title>Uses of Interface org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="description" content="use: package: org.apache.hadoop.hbase.coprocessor, interface: ClientMetaCoprocessor">
+<meta name="generator" content="javadoc/ClassUseWriter">
+<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
+<link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
+<link rel="stylesheet" type="text/css" href="../../../../../../jquery-ui.overrides.css" title="Style">
+<script type="text/javascript" src="../../../../../../script.js"></script>
+<script type="text/javascript" src="../../../../../../script-dir/jquery-3.6.1.min.js"></script>
+<script type="text/javascript" src="../../../../../../script-dir/jquery-ui.min.js"></script>
+</head>
+<body class="class-use-page">
+<script type="text/javascript">var pathtoroot = "../../../../../../";
+loadScripts(document, 'script');</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<div class="flex-box">
+<header role="banner" class="flex-header">
+<nav role="navigation">
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="top-nav" id="navbar-top">
+<div class="skip-nav"><a href="#skip-navbar-top" title="Skip navigation links">Skip navigation links</a></div>
+<ul id="navbar-top-firstrow" class="nav-list" title="Navigation">
+<li><a href="../../../../../../index.html">Overview</a></li>
+<li><a href="../package-summary.html">Package</a></li>
+<li>Class</li>
+<li class="nav-bar-cell1-rev">Use</li>
+<li><a href="../package-tree.html">Tree</a></li>
+<li><a href="../../../../../../deprecated-list.html">Deprecated</a></li>
+<li><a href="../../../../../../index-all.html">Index</a></li>
+<li><a href="../../../../../../help-doc.html#use">Help</a></li>
+</ul>
+</div>
+<div class="sub-nav">
+<div class="nav-list-search"><label for="search-input">SEARCH:</label>
+<input type="text" id="search-input" value="search" disabled="disabled">
+<input type="reset" id="reset-button" value="reset" disabled="disabled">
+</div>
+</div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<span class="skip-nav" id="skip-navbar-top"></span></nav>
+</header>
+<div class="flex-content">
+<main role="main">
+<div class="header">
+<h1 title="Uses of Interface org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor" class="title">Uses of Interface<br>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor</h1>
+</div>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor</span></div>
+<div class="summary-table two-column-summary">
+<div class="table-header col-first">Package</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.coprocessor">org.apache.hadoop.hbase.coprocessor</a></div>
+<div class="col-last even-row-color">
+<div class="block">Table of Contents</div>
+</div>
+</div>
+<section class="class-uses">
+<ul class="block-list">
+<li>
+<section class="detail" id="org.apache.hadoop.hbase.coprocessor">
+<h2>Uses of org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a></h2>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a> that return org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>checkAndGetInstance<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Class.html" title="class or interface in java.lang" class="external-link">Class</a>&lt;?&gt;&nbsp;implClass)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a> with parameters of type org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>createEnvironment<wbr>(org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor&nbsp;instance,
+ int&nbsp;priority,
+ int&nbsp;sequence,
+ org.apache.hadoop.conf.Configuration&nbsp;conf)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
+</section>
+</li>
+</ul>
+</section>
+</main>
+<footer role="contentinfo">
+<hr>
+<p class="legal-copy"><small>Copyright &#169; 2007&#x2013;2020 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
+</footer>
+</div>
+</div>
+</body>
+</html>
diff --git a/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaCoprocessorEnvironment.html b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaCoprocessorEnvironment.html
new file mode 100644
index 00000000000..408b84e51c3
--- /dev/null
+++ b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaCoprocessorEnvironment.html
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+<!-- Generated by javadoc (17) -->
+<title>Uses of Interface org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="description" content="use: package: org.apache.hadoop.hbase.coprocessor, interface: ClientMetaCoprocessorEnvironment">
+<meta name="generator" content="javadoc/ClassUseWriter">
+<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
+<link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
+<link rel="stylesheet" type="text/css" href="../../../../../../jquery-ui.overrides.css" title="Style">
+<script type="text/javascript" src="../../../../../../script.js"></script>
+<script type="text/javascript" src="../../../../../../script-dir/jquery-3.6.1.min.js"></script>
+<script type="text/javascript" src="../../../../../../script-dir/jquery-ui.min.js"></script>
+</head>
+<body class="class-use-page">
+<script type="text/javascript">var pathtoroot = "../../../../../../";
+loadScripts(document, 'script');</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<div class="flex-box">
+<header role="banner" class="flex-header">
+<nav role="navigation">
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="top-nav" id="navbar-top">
+<div class="skip-nav"><a href="#skip-navbar-top" title="Skip navigation links">Skip navigation links</a></div>
+<ul id="navbar-top-firstrow" class="nav-list" title="Navigation">
+<li><a href="../../../../../../index.html">Overview</a></li>
+<li><a href="../package-summary.html">Package</a></li>
+<li>Class</li>
+<li class="nav-bar-cell1-rev">Use</li>
+<li><a href="../package-tree.html">Tree</a></li>
+<li><a href="../../../../../../deprecated-list.html">Deprecated</a></li>
+<li><a href="../../../../../../index-all.html">Index</a></li>
+<li><a href="../../../../../../help-doc.html#use">Help</a></li>
+</ul>
+</div>
+<div class="sub-nav">
+<div class="nav-list-search"><label for="search-input">SEARCH:</label>
+<input type="text" id="search-input" value="search" disabled="disabled">
+<input type="reset" id="reset-button" value="reset" disabled="disabled">
+</div>
+</div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<span class="skip-nav" id="skip-navbar-top"></span></nav>
+</header>
+<div class="flex-content">
+<main role="main">
+<div class="header">
+<h1 title="Uses of Interface org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment" class="title">Uses of Interface<br>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment</h1>
+</div>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment</span></div>
+<div class="summary-table two-column-summary">
+<div class="table-header col-first">Package</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.coprocessor">org.apache.hadoop.hbase.coprocessor</a></div>
+<div class="col-last even-row-color">
+<div class="block">Table of Contents</div>
+</div>
+</div>
+<section class="class-uses">
+<ul class="block-list">
+<li>
+<section class="detail" id="org.apache.hadoop.hbase.coprocessor">
+<h2>Uses of org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a></h2>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a> that return org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessorHost.</span><code>createEnvironment<wbr>(org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor&nbsp;instance,
+ int&nbsp;priority,
+ int&nbsp;sequence,
+ org.apache.hadoop.conf.Configuration&nbsp;conf)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
+<div class="caption"><span>Method parameters in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a> with type arguments of type org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.ServerName</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetActiveMaster<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.ServerName&nbsp;serverName)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called after we got the active master.</div>
+</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetBootstrapNodes<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;&nbsp;bootstrapNodes)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got bootstrap nodes.</div>
+</div>
+<div class="col-first even-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetClusterId<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;clusterId)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called after we got the cluster ID.</div>
+</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetMasters<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;&nbsp;serverNames)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got the master servers.</div>
+</div>
+<div class="col-first even-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetMetaLocations<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;&nbsp;metaLocations)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called after we got the meta region locations.</div>
+</div>
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetActiveMaster<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called before getting the active master.</div>
+</div>
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetBootstrapNodes<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called before getting bootstrap nodes.</div>
+</div>
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetClusterId<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called before getting the cluster ID.</div>
+</div>
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetMasters<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called before getting the master servers.</div>
+</div>
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetMetaLocations<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called before getting the meta region locations.</div>
+</div>
+</div>
+</section>
+</li>
+</ul>
+</section>
+</main>
+<footer role="contentinfo">
+<hr>
+<p class="legal-copy"><small>Copyright &#169; 2007&#x2013;2020 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
+</footer>
+</div>
+</div>
+</body>
+</html>
diff --git a/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaCoprocessorHost.html b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaCoprocessorHost.html
new file mode 100644
index 00000000000..0905d43f33d
--- /dev/null
+++ b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaCoprocessorHost.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+<!-- Generated by javadoc (17) -->
+<title>Uses of Class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="description" content="use: package: org.apache.hadoop.hbase.coprocessor, class: ClientMetaCoprocessorHost">
+<meta name="generator" content="javadoc/ClassUseWriter">
+<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
+<link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
+<link rel="stylesheet" type="text/css" href="../../../../../../jquery-ui.overrides.css" title="Style">
+<script type="text/javascript" src="../../../../../../script.js"></script>
+<script type="text/javascript" src="../../../../../../script-dir/jquery-3.6.1.min.js"></script>
+<script type="text/javascript" src="../../../../../../script-dir/jquery-ui.min.js"></script>
+</head>
+<body class="class-use-page">
+<script type="text/javascript">var pathtoroot = "../../../../../../";
+loadScripts(document, 'script');</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<div class="flex-box">
+<header role="banner" class="flex-header">
+<nav role="navigation">
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="top-nav" id="navbar-top">
+<div class="skip-nav"><a href="#skip-navbar-top" title="Skip navigation links">Skip navigation links</a></div>
+<ul id="navbar-top-firstrow" class="nav-list" title="Navigation">
+<li><a href="../../../../../../index.html">Overview</a></li>
+<li><a href="../package-summary.html">Package</a></li>
+<li>Class</li>
+<li class="nav-bar-cell1-rev">Use</li>
+<li><a href="../package-tree.html">Tree</a></li>
+<li><a href="../../../../../../deprecated-list.html">Deprecated</a></li>
+<li><a href="../../../../../../index-all.html">Index</a></li>
+<li><a href="../../../../../../help-doc.html#use">Help</a></li>
+</ul>
+</div>
+<div class="sub-nav">
+<div class="nav-list-search"><label for="search-input">SEARCH:</label>
+<input type="text" id="search-input" value="search" disabled="disabled">
+<input type="reset" id="reset-button" value="reset" disabled="disabled">
+</div>
+</div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<span class="skip-nav" id="skip-navbar-top"></span></nav>
+</header>
+<div class="flex-content">
+<main role="main">
+<div class="header">
+<h1 title="Uses of Class org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost" class="title">Uses of Class<br>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</h1>
+</div>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</span></div>
+<div class="summary-table two-column-summary">
+<div class="table-header col-first">Package</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase">org.apache.hadoop.hbase</a></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
+<section class="class-uses">
+<ul class="block-list">
+<li>
+<section class="detail" id="org.apache.hadoop.hbase">
+<h2>Uses of org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost in <a href="../../package-summary.html">org.apache.hadoop.hbase</a></h2>
+<div class="caption"><span>Methods in <a href="../../package-summary.html">org.apache.hadoop.hbase</a> that return org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">HBaseRpcServicesBase.</span><code>getClientMetaCoprocessorHost()</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
+</section>
+</li>
+</ul>
+</section>
+</main>
+<footer role="contentinfo">
+<hr>
+<p class="legal-copy"><small>Copyright &#169; 2007&#x2013;2020 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
+</footer>
+</div>
+</div>
+</body>
+</html>
diff --git a/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaObserver.html b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaObserver.html
new file mode 100644
index 00000000000..32cc82e7263
--- /dev/null
+++ b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ClientMetaObserver.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+<!-- Generated by javadoc (17) -->
+<title>Uses of Interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="description" content="use: package: org.apache.hadoop.hbase.coprocessor, interface: ClientMetaObserver">
+<meta name="generator" content="javadoc/ClassUseWriter">
+<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
+<link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
+<link rel="stylesheet" type="text/css" href="../../../../../../jquery-ui.overrides.css" title="Style">
+<script type="text/javascript" src="../../../../../../script.js"></script>
+<script type="text/javascript" src="../../../../../../script-dir/jquery-3.6.1.min.js"></script>
+<script type="text/javascript" src="../../../../../../script-dir/jquery-ui.min.js"></script>
+</head>
+<body class="class-use-page">
+<script type="text/javascript">var pathtoroot = "../../../../../../";
+loadScripts(document, 'script');</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<div class="flex-box">
+<header role="banner" class="flex-header">
+<nav role="navigation">
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="top-nav" id="navbar-top">
+<div class="skip-nav"><a href="#skip-navbar-top" title="Skip navigation links">Skip navigation links</a></div>
+<ul id="navbar-top-firstrow" class="nav-list" title="Navigation">
+<li><a href="../../../../../../index.html">Overview</a></li>
+<li><a href="../package-summary.html">Package</a></li>
+<li>Class</li>
+<li class="nav-bar-cell1-rev">Use</li>
+<li><a href="../package-tree.html">Tree</a></li>
+<li><a href="../../../../../../deprecated-list.html">Deprecated</a></li>
+<li><a href="../../../../../../index-all.html">Index</a></li>
+<li><a href="../../../../../../help-doc.html#use">Help</a></li>
+</ul>
+</div>
+<div class="sub-nav">
+<div class="nav-list-search"><label for="search-input">SEARCH:</label>
+<input type="text" id="search-input" value="search" disabled="disabled">
+<input type="reset" id="reset-button" value="reset" disabled="disabled">
+</div>
+</div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<span class="skip-nav" id="skip-navbar-top"></span></nav>
+</header>
+<div class="flex-content">
+<main role="main">
+<div class="header">
+<h1 title="Uses of Interface org.apache.hadoop.hbase.coprocessor.ClientMetaObserver" class="title">Uses of Interface<br>org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</h1>
+</div>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</span></div>
+<div class="summary-table two-column-summary">
+<div class="table-header col-first">Package</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.coprocessor">org.apache.hadoop.hbase.coprocessor</a></div>
+<div class="col-last even-row-color">
+<div class="block">Table of Contents</div>
+</div>
+</div>
+<section class="class-uses">
+<ul class="block-list">
+<li>
+<section class="detail" id="org.apache.hadoop.hbase.coprocessor">
+<h2>Uses of org.apache.hadoop.hbase.coprocessor.ClientMetaObserver in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a></h2>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a> that return types with arguments of type org.apache.hadoop.hbase.coprocessor.ClientMetaObserver in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Optional.html" title="class or interface in java.util" class="external-link">Optional</a>&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaObserver&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaCoprocessor.</span><code>getClientMetaObserver()</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
+</section>
+</li>
+</ul>
+</section>
+</main>
+<footer role="contentinfo">
+<hr>
+<p class="legal-copy"><small>Copyright &#169; 2007&#x2013;2020 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
+</footer>
+</div>
+</div>
+</body>
+</html>
diff --git a/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/CoprocessorHost.html b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/CoprocessorHost.html
index 62d4ed6265d..bd015180973 100644
--- a/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/CoprocessorHost.html
+++ b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/CoprocessorHost.html
@@ -57,16 +57,20 @@ loadScripts(document, 'script');</script>
 <div class="table-header col-last">Description</div>
 <div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase">org.apache.hadoop.hbase</a></div>
 <div class="col-last even-row-color">&nbsp;</div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.coprocessor">org.apache.hadoop.hbase.coprocessor</a></div>
 <div class="col-last odd-row-color">
+<div class="block">Table of Contents</div>
+</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
 <div class="block">Tools to help define network clients and servers.</div>
 </div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.master">org.apache.hadoop.hbase.master</a></div>
-<div class="col-last even-row-color">&nbsp;</div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.regionserver">org.apache.hadoop.hbase.regionserver</a></div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.master">org.apache.hadoop.hbase.master</a></div>
 <div class="col-last odd-row-color">&nbsp;</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.regionserver">org.apache.hadoop.hbase.regionserver</a></div>
 <div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
+<div class="col-last odd-row-color">&nbsp;</div>
 </div>
 <section class="class-uses">
 <ul class="block-list">
@@ -85,6 +89,20 @@ loadScripts(document, 'script');</script>
 </section>
 </li>
 <li>
+<section class="detail" id="org.apache.hadoop.hbase.coprocessor">
+<h2>Uses of org.apache.hadoop.hbase.coprocessor.CoprocessorHost in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a></h2>
+<div class="caption"><span>Subclasses of org.apache.hadoop.hbase.coprocessor.CoprocessorHost in  in <a href="../package-summary.html">org.apache.hadoop.hbase.coprocessor</a></span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Class</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>class&nbsp;</code></div>
+<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
+</section>
+</li>
+<li>
 <section class="detail" id="org.apache.hadoop.hbase.ipc">
 <h2>Uses of org.apache.hadoop.hbase.coprocessor.CoprocessorHost in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
 <div class="caption"><span>Subclasses of org.apache.hadoop.hbase.coprocessor.CoprocessorHost in  in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></span></div>
diff --git a/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ObserverContext.html b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ObserverContext.html
index 895909c4ed2..ab66403aa20 100644
--- a/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ObserverContext.html
+++ b/apidocs/org/apache/hadoop/hbase/coprocessor/class-use/ObserverContext.html
@@ -538,506 +538,536 @@ loadScripts(document, 'script');</script>
 <div class="col-last even-row-color">
 <div class="block">Called after a Store's memstore is flushed to disk.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetClusterMetrics<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.ClusterMetrics&nbsp;status)</code></div>
+<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.ServerName</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetActiveMaster<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.ServerName&nbsp;serverName)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after get cluster status.</div>
+<div class="block">Called after we got the active master.</div>
+</div>
+<div class="col-first even-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetBootstrapNodes<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;&nbsp;bootstrapNodes)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called after we got bootstrap nodes.</div>
+</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetClusterId<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;clusterId)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got the cluster ID.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetConfiguredNamespacesAndTablesInRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;groupName)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetClusterMetrics<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.ClusterMetrics&nbsp;status)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after getting the configured namespaces and tables in the region server group.</div>
+<div class="block">Called after get cluster status.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetLocks<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetConfiguredNamespacesAndTablesInRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;groupName)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after a getLocks request has been processed.</div>
+<div class="block">Called after getting the configured namespaces and tables in the region server group.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetNamespaceDescriptor<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.NamespaceDescriptor&nbsp;ns)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetLocks<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after a getNamespaceDescriptor request has been processed.</div>
+<div class="block">Called after a getLocks request has been processed.</div>
+</div>
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetMasters<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;org.apache.hadoop.hbase.ServerName,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a>&gt;&nbsp;serverNames)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after we got the master servers.</div>
+</div>
+<div class="col-first even-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>postGetMetaLocations<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.HRegionLocation&gt;&nbsp;metaLocations)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called after we got the meta region locations.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postGetOp<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
- org.apache.hadoop.hbase.client.Get&nbsp;get,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.Cell&gt;&nbsp;result)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetNamespaceDescriptor<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.NamespaceDescriptor&nbsp;ns)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after the client performs a Get</div>
+<div class="block">Called after a getNamespaceDescriptor request has been processed.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetProcedures<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postGetOp<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+ org.apache.hadoop.hbase.client.Get&nbsp;get,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.Cell&gt;&nbsp;result)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after a getProcedures request has been processed.</div>
+<div class="block">Called after the client performs a Get</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetReplicationPeerConfig<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetProcedures<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after get the configured ReplicationPeerConfig for the specified peer</div>
+<div class="block">Called after a getProcedures request has been processed.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetRSGroupInfo<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;groupName)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetReplicationPeerConfig<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after getting region server group info of the passed groupName.</div>
+<div class="block">Called after get the configured ReplicationPeerConfig for the specified peer</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetRSGroupInfoOfServer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.net.Address&nbsp;server)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetRSGroupInfo<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;groupName)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after getting region server group info of the passed server.</div>
+<div class="block">Called after getting region server group info of the passed groupName.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetRSGroupInfoOfTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetRSGroupInfoOfServer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.net.Address&nbsp;server)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after getting region server group info of the passed tableName.</div>
+<div class="block">Called after getting region server group info of the passed server.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetTableDescriptors<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetRSGroupInfoOfTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after getting region server group info of the passed tableName.</div>
+</div>
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetTableDescriptors<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.TableName&gt;&nbsp;tableNamesList,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.client.TableDescriptor&gt;&nbsp;descriptors,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;regex)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after a getTableDescriptors request has been processed.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetTableNames<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetTableNames<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.client.TableDescriptor&gt;&nbsp;descriptors,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;regex)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after a getTableNames request has been processed.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetUserPermissions<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGetUserPermissions<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;userName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;namespace,
  org.apache.hadoop.hbase.TableName&nbsp;tableName,
  byte[]&nbsp;family,
  byte[]&nbsp;qualifier)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after getting user permissions.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postGrant<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postGrant<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.security.access.UserPermission&nbsp;userPermission,
  boolean&nbsp;mergeExistingPermissions)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after granting user permissions.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postHasUserPermissions<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postHasUserPermissions<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;userName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.security.access.Permission&gt;&nbsp;permissions)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after checking if user has permissions.</div>
 </div>
-<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postIncrement<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postIncrement<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Increment&nbsp;increment,
  org.apache.hadoop.hbase.client.Result&nbsp;result)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postIncrement<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postIncrement<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Increment&nbsp;increment,
  org.apache.hadoop.hbase.client.Result&nbsp;result,
  org.apache.hadoop.hbase.wal.WALEdit&nbsp;edit)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after increment</div>
 </div>
-<div class="col-first even-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.util.Pair&lt;org.apache.hadoop.hbase.Cell,<wbr>org.apache.hadoop.hbase.Cell&gt;&gt;</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postIncrementBeforeWAL<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.util.Pair&lt;org.apache.hadoop.hbase.Cell,<wbr>org.apache.hadoop.hbase.Cell&gt;&gt;</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postIncrementBeforeWAL<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.Mutation&nbsp;mutation,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.util.Pair&lt;org.apache.hadoop.hbase.Cell,<wbr>org.apache.hadoop.hbase.Cell&gt;&gt;&nbsp;cellPairs)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after a list of new cells has been created during an increment operation, but before
  they are committed to the WAL or memstore.</div>
 </div>
-<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.regionserver.querymatcher.DeleteTracker</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postInstantiateDeleteTracker<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.regionserver.querymatcher.DeleteTracker</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postInstantiateDeleteTracker<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.regionserver.querymatcher.DeleteTracker&nbsp;delTracker)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">Since 2.0.0, will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postIsRpcThrottleEnabled<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- boolean&nbsp;rpcThrottleEnabled)</code></div>
-<div class="col-last even-row-color">
-<div class="block">Called after getting if is rpc throttle enabled.</div>
-</div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postListDecommissionedRegionServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postIsRpcThrottleEnabled<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ boolean&nbsp;rpcThrottleEnabled)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after list decommissioned region servers.</div>
+<div class="block">Called after getting if is rpc throttle enabled.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postListNamespaceDescriptors<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.NamespaceDescriptor&gt;&nbsp;descriptors)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postListDecommissionedRegionServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after a listNamespaceDescriptors request has been processed.</div>
+<div class="block">Called after list decommissioned region servers.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postListNamespaces<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;&nbsp;namespaces)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postListNamespaceDescriptors<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.NamespaceDescriptor&gt;&nbsp;descriptors)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after a listNamespaces request has been processed.</div>
+<div class="block">Called after a listNamespaceDescriptors request has been processed.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postListReplicationPeers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;regex)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postListNamespaces<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;&nbsp;namespaces)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after list replication peers.</div>
+<div class="block">Called after a listNamespaces request has been processed.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postListRSGroups<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postListReplicationPeers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;regex)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after listing region server group information.</div>
+<div class="block">Called after list replication peers.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postListSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.client.SnapshotDescription&nbsp;snapshot)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postListRSGroups<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after listSnapshots request has been processed.</div>
+<div class="block">Called after listing region server group information.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postListTablesInRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;groupName)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postListSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.client.SnapshotDescription&nbsp;snapshot)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after listing all tables in the region server group.</div>
+<div class="block">Called after listSnapshots request has been processed.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postLockHeartbeat<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postListTablesInRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;groupName)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after heartbeat to a lock.</div>
+<div class="block">Called after listing all tables in the region server group.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postMasterStoreFlush<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postLockHeartbeat<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after the master local region memstore is flushed to disk.</div>
+<div class="block">Called after heartbeat to a lock.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postMemStoreCompaction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
- org.apache.hadoop.hbase.regionserver.Store&nbsp;store)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postMasterStoreFlush<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after the in memory compaction is finished.</div>
+<div class="block">Called after the master local region memstore is flushed to disk.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postMergeRegions<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;c,
- org.apache.hadoop.hbase.client.RegionInfo[]&nbsp;regionsToMerge)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postMemStoreCompaction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+ org.apache.hadoop.hbase.regionserver.Store&nbsp;store)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">called after merge regions request.</div>
+<div class="block">Called after the in memory compaction is finished.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postMergeRegionsCommitAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postMergeRegions<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;c,
+ org.apache.hadoop.hbase.client.RegionInfo[]&nbsp;regionsToMerge)</code></div>
+<div class="col-last even-row-color">
+<div class="block">called after merge regions request.</div>
+</div>
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postMergeRegionsCommitAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.RegionInfo[]&nbsp;regionsToMerge,
  org.apache.hadoop.hbase.client.RegionInfo&nbsp;mergedRegion)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">This will be called after META step as part of regions merge transaction.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postModifyColumnFamilyStoreFileTracker<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postModifyColumnFamilyStoreFileTracker<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.TableName&nbsp;tableName,
  byte[]&nbsp;family,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;dstSFT)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after modifying a family store file tracker.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postModifyNamespace<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postModifyNamespace<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.NamespaceDescriptor&nbsp;oldNsDescriptor,
  org.apache.hadoop.hbase.NamespaceDescriptor&nbsp;currentNsDescriptor)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after the modifyNamespace operation has been requested.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postModifyTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postModifyTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.TableName&nbsp;tableName,
  org.apache.hadoop.hbase.client.TableDescriptor&nbsp;oldDescriptor,
  org.apache.hadoop.hbase.client.TableDescriptor&nbsp;currentDescriptor)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after the modifyTable operation has been requested.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postModifyTableStoreFileTracker<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postModifyTableStoreFileTracker<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.TableName&nbsp;tableName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;dstSFT)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after modifying a table's store file tracker.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postMove<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postMove<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.RegionInfo&nbsp;region,
  org.apache.hadoop.hbase.ServerName&nbsp;srcServer,
  org.apache.hadoop.hbase.ServerName&nbsp;destServer)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after the region move has been requested.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postMoveServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postMoveServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;org.apache.hadoop.hbase.net.Address&gt;&nbsp;servers,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;targetGroup)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after servers are moved to target region server group</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postMoveServersAndTables<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postMoveServersAndTables<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;org.apache.hadoop.hbase.net.Address&gt;&nbsp;servers,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;org.apache.hadoop.hbase.TableName&gt;&nbsp;tables,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;targetGroup)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after servers are moved to target region server group</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postMoveTables<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postMoveTables<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;org.apache.hadoop.hbase.TableName&gt;&nbsp;tables,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;targetGroup)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after servers are moved to target region server group</div>
 </div>
-<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.Cell</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postMutationBeforeWAL<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.Cell</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postMutationBeforeWAL<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.coprocessor.RegionObserver.MutationType&nbsp;opType,
  org.apache.hadoop.hbase.client.Mutation&nbsp;mutation,
  org.apache.hadoop.hbase.Cell&nbsp;oldCell,
  org.apache.hadoop.hbase.Cell&nbsp;newCell)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 2.2.0 and will be removedin 4.0.0.</div>
 </div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c)</code></div>
-<div class="col-last even-row-color">
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c)</code></div>
+<div class="col-last odd-row-color">
 <div class="block">Called after the region is reported as open to the master.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postPut<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postPut<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Put&nbsp;put,
  org.apache.hadoop.hbase.wal.WALEdit&nbsp;edit)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after the client stores a value.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postPut<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postPut<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Put&nbsp;put,
  org.apache.hadoop.hbase.wal.WALEdit&nbsp;edit,
  org.apache.hadoop.hbase.client.Durability&nbsp;durability)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRecommissionRegionServer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRecommissionRegionServer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.ServerName&nbsp;server,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;byte[]&gt;&nbsp;encodedRegionNames)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after recommission region server.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRegionOffline<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRegionOffline<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.RegionInfo&nbsp;regionInfo)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after the region has been marked offline.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRemoveReplicationPeer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRemoveReplicationPeer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after remove a replication peer</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRemoveRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRemoveRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;name)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after a region server group is removed</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRemoveServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRemoveServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;org.apache.hadoop.hbase.net.Address&gt;&nbsp;servers)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after servers are removed from rsgroup</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRenameRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRenameRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;oldName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;newName)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after rename rsgroup.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postReplayWALs<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postReplayWALs<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.RegionInfo&nbsp;info,
  org.apache.hadoop.fs.Path&nbsp;edits)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after replaying WALs for this region.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionServerObserver.</span><code>postReplicateLogEntries<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
-<div class="col-last even-row-color">
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionServerObserver.</span><code>postReplicateLogEntries<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last odd-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">As of release 2.0.0 with out any replacement, plan to remove in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionServerObserver.</span><code>postReplicationSinkBatchMutate<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionServerObserver.</span><code>postReplicationSinkBatchMutate<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.WALEntry&nbsp;walEntry,
  org.apache.hadoop.hbase.client.Mutation&nbsp;mutation)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">This will be called after replication sink mutations are executed on the sink table as part of
  batch call.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRequestLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRequestLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;namespace,
  org.apache.hadoop.hbase.TableName&nbsp;tableName,
  org.apache.hadoop.hbase.client.RegionInfo[]&nbsp;regionInfos,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;description)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after new LockProcedure is queued.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRestoreSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRestoreSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.SnapshotDescription&nbsp;snapshot,
  org.apache.hadoop.hbase.client.TableDescriptor&nbsp;tableDescriptor)</code></div>
-<div class="col-last odd-row-color">
-<div class="block">Called after a snapshot restore operation has been requested.</div>
-</div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRevoke<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.security.access.UserPermission&nbsp;userPermission)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after revoking user permissions.</div>
+<div class="block">Called after a snapshot restore operation has been requested.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRollBackMergeRegionsAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.client.RegionInfo[]&nbsp;regionsToMerge)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRevoke<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.security.access.UserPermission&nbsp;userPermission)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">This will be called after the roll back of the regions merge.</div>
+<div class="block">Called after revoking user permissions.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRollBackSplitRegionAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postRollBackMergeRegionsAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.client.RegionInfo[]&nbsp;regionsToMerge)</code></div>
 <div class="col-last even-row-color">
-<div class="block">This will be called after the roll back of the split region is completed</div>
+<div class="block">This will be called after the roll back of the regions merge.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionServerObserver.</span><code>postRollWALWriterRequest<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postRollBackSplitRegionAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">This will be called after executing user request to roll a region server WAL.</div>
+<div class="block">This will be called after the roll back of the split region is completed</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postScannerClose<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.regionserver.InternalScanner&nbsp;s)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionServerObserver.</span><code>postRollWALWriterRequest<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last even-row-color">
+<div class="block">This will be called after executing user request to roll a region server WAL.</div>
+</div>
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postScannerClose<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.regionserver.InternalScanner&nbsp;s)</code></div>
+<div class="col-last odd-row-color">
 <div class="block">Called after the client closes a scanner.</div>
 </div>
-<div class="col-first odd-row-color"><code>default boolean</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postScannerFilterRow<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default boolean</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postScannerFilterRow<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.regionserver.InternalScanner&nbsp;s,
  org.apache.hadoop.hbase.Cell&nbsp;curRowCell,
  boolean&nbsp;hasMore)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">This will be called by the scan flow when the current scanned row is being filtered out by the
  filter.</div>
 </div>
-<div class="col-first even-row-color"><code>default boolean</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postScannerNext<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default boolean</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postScannerNext<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.regionserver.InternalScanner&nbsp;s,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.client.Result&gt;&nbsp;result,
  int&nbsp;limit,
  boolean&nbsp;hasNext)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after the client asks for the next row on a scanner.</div>
 </div>
-<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.regionserver.RegionScanner</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postScannerOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.regionserver.RegionScanner</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postScannerOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Scan&nbsp;scan,
  org.apache.hadoop.hbase.regionserver.RegionScanner&nbsp;s)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after the client opens a new scanner.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetNamespaceQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetNamespaceQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;namespace,
  org.apache.hadoop.hbase.quotas.GlobalQuotaSettings&nbsp;quotas)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after the quota for the namespace is stored.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetRegionServerQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetRegionServerQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;regionServer,
  org.apache.hadoop.hbase.quotas.GlobalQuotaSettings&nbsp;quotas)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after the quota for the region server is stored.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetSplitOrMergeEnabled<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetSplitOrMergeEnabled<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  boolean&nbsp;newValue,
  org.apache.hadoop.hbase.client.MasterSwitchType&nbsp;switchType)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after setting split / merge switch</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetTableQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetTableQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.TableName&nbsp;tableName,
  org.apache.hadoop.hbase.quotas.GlobalQuotaSettings&nbsp;quotas)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after the quota for the table is stored.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetUserQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetUserQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;userName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;namespace,
  org.apache.hadoop.hbase.quotas.GlobalQuotaSettings&nbsp;quotas)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after the quota for the user on the specified namespace is stored.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetUserQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetUserQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;userName,
  org.apache.hadoop.hbase.quotas.GlobalQuotaSettings&nbsp;quotas)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after the quota for the user is stored.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetUserQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSetUserQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;userName,
  org.apache.hadoop.hbase.TableName&nbsp;tableName,
  org.apache.hadoop.hbase.quotas.GlobalQuotaSettings&nbsp;quotas)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after the quota for the user on the specified table is stored.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.SnapshotDescription&nbsp;snapshot,
  org.apache.hadoop.hbase.client.TableDescriptor&nbsp;tableDescriptor)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after the snapshot operation has been requested.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postStartMaster<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
-<div class="col-last even-row-color">
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postStartMaster<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last odd-row-color">
 <div class="block">Called immediately after an active master instance has completed initialization.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postStartRegionOperation<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postStartRegionOperation<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.regionserver.Region.Operation&nbsp;operation)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">This will be called for region operations where read lock is acquired in
  <code>Region.startRegionOperation()</code>.</div>
 </div>
-<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.regionserver.StoreFileReader</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postStoreFileReaderOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.regionserver.StoreFileReader</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postStoreFileReaderOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.fs.FileSystem&nbsp;fs,
  org.apache.hadoop.fs.Path&nbsp;p,
  org.apache.hadoop.hbase.io.FSDataInputStreamWrapper&nbsp;in,
@@ -1045,201 +1075,201 @@ loadScripts(document, 'script');</script>
  org.apache.hadoop.hbase.io.hfile.CacheConfig&nbsp;cacheConf,
  org.apache.hadoop.hbase.io.Reference&nbsp;r,
  org.apache.hadoop.hbase.regionserver.StoreFileReader&nbsp;reader)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">For Phoenix only, StoreFileReader is not a stable interface.</div>
 </div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSwitchExceedThrottleQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSwitchExceedThrottleQuota<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  boolean&nbsp;oldValue,
  boolean&nbsp;newValue)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after switching exceed throttle quota state.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postSwitchRpcThrottle<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postSwitchRpcThrottle<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  boolean&nbsp;oldValue,
  boolean&nbsp;newValue)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after switching rpc throttle enabled state.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postTableFlush<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postTableFlush<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after the table memstore is flushed to disk.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postTransitReplicationPeerSyncReplicationState<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postTransitReplicationPeerSyncReplicationState<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId,
  org.apache.hadoop.hbase.replication.SyncReplicationState&nbsp;from,
  org.apache.hadoop.hbase.replication.SyncReplicationState&nbsp;to)</code></div>
-<div class="col-last even-row-color">
-<div class="block">Called after transit current cluster state for the specified synchronous replication peer</div>
-</div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postTruncateRegion<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;c,
- org.apache.hadoop.hbase.client.RegionInfo&nbsp;regionInfo)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after the truncate region procedure is called.</div>
+<div class="block">Called after transit current cluster state for the specified synchronous replication peer</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postTruncateRegionAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postTruncateRegion<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.RegionInfo&nbsp;regionInfo)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called post the region is truncated.</div>
+<div class="block">Called after the truncate region procedure is called.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postTruncateTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postTruncateRegionAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;c,
+ org.apache.hadoop.hbase.client.RegionInfo&nbsp;regionInfo)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after the truncateTable operation has been requested.</div>
+<div class="block">Called post the region is truncated.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postUnassign<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.client.RegionInfo&nbsp;regionInfo)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postTruncateTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after the region unassignment has been requested.</div>
+<div class="block">Called after the truncateTable operation has been requested.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postUpdateMasterConfiguration<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.conf.Configuration&nbsp;postReloadConf)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postUnassign<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.client.RegionInfo&nbsp;regionInfo)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called after reloading the HMaster's <code>Configuration</code> from disk</div>
+<div class="block">Called after the region unassignment has been requested.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionServerObserver.</span><code>postUpdateRegionServerConfiguration<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postUpdateMasterConfiguration<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.conf.Configuration&nbsp;postReloadConf)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called after reloading the RegionServer's <code>Configuration</code> from disk</div>
+<div class="block">Called after reloading the HMaster's <code>Configuration</code> from disk</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postUpdateReplicationPeerConfig<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-second odd-row-color"><span class="type-name-label">RegionServerObserver.</span><code>postUpdateRegionServerConfiguration<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.conf.Configuration&nbsp;postReloadConf)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called after reloading the RegionServer's <code>Configuration</code> from disk</div>
+</div>
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postUpdateReplicationPeerConfig<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId,
  org.apache.hadoop.hbase.replication.ReplicationPeerConfig&nbsp;peerConfig)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after update peerConfig for the specified peer</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>postUpdateRSGroupConfig<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>postUpdateRSGroupConfig<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;groupName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>,<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">St [...]
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after update rsgroup config.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>postWALRestore<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>postWALRestore<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.RegionInfo&nbsp;info,
  org.apache.hadoop.hbase.wal.WALKey&nbsp;logKey,
  org.apache.hadoop.hbase.wal.WALEdit&nbsp;logEdit)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after a <code>WALEdit</code> replayed for this region.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">WALObserver.</span><code>postWALRoll<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.WALCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">WALObserver.</span><code>postWALRoll<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.WALCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.fs.Path&nbsp;oldPath,
  org.apache.hadoop.fs.Path&nbsp;newPath)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called after rolling the current WAL</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">WALObserver.</span><code>postWALWrite<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.WALCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">WALObserver.</span><code>postWALWrite<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.WALCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.RegionInfo&nbsp;info,
  org.apache.hadoop.hbase.wal.WALKey&nbsp;logKey,
  org.apache.hadoop.hbase.wal.WALEdit&nbsp;logEdit)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called after a <code>WALEdit</code> is writen to WAL.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preAbortProcedure<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preAbortProcedure<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  long&nbsp;procId)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before a abortProcedure request has been processed.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preAddReplicationPeer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preAddReplicationPeer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId,
  org.apache.hadoop.hbase.replication.ReplicationPeerConfig&nbsp;peerConfig)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before add a replication peer</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preAddRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preAddRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;name)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before a new region server group is added</div>
 </div>
-<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preAppend<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preAppend<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Append&nbsp;append)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preAppend<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preAppend<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Append&nbsp;append,
  org.apache.hadoop.hbase.wal.WALEdit&nbsp;edit)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before Append.</div>
 </div>
-<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preAppendAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.client.Result</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preAppendAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Append&nbsp;append)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preAssign<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preAssign<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.RegionInfo&nbsp;regionInfo)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called prior to assigning a specific region.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RpcObserver.</span><code>preAuthorizeConnection<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RpcCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RpcObserver.</span><code>preAuthorizeConnection<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RpcCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.ConnectionHeader&nbsp;connectionHeader,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/InetAddress.html" title="class or interface in java.net" class="external-link">InetAddress</a>&nbsp;remoteAddr)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before authorizing connection</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preBalance<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preBalance<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.BalanceRequest&nbsp;request)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called prior to requesting rebalancing of the cluster regions, though after the initial checks
  for regions in transition and the balance switch flag.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preBalanceRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preBalanceRSGroup<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;groupName,
  org.apache.hadoop.hbase.client.BalanceRequest&nbsp;request)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before a region server group is removed</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preBalanceSwitch<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preBalanceSwitch<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  boolean&nbsp;newValue)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called prior to modifying the flag used to enable/disable region balancing.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preBatchMutate<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preBatchMutate<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress&lt;org.apache.hadoop.hbase.client.Mutation&gt;&nbsp;miniBatchOp)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">This will be called for every batch mutation operation happening at the server.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preBulkLoadHFile<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preBulkLoadHFile<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.util.Pair&lt;byte[],<wbr><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;&gt;&nbsp;familyPaths)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before bulkLoadHFile.</div>
 </div>
-<div class="col-first odd-row-color"><code>default boolean</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndDelete<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default boolean</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndDelete<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  byte[]&nbsp;row,
  byte[]&nbsp;family,
  byte[]&nbsp;qualifier,
@@ -1247,24 +1277,24 @@ loadScripts(document, 'script');</script>
  org.apache.hadoop.hbase.filter.ByteArrayComparable&nbsp;comparator,
  org.apache.hadoop.hbase.client.Delete&nbsp;delete,
  boolean&nbsp;result)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first even-row-color"><code>default boolean</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndDelete<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default boolean</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndDelete<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  byte[]&nbsp;row,
  org.apache.hadoop.hbase.filter.Filter&nbsp;filter,
  org.apache.hadoop.hbase.client.Delete&nbsp;delete,
  boolean&nbsp;result)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first odd-row-color"><code>default boolean</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndDeleteAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default boolean</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndDeleteAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  byte[]&nbsp;row,
  byte[]&nbsp;family,
  byte[]&nbsp;qualifier,
@@ -1272,38 +1302,38 @@ loadScripts(document, 'script');</script>
  org.apache.hadoop.hbase.filter.ByteArrayComparable&nbsp;comparator,
  org.apache.hadoop.hbase.client.Delete&nbsp;delete,
  boolean&nbsp;result)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first even-row-color"><code>default boolean</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndDeleteAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default boolean</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndDeleteAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  byte[]&nbsp;row,
  org.apache.hadoop.hbase.filter.Filter&nbsp;filter,
  org.apache.hadoop.hbase.client.Delete&nbsp;delete,
  boolean&nbsp;result)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.client.CheckAndMutateResult</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndMutate<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.client.CheckAndMutateResult</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndMutate<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  <a href="../../client/CheckAndMutate.html" title="class in org.apache.hadoop.hbase.client">CheckAndMutate</a>&nbsp;checkAndMutate,
  org.apache.hadoop.hbase.client.CheckAndMutateResult&nbsp;result)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before checkAndMutate</div>
 </div>
-<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.client.CheckAndMutateResult</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndMutateAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.client.CheckAndMutateResult</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndMutateAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  <a href="../../client/CheckAndMutate.html" title="class in org.apache.hadoop.hbase.client">CheckAndMutate</a>&nbsp;checkAndMutate,
  org.apache.hadoop.hbase.client.CheckAndMutateResult&nbsp;result)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before checkAndDelete but after acquiring rowlock.</div>
 </div>
-<div class="col-first odd-row-color"><code>default boolean</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndPut<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default boolean</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndPut<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  byte[]&nbsp;row,
  byte[]&nbsp;family,
  byte[]&nbsp;qualifier,
@@ -1311,24 +1341,24 @@ loadScripts(document, 'script');</script>
  org.apache.hadoop.hbase.filter.ByteArrayComparable&nbsp;comparator,
  org.apache.hadoop.hbase.client.Put&nbsp;put,
  boolean&nbsp;result)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first even-row-color"><code>default boolean</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndPut<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default boolean</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndPut<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  byte[]&nbsp;row,
  org.apache.hadoop.hbase.filter.Filter&nbsp;filter,
  org.apache.hadoop.hbase.client.Put&nbsp;put,
  boolean&nbsp;result)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first odd-row-color"><code>default boolean</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndPutAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default boolean</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndPutAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  byte[]&nbsp;row,
  byte[]&nbsp;family,
  byte[]&nbsp;qualifier,
@@ -1336,244 +1366,259 @@ loadScripts(document, 'script');</script>
  org.apache.hadoop.hbase.filter.ByteArrayComparable&nbsp;comparator,
  org.apache.hadoop.hbase.client.Put&nbsp;put,
  boolean&nbsp;result)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first even-row-color"><code>default boolean</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndPutAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default boolean</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCheckAndPutAfterRowLock<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  byte[]&nbsp;row,
  org.apache.hadoop.hbase.filter.Filter&nbsp;filter,
  org.apache.hadoop.hbase.client.Put&nbsp;put,
  boolean&nbsp;result)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">BulkLoadObserver.</span><code>preCleanupBulkLoad<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
-<div class="col-last odd-row-color">
-<div class="block">Called as part of the SecureBulkLoadEndpoint.cleanupBulkLoad() RPC call.</div>
-</div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionServerObserver.</span><code>preClearCompactionQueues<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">BulkLoadObserver.</span><code>preCleanupBulkLoad<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last even-row-color">
-<div class="block">This will be called before clearing compaction queues</div>
+<div class="block">Called as part of the SecureBulkLoadEndpoint.cleanupBulkLoad() RPC call.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preClearDeadServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionServerObserver.</span><code>preClearCompactionQueues<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called before clear dead region servers.</div>
+<div class="block">This will be called before clearing compaction queues</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionServerObserver.</span><code>preClearRegionBlockCache<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preClearDeadServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called before clearing the block caches for one or more regions</div>
+<div class="block">Called before clear dead region servers.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preCloneSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-second odd-row-color"><span class="type-name-label">RegionServerObserver.</span><code>preClearRegionBlockCache<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called before clearing the block caches for one or more regions</div>
+</div>
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preCloneSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.SnapshotDescription&nbsp;snapshot,
  org.apache.hadoop.hbase.client.TableDescriptor&nbsp;tableDescriptor)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before a snapshot is cloned.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preClose<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preClose<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  boolean&nbsp;abortRequested)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before the region is reported as closed to the master.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCommitStoreFile<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCommitStoreFile<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  byte[]&nbsp;family,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.util.Pair&lt;org.apache.hadoop.fs.Path,<wbr>org.apache.hadoop.fs.Path&gt;&gt;&nbsp;pairs)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before moving bulk loaded hfile to region directory.</div>
 </div>
-<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.regionserver.InternalScanner</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCompact<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.regionserver.InternalScanner</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCompact<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.regionserver.Store&nbsp;store,
  org.apache.hadoop.hbase.regionserver.InternalScanner&nbsp;scanner,
  org.apache.hadoop.hbase.regionserver.ScanType&nbsp;scanType,
  org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker&nbsp;tracker,
  org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest&nbsp;request)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called prior to writing the <code>StoreFile</code>s selected for compaction into a new
  <code>StoreFile</code>.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCompactScannerOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCompactScannerOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.regionserver.Store&nbsp;store,
  org.apache.hadoop.hbase.regionserver.ScanType&nbsp;scanType,
  org.apache.hadoop.hbase.regionserver.ScanOptions&nbsp;options,
  org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker&nbsp;tracker,
  org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest&nbsp;request)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before we open store scanner for compaction.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preCompactSelection<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preCompactSelection<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.regionserver.Store&nbsp;store,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;? extends org.apache.hadoop.hbase.regionserver.StoreFile&gt;&nbsp;candidates,
  org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker&nbsp;tracker)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called prior to selecting the <code>StoreFiles</code> to compact from the list of
  available candidates.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preCreateNamespace<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preCreateNamespace<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.NamespaceDescriptor&nbsp;ns)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before a new namespace is created by <code>HMaster</code>.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preCreateTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preCreateTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.TableDescriptor&nbsp;desc,
  org.apache.hadoop.hbase.client.RegionInfo[]&nbsp;regions)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before a new table is created by <code>HMaster</code>.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preCreateTableAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preCreateTableAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.TableDescriptor&nbsp;desc,
  org.apache.hadoop.hbase.client.RegionInfo[]&nbsp;regions)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before a new table is created by <code>HMaster</code>.</div>
 </div>
-<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.client.TableDescriptor</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preCreateTableRegionsInfos<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.client.TableDescriptor</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preCreateTableRegionsInfos<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.client.TableDescriptor&nbsp;desc)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before we create the region infos for this table.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preDecommissionRegionServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preDecommissionRegionServers<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;org.apache.hadoop.hbase.ServerName&gt;&nbsp;servers,
  boolean&nbsp;offload)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before decommission region servers.</div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preDelete<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preDelete<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Delete&nbsp;delete,
  org.apache.hadoop.hbase.wal.WALEdit&nbsp;edit)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before the client deletes a value.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preDelete<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preDelete<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Delete&nbsp;delete,
  org.apache.hadoop.hbase.wal.WALEdit&nbsp;edit,
  org.apache.hadoop.hbase.client.Durability&nbsp;durability)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block"><span class="deprecated-label">Deprecated.</span>
 <div class="deprecation-comment">since 3.0.0 and will be removed in 4.0.0.</div>
 </div>
 </div>
-<div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preDeleteNamespace<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;namespace)</code></div>
-<div class="col-last even-row-color">
-<div class="block">Called before <code>HMaster</code> deletes a namespace</div>
-</div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preDeleteSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.client.SnapshotDescription&nbsp;snapshot)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preDeleteNamespace<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;namespace)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called before a snapshot is deleted.</div>
+<div class="block">Called before <code>HMaster</code> deletes a namespace</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preDeleteTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preDeleteSnapshot<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.client.SnapshotDescription&nbsp;snapshot)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called before <code>HMaster</code> deletes a table.</div>
+<div class="block">Called before a snapshot is deleted.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preDeleteTableAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preDeleteTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
 <div class="col-last odd-row-color">
 <div class="block">Called before <code>HMaster</code> deletes a table.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preDisableReplicationPeer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preDeleteTableAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called before disable a replication peer</div>
+<div class="block">Called before <code>HMaster</code> deletes a table.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preDisableTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preDisableReplicationPeer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called prior to disabling a table.</div>
+<div class="block">Called before disable a replication peer</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preDisableTableAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preDisableTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
 <div class="col-last even-row-color">
 <div class="block">Called prior to disabling a table.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preEnableReplicationPeer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preDisableTableAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
 <div class="col-last odd-row-color">
-<div class="block">Called before enable a replication peer</div>
+<div class="block">Called prior to disabling a table.</div>
 </div>
 <div class="col-first even-row-color"><code>default void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preEnableTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
- org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preEnableReplicationPeer<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;peerId)</code></div>
 <div class="col-last even-row-color">
-<div class="block">Called prior to enabling a table.</div>
+<div class="block">Called before enable a replication peer</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preEnableTableAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preEnableTable<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
 <div class="col-last odd-row-color">
 <div class="block">Called prior to enabling a table.</div>
 </div>
-<div class="col-first even-row-color"><code>default org.apache.hbase.thirdparty.com.google.protobuf.Message</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">EndpointObserver.</span><code>preEndpointInvocation<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preEnableTableAction<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
+ org.apache.hadoop.hbase.TableName&nbsp;tableName)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called prior to enabling a table.</div>
+</div>
+<div class="col-first odd-row-color"><code>default org.apache.hbase.thirdparty.com.google.protobuf.Message</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">EndpointObserver.</span><code>preEndpointInvocation<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;ctx,
  org.apache.hbase.thirdparty.com.google.protobuf.Service&nbsp;service,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;methodName,
  org.apache.hbase.thirdparty.com.google.protobuf.Message&nbsp;request)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before an Endpoint service method is invoked.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionServerObserver.</span><code>preExecuteProcedures<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionServerObserver.</span><code>preExecuteProcedures<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last even-row-color">
 <div class="block">This will be called before executing procedures</div>
 </div>
-<div class="col-first even-row-color"><code>default boolean</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preExists<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default boolean</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preExists<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.client.Get&nbsp;get,
  boolean&nbsp;exists)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before the client tests for existence using a Get.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preFlush<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preFlush<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.regionserver.FlushLifeCycleTracker&nbsp;tracker)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before the memstore is flushed to disk.</div>
 </div>
-<div class="col-first even-row-color"><code>default org.apache.hadoop.hbase.regionserver.InternalScanner</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preFlush<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first odd-row-color"><code>default org.apache.hadoop.hbase.regionserver.InternalScanner</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preFlush<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.regionserver.Store&nbsp;store,
  org.apache.hadoop.hbase.regionserver.InternalScanner&nbsp;scanner,
  org.apache.hadoop.hbase.regionserver.FlushLifeCycleTracker&nbsp;tracker)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Called before a Store's memstore is flushed to disk.</div>
 </div>
-<div class="col-first odd-row-color"><code>default void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RegionObserver.</span><code>preFlushScannerOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RegionObserver.</span><code>preFlushScannerOpen<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;? extends org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment&gt;&nbsp;c,
  org.apache.hadoop.hbase.regionserver.Store&nbsp;store,
  org.apache.hadoop.hbase.regionserver.ScanOptions&nbsp;options,
  org.apache.hadoop.hbase.regionserver.FlushLifeCycleTracker&nbsp;tracker)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-last even-row-color">
 <div class="block">Called before we open store scanner for flush.</div>
 </div>
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetActiveMaster<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called before getting the active master.</div>
+</div>
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetBootstrapNodes<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called before getting bootstrap nodes.</div>
+</div>
+<div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetClusterId<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called before getting the cluster ID.</div>
+</div>
 <div class="col-first even-row-color"><code>default void</code></div>
 <div class="col-second even-row-color"><span class="type-name-label">MasterObserver.</span><code>preGetClusterMetrics<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
 <div class="col-last even-row-color">
@@ -1591,6 +1636,16 @@ loadScripts(document, 'script');</script>
 <div class="block">Called before a getLocks request has been processed.</div>
 </div>
 <div class="col-first odd-row-color"><code>default void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetMasters<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Called before getting the master servers.</div>
+</div>
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ClientMetaObserver.</span><code>preGetMetaLocations<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment&gt;&nbsp;ctx)</code></div>
+<div class="col-last even-row-color">
+<div class="block">Called before getting the meta region locations.</div>
+</div>
+<div class="col-first odd-row-color"><code>default void</code></div>
 <div class="col-second odd-row-color"><span class="type-name-label">MasterObserver.</span><code>preGetNamespaceDescriptor<wbr>(org.apache.hadoop.hbase.coprocessor.ObserverContext&lt;org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment&gt;&nbsp;ctx,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;namespace)</code></div>
 <div class="col-last odd-row-color">
diff --git a/apidocs/org/apache/hadoop/hbase/coprocessor/package-summary.html b/apidocs/org/apache/hadoop/hbase/coprocessor/package-summary.html
index fbb382ac8e9..31a5e5003e8 100644
--- a/apidocs/org/apache/hadoop/hbase/coprocessor/package-summary.html
+++ b/apidocs/org/apache/hadoop/hbase/coprocessor/package-summary.html
@@ -348,6 +348,17 @@ order of assigned priority.
 <div class="col-last odd-row-color class-summary class-summary-tab1">
 <div class="block">Coprocessors implement this interface to observe and mediate bulk load operations.</div>
 </div>
+<div class="col-first even-row-color class-summary class-summary-tab1">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor</div>
+<div class="col-last even-row-color class-summary class-summary-tab1">&nbsp;</div>
+<div class="col-first odd-row-color class-summary class-summary-tab1">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment</div>
+<div class="col-last odd-row-color class-summary class-summary-tab1">&nbsp;</div>
+<div class="col-first even-row-color class-summary class-summary-tab2">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</div>
+<div class="col-last even-row-color class-summary class-summary-tab2">&nbsp;</div>
+<div class="col-first odd-row-color class-summary class-summary-tab1">org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</div>
+<div class="col-last odd-row-color class-summary class-summary-tab1">
+<div class="block">Defines coprocessor hooks for interacting operations for ClientMetaService which is responsible
+ for ZooKeeperless HBase service discovery.</div>
+</div>
 <div class="col-first even-row-color class-summary class-summary-tab2">org.apache.hadoop.hbase.coprocessor.ColumnInterpreter&lt;T,<wbr>S,<wbr>P extends org.apache.hbase.thirdparty.com.google.protobuf.Message,<wbr>Q extends org.apache.hbase.thirdparty.com.google.protobuf.Message,<wbr>R extends org.apache.hbase.thirdparty.com.google.protobuf.Message&gt;</div>
 <div class="col-last even-row-color class-summary class-summary-tab2">
 <div class="block">Defines how value for specific column is interpreted and provides utility methods like compare,
diff --git a/apidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html b/apidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
index dc4b416fa8e..7f81988dc79 100644
--- a/apidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
+++ b/apidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
@@ -67,7 +67,11 @@ loadScripts(document, 'script');</script>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.ReadOnlyConfiguration</li>
 </ul>
 </li>
-<li class="circle">org.apache.hadoop.hbase.coprocessor.CoprocessorHost&lt;C,<wbr>E&gt;</li>
+<li class="circle">org.apache.hadoop.hbase.coprocessor.CoprocessorHost&lt;C,<wbr>E&gt;
+<ul>
+<li class="circle">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</li>
+</ul>
+</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.MetaTableMetrics (implements org.apache.hadoop.hbase.coprocessor.RegionCoprocessor)</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.MetricsCoprocessor</li>
 <li class="circle">org.apache.hadoop.hbase.shaded.protobuf.generated.MultiRowMutationProtos.MultiRowMutationService (implements org.apache.hbase.thirdparty.com.google.protobuf.Service)
@@ -110,8 +114,10 @@ loadScripts(document, 'script');</script>
 <h2 title="Interface Hierarchy">Interface Hierarchy</h2>
 <ul>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.BulkLoadObserver</li>
+<li class="circle">org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</li>
 <li class="circle">org.apache.hadoop.hbase.Coprocessor
 <ul>
+<li class="circle">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.MasterCoprocessor</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.RegionCoprocessor</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessor</li>
@@ -121,6 +127,7 @@ loadScripts(document, 'script');</script>
 </li>
 <li class="circle">org.apache.hadoop.hbase.CoprocessorEnvironment&lt;C&gt;
 <ul>
+<li class="circle">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment</li>
diff --git a/apidocs/org/apache/hadoop/hbase/coprocessor/package-use.html b/apidocs/org/apache/hadoop/hbase/coprocessor/package-use.html
index 12c096afd11..1fd1cf7131b 100644
--- a/apidocs/org/apache/hadoop/hbase/coprocessor/package-use.html
+++ b/apidocs/org/apache/hadoop/hbase/coprocessor/package-use.html
@@ -86,15 +86,17 @@ loadScripts(document, 'script');</script>
 <div class="summary-table two-column-summary">
 <div class="table-header col-first">Class</div>
 <div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><a href="class-use/CoprocessorHost.html#org.apache.hadoop.hbase">CoprocessorHost</a></div>
-<div class="col-last even-row-color">
+<div class="col-first even-row-color"><a href="class-use/ClientMetaCoprocessorHost.html#org.apache.hadoop.hbase">ClientMetaCoprocessorHost</a></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><a href="class-use/CoprocessorHost.html#org.apache.hadoop.hbase">CoprocessorHost</a></div>
+<div class="col-last odd-row-color">
 <div class="block">Provides the common setup framework and runtime services for coprocessor invocation from HBase
  services.</div>
 </div>
-<div class="col-first odd-row-color"><a href="class-use/MasterCoprocessor.html#org.apache.hadoop.hbase">MasterCoprocessor</a></div>
-<div class="col-last odd-row-color">&nbsp;</div>
-<div class="col-first even-row-color"><a href="class-use/RegionServerCoprocessor.html#org.apache.hadoop.hbase">RegionServerCoprocessor</a></div>
+<div class="col-first even-row-color"><a href="class-use/MasterCoprocessor.html#org.apache.hadoop.hbase">MasterCoprocessor</a></div>
 <div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><a href="class-use/RegionServerCoprocessor.html#org.apache.hadoop.hbase">RegionServerCoprocessor</a></div>
+<div class="col-last odd-row-color">&nbsp;</div>
 </div>
 </section>
 </li>
@@ -139,6 +141,20 @@ loadScripts(document, 'script');</script>
 <div class="col-last even-row-color">
 <div class="block">Coprocessors implement this interface to observe and mediate bulk load operations.</div>
 </div>
+<div class="col-first odd-row-color"><a href="class-use/ClientMetaCoprocessor.html#org.apache.hadoop.hbase.coprocessor">ClientMetaCoprocessor</a></div>
+<div class="col-last odd-row-color">&nbsp;</div>
+<div class="col-first even-row-color"><a href="class-use/ClientMetaCoprocessorEnvironment.html#org.apache.hadoop.hbase.coprocessor">ClientMetaCoprocessorEnvironment</a></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><a href="class-use/ClientMetaObserver.html#org.apache.hadoop.hbase.coprocessor">ClientMetaObserver</a></div>
+<div class="col-last odd-row-color">
+<div class="block">Defines coprocessor hooks for interacting operations for ClientMetaService which is responsible
+ for ZooKeeperless HBase service discovery.</div>
+</div>
+<div class="col-first even-row-color"><a href="class-use/CoprocessorHost.html#org.apache.hadoop.hbase.coprocessor">CoprocessorHost</a></div>
+<div class="col-last even-row-color">
+<div class="block">Provides the common setup framework and runtime services for coprocessor invocation from HBase
+ services.</div>
+</div>
 <div class="col-first odd-row-color"><a href="class-use/CoprocessorHost.ObserverGetter.html#org.apache.hadoop.hbase.coprocessor">CoprocessorHost.ObserverGetter</a></div>
 <div class="col-last odd-row-color">
 <div class="block">Implementations defined function to get an observer of type <code>O</code> from a coprocessor of
diff --git a/apidocs/org/apache/hadoop/hbase/package-use.html b/apidocs/org/apache/hadoop/hbase/package-use.html
index ef69d71da93..74adce0f970 100644
--- a/apidocs/org/apache/hadoop/hbase/package-use.html
+++ b/apidocs/org/apache/hadoop/hbase/package-use.html
@@ -876,27 +876,31 @@ service.</div>
 <div class="col-last even-row-color">
 <div class="block">All hbase specific IOExceptions should be subclasses of HBaseIOException</div>
 </div>
-<div class="col-first odd-row-color"><a href="class-use/MetaMutationAnnotation.html#org.apache.hadoop.hbase.coprocessor">MetaMutationAnnotation</a></div>
+<div class="col-first odd-row-color"><a href="class-use/HRegionLocation.html#org.apache.hadoop.hbase.coprocessor">HRegionLocation</a></div>
 <div class="col-last odd-row-color">
+<div class="block">Data structure to hold RegionInfo and the address for the hosting HRegionServer.</div>
+</div>
+<div class="col-first even-row-color"><a href="class-use/MetaMutationAnnotation.html#org.apache.hadoop.hbase.coprocessor">MetaMutationAnnotation</a></div>
+<div class="col-last even-row-color">
 <div class="block">The field or the parameter to which this annotation can be applied only when it holds mutations
  for hbase:meta table.</div>
 </div>
-<div class="col-first even-row-color"><a href="class-use/NamespaceDescriptor.html#org.apache.hadoop.hbase.coprocessor">NamespaceDescriptor</a></div>
-<div class="col-last even-row-color">
+<div class="col-first odd-row-color"><a href="class-use/NamespaceDescriptor.html#org.apache.hadoop.hbase.coprocessor">NamespaceDescriptor</a></div>
+<div class="col-last odd-row-color">
 <div class="block">Namespace POJO class.</div>
 </div>
-<div class="col-first odd-row-color"><a href="class-use/RawCellBuilder.html#org.apache.hadoop.hbase.coprocessor">RawCellBuilder</a></div>
-<div class="col-last odd-row-color">
+<div class="col-first even-row-color"><a href="class-use/RawCellBuilder.html#org.apache.hadoop.hbase.coprocessor">RawCellBuilder</a></div>
+<div class="col-last even-row-color">
 <div class="block">Allows creating a cell with <code>Tag</code> An instance of this type can be acquired by using
  RegionCoprocessorEnvironment#getCellBuilder (for prod code) and <code>RawCellBuilderFactory</code>
  (for unit tests).</div>
 </div>
-<div class="col-first even-row-color"><a href="class-use/ServerName.html#org.apache.hadoop.hbase.coprocessor">ServerName</a></div>
-<div class="col-last even-row-color">
+<div class="col-first odd-row-color"><a href="class-use/ServerName.html#org.apache.hadoop.hbase.coprocessor">ServerName</a></div>
+<div class="col-last odd-row-color">
 <div class="block">Name of a particular incarnation of an HBase Server.</div>
 </div>
-<div class="col-first odd-row-color"><a href="class-use/TableName.html#org.apache.hadoop.hbase.coprocessor">TableName</a></div>
-<div class="col-last odd-row-color">
+<div class="col-first even-row-color"><a href="class-use/TableName.html#org.apache.hadoop.hbase.coprocessor">TableName</a></div>
+<div class="col-last even-row-color">
 <div class="block">Immutable POJO class for representing a table name.</div>
 </div>
 </div>
diff --git a/apidocs/overview-tree.html b/apidocs/overview-tree.html
index b4107519d83..ae1dc7fafa8 100644
--- a/apidocs/overview-tree.html
+++ b/apidocs/overview-tree.html
@@ -881,6 +881,7 @@ loadScripts(document, 'script');</script>
 <li class="circle">org.apache.hadoop.hbase.client.CoprocessorDescriptorBuilder</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.CoprocessorHost&lt;C,<wbr>E&gt;
 <ul>
+<li class="circle">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost</li>
 <li class="circle">org.apache.hadoop.hbase.master.MasterCoprocessorHost</li>
 <li class="circle">org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost</li>
 <li class="circle">org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost</li>
@@ -3039,6 +3040,7 @@ loadScripts(document, 'script');</script>
 </li>
 <li class="circle">org.apache.hadoop.hbase.regionserver.ChangedReadersObserver</li>
 <li class="circle">org.apache.hadoop.hbase.client.backoff.ClientBackoffPolicy</li>
+<li class="circle">org.apache.hadoop.hbase.coprocessor.ClientMetaObserver</li>
 <li class="circle">org.apache.hadoop.hbase.ClientMetaTableAccessor.Visitor
 <ul>
 <li class="circle">org.apache.hadoop.hbase.ClientMetaTableAccessor.CloseableVisitor (also extends java.io.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Closeable.html" title="class or interface in java.io" class="external-link">Closeable</a>)</li>
@@ -3105,6 +3107,7 @@ loadScripts(document, 'script');</script>
 <li class="circle">org.apache.hadoop.hbase.CoordinatedStateManager</li>
 <li class="circle">org.apache.hadoop.hbase.Coprocessor
 <ul>
+<li class="circle">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessor</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.MasterCoprocessor</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.RegionCoprocessor</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessor</li>
@@ -3115,6 +3118,7 @@ loadScripts(document, 'script');</script>
 <li class="circle">org.apache.hadoop.hbase.client.CoprocessorDescriptor</li>
 <li class="circle">org.apache.hadoop.hbase.CoprocessorEnvironment&lt;C&gt;
 <ul>
+<li class="circle">org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorEnvironment</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment</li>
 <li class="circle">org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment</li>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/HBaseRpcServicesBase.html b/apidocs/src-html/org/apache/hadoop/hbase/HBaseRpcServicesBase.html
index 076a00b4d59..6fd0aca70c9 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/HBaseRpcServicesBase.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/HBaseRpcServicesBase.html
@@ -30,375 +30,449 @@
 <span class="source-line-no">017</span><span id="line-17"> */</span>
 <span class="source-line-no">018</span><span id="line-18">package org.apache.hadoop.hbase;</span>
 <span class="source-line-no">019</span><span id="line-19"></span>
-<span class="source-line-no">020</span><span id="line-20">import java.io.IOException;</span>
-<span class="source-line-no">021</span><span id="line-21">import java.lang.reflect.InvocationTargetException;</span>
-<span class="source-line-no">022</span><span id="line-22">import java.lang.reflect.Method;</span>
-<span class="source-line-no">023</span><span id="line-23">import java.net.BindException;</span>
-<span class="source-line-no">024</span><span id="line-24">import java.net.InetSocketAddress;</span>
-<span class="source-line-no">025</span><span id="line-25">import java.util.Collections;</span>
-<span class="source-line-no">026</span><span id="line-26">import java.util.List;</span>
-<span class="source-line-no">027</span><span id="line-27">import java.util.Optional;</span>
-<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.conf.Configuration;</span>
-<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.client.ConnectionUtils;</span>
-<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.conf.ConfigurationObserver;</span>
-<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.io.ByteBuffAllocator;</span>
-<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.ipc.HBaseRPCErrorHandler;</span>
-<span class="source-line-no">033</span><span id="line-33">import org.apache.hadoop.hbase.ipc.PriorityFunction;</span>
-<span class="source-line-no">034</span><span id="line-34">import org.apache.hadoop.hbase.ipc.QosPriority;</span>
-<span class="source-line-no">035</span><span id="line-35">import org.apache.hadoop.hbase.ipc.RpcScheduler;</span>
-<span class="source-line-no">036</span><span id="line-36">import org.apache.hadoop.hbase.ipc.RpcServer;</span>
-<span class="source-line-no">037</span><span id="line-37">import org.apache.hadoop.hbase.ipc.RpcServer.BlockingServiceAndInterface;</span>
-<span class="source-line-no">038</span><span id="line-38">import org.apache.hadoop.hbase.ipc.RpcServerFactory;</span>
-<span class="source-line-no">039</span><span id="line-39">import org.apache.hadoop.hbase.ipc.RpcServerInterface;</span>
-<span class="source-line-no">040</span><span id="line-40">import org.apache.hadoop.hbase.namequeues.NamedQueuePayload;</span>
-<span class="source-line-no">041</span><span id="line-41">import org.apache.hadoop.hbase.namequeues.NamedQueueRecorder;</span>
-<span class="source-line-no">042</span><span id="line-42">import org.apache.hadoop.hbase.namequeues.RpcLogDetails;</span>
-<span class="source-line-no">043</span><span id="line-43">import org.apache.hadoop.hbase.namequeues.request.NamedQueueGetRequest;</span>
-<span class="source-line-no">044</span><span id="line-44">import org.apache.hadoop.hbase.namequeues.response.NamedQueueGetResponse;</span>
-<span class="source-line-no">045</span><span id="line-45">import org.apache.hadoop.hbase.net.Address;</span>
-<span class="source-line-no">046</span><span id="line-46">import org.apache.hadoop.hbase.regionserver.RpcSchedulerFactory;</span>
-<span class="source-line-no">047</span><span id="line-47">import org.apache.hadoop.hbase.security.User;</span>
-<span class="source-line-no">048</span><span id="line-48">import org.apache.hadoop.hbase.security.access.AccessChecker;</span>
-<span class="source-line-no">049</span><span id="line-49">import org.apache.hadoop.hbase.security.access.NoopAccessChecker;</span>
-<span class="source-line-no">050</span><span id="line-50">import org.apache.hadoop.hbase.security.access.Permission;</span>
-<span class="source-line-no">051</span><span id="line-51">import org.apache.hadoop.hbase.security.access.ZKPermissionWatcher;</span>
-<span class="source-line-no">052</span><span id="line-52">import org.apache.hadoop.hbase.util.DNS;</span>
-<span class="source-line-no">053</span><span id="line-53">import org.apache.hadoop.hbase.util.OOMEChecker;</span>
-<span class="source-line-no">054</span><span id="line-54">import org.apache.hadoop.hbase.util.ReservoirSample;</span>
-<span class="source-line-no">055</span><span id="line-55">import org.apache.hadoop.hbase.zookeeper.ZKWatcher;</span>
-<span class="source-line-no">056</span><span id="line-56">import org.apache.yetus.audience.InterfaceAudience;</span>
-<span class="source-line-no">057</span><span id="line-57">import org.apache.zookeeper.KeeperException;</span>
-<span class="source-line-no">058</span><span id="line-58">import org.slf4j.Logger;</span>
-<span class="source-line-no">059</span><span id="line-59">import org.slf4j.LoggerFactory;</span>
-<span class="source-line-no">060</span><span id="line-60"></span>
-<span class="source-line-no">061</span><span id="line-61">import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;</span>
-<span class="source-line-no">062</span><span id="line-62">import org.apache.hbase.thirdparty.com.google.protobuf.Message;</span>
-<span class="source-line-no">063</span><span id="line-63">import org.apache.hbase.thirdparty.com.google.protobuf.RpcController;</span>
-<span class="source-line-no">064</span><span id="line-64">import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;</span>
-<span class="source-line-no">065</span><span id="line-65"></span>
-<span class="source-line-no">066</span><span id="line-66">import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;</span>
-<span class="source-line-no">067</span><span id="line-67">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService;</span>
-<span class="source-line-no">068</span><span id="line-68">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearSlowLogResponseRequest;</span>
-<span class="source-line-no">069</span><span id="line-69">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearSlowLogResponses;</span>
-<span class="source-line-no">070</span><span id="line-70">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.SlowLogResponseRequest;</span>
-<span class="source-line-no">071</span><span id="line-71">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.SlowLogResponses;</span>
-<span class="source-line-no">072</span><span id="line-72">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.UpdateConfigurationRequest;</span>
-<span class="source-line-no">073</span><span id="line-73">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.UpdateConfigurationResponse;</span>
-<span class="source-line-no">074</span><span id="line-74">import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;</span>
-<span class="source-line-no">075</span><span id="line-75">import org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader;</span>
-<span class="source-line-no">076</span><span id="line-76">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.ClientMetaService;</span>
-<span class="source-line-no">077</span><span id="line-77">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetActiveMasterRequest;</span>
-<span class="source-line-no">078</span><span id="line-78">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetActiveMasterResponse;</span>
-<span class="source-line-no">079</span><span id="line-79">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetBootstrapNodesRequest;</span>
-<span class="source-line-no">080</span><span id="line-80">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetBootstrapNodesResponse;</span>
-<span class="source-line-no">081</span><span id="line-81">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetClusterIdRequest;</span>
-<span class="source-line-no">082</span><span id="line-82">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetClusterIdResponse;</span>
-<span class="source-line-no">083</span><span id="line-83">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMastersRequest;</span>
-<span class="source-line-no">084</span><span id="line-84">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMastersResponse;</span>
-<span class="source-line-no">085</span><span id="line-85">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMastersResponseEntry;</span>
-<span class="source-line-no">086</span><span id="line-86">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMetaRegionLocationsRequest;</span>
-<span class="source-line-no">087</span><span id="line-87">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMetaRegionLocationsResponse;</span>
-<span class="source-line-no">088</span><span id="line-88">import org.apache.hadoop.hbase.shaded.protobuf.generated.TooSlowLog.SlowLogPayload;</span>
-<span class="source-line-no">089</span><span id="line-89"></span>
-<span class="source-line-no">090</span><span id="line-90">/**</span>
-<span class="source-line-no">091</span><span id="line-91"> * Base class for Master and RegionServer RpcServices.</span>
-<span class="source-line-no">092</span><span id="line-92"> */</span>
-<span class="source-line-no">093</span><span id="line-93">@InterfaceAudience.Private</span>
-<span class="source-line-no">094</span><span id="line-94">public abstract class HBaseRpcServicesBase&lt;S extends HBaseServerBase&lt;?&gt;&gt;</span>
-<span class="source-line-no">095</span><span id="line-95">  implements ClientMetaService.BlockingInterface, AdminService.BlockingInterface,</span>
-<span class="source-line-no">096</span><span id="line-96">  HBaseRPCErrorHandler, PriorityFunction, ConfigurationObserver {</span>
-<span class="source-line-no">097</span><span id="line-97"></span>
-<span class="source-line-no">098</span><span id="line-98">  private static final Logger LOG = LoggerFactory.getLogger(HBaseRpcServicesBase.class);</span>
-<span class="source-line-no">099</span><span id="line-99"></span>
-<span class="source-line-no">100</span><span id="line-100">  public static final String CLIENT_BOOTSTRAP_NODE_LIMIT = "hbase.client.bootstrap.node.limit";</span>
+<span class="source-line-no">020</span><span id="line-20">import com.google.errorprone.annotations.RestrictedApi;</span>
+<span class="source-line-no">021</span><span id="line-21">import java.io.IOException;</span>
+<span class="source-line-no">022</span><span id="line-22">import java.lang.reflect.InvocationTargetException;</span>
+<span class="source-line-no">023</span><span id="line-23">import java.lang.reflect.Method;</span>
+<span class="source-line-no">024</span><span id="line-24">import java.net.BindException;</span>
+<span class="source-line-no">025</span><span id="line-25">import java.net.InetSocketAddress;</span>
+<span class="source-line-no">026</span><span id="line-26">import java.util.Collections;</span>
+<span class="source-line-no">027</span><span id="line-27">import java.util.LinkedHashMap;</span>
+<span class="source-line-no">028</span><span id="line-28">import java.util.List;</span>
+<span class="source-line-no">029</span><span id="line-29">import java.util.Map;</span>
+<span class="source-line-no">030</span><span id="line-30">import java.util.Optional;</span>
+<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.conf.Configuration;</span>
+<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.client.ConnectionUtils;</span>
+<span class="source-line-no">033</span><span id="line-33">import org.apache.hadoop.hbase.conf.ConfigurationObserver;</span>
+<span class="source-line-no">034</span><span id="line-34">import org.apache.hadoop.hbase.coprocessor.ClientMetaCoprocessorHost;</span>
+<span class="source-line-no">035</span><span id="line-35">import org.apache.hadoop.hbase.io.ByteBuffAllocator;</span>
+<span class="source-line-no">036</span><span id="line-36">import org.apache.hadoop.hbase.ipc.HBaseRPCErrorHandler;</span>
+<span class="source-line-no">037</span><span id="line-37">import org.apache.hadoop.hbase.ipc.PriorityFunction;</span>
+<span class="source-line-no">038</span><span id="line-38">import org.apache.hadoop.hbase.ipc.QosPriority;</span>
+<span class="source-line-no">039</span><span id="line-39">import org.apache.hadoop.hbase.ipc.RpcScheduler;</span>
+<span class="source-line-no">040</span><span id="line-40">import org.apache.hadoop.hbase.ipc.RpcServer;</span>
+<span class="source-line-no">041</span><span id="line-41">import org.apache.hadoop.hbase.ipc.RpcServer.BlockingServiceAndInterface;</span>
+<span class="source-line-no">042</span><span id="line-42">import org.apache.hadoop.hbase.ipc.RpcServerFactory;</span>
+<span class="source-line-no">043</span><span id="line-43">import org.apache.hadoop.hbase.ipc.RpcServerInterface;</span>
+<span class="source-line-no">044</span><span id="line-44">import org.apache.hadoop.hbase.namequeues.NamedQueuePayload;</span>
+<span class="source-line-no">045</span><span id="line-45">import org.apache.hadoop.hbase.namequeues.NamedQueueRecorder;</span>
+<span class="source-line-no">046</span><span id="line-46">import org.apache.hadoop.hbase.namequeues.RpcLogDetails;</span>
+<span class="source-line-no">047</span><span id="line-47">import org.apache.hadoop.hbase.namequeues.request.NamedQueueGetRequest;</span>
+<span class="source-line-no">048</span><span id="line-48">import org.apache.hadoop.hbase.namequeues.response.NamedQueueGetResponse;</span>
+<span class="source-line-no">049</span><span id="line-49">import org.apache.hadoop.hbase.net.Address;</span>
+<span class="source-line-no">050</span><span id="line-50">import org.apache.hadoop.hbase.regionserver.RpcSchedulerFactory;</span>
+<span class="source-line-no">051</span><span id="line-51">import org.apache.hadoop.hbase.security.User;</span>
+<span class="source-line-no">052</span><span id="line-52">import org.apache.hadoop.hbase.security.access.AccessChecker;</span>
+<span class="source-line-no">053</span><span id="line-53">import org.apache.hadoop.hbase.security.access.NoopAccessChecker;</span>
+<span class="source-line-no">054</span><span id="line-54">import org.apache.hadoop.hbase.security.access.Permission;</span>
+<span class="source-line-no">055</span><span id="line-55">import org.apache.hadoop.hbase.security.access.ZKPermissionWatcher;</span>
+<span class="source-line-no">056</span><span id="line-56">import org.apache.hadoop.hbase.util.DNS;</span>
+<span class="source-line-no">057</span><span id="line-57">import org.apache.hadoop.hbase.util.OOMEChecker;</span>
+<span class="source-line-no">058</span><span id="line-58">import org.apache.hadoop.hbase.util.ReservoirSample;</span>
+<span class="source-line-no">059</span><span id="line-59">import org.apache.hadoop.hbase.zookeeper.ZKWatcher;</span>
+<span class="source-line-no">060</span><span id="line-60">import org.apache.yetus.audience.InterfaceAudience;</span>
+<span class="source-line-no">061</span><span id="line-61">import org.apache.zookeeper.KeeperException;</span>
+<span class="source-line-no">062</span><span id="line-62">import org.slf4j.Logger;</span>
+<span class="source-line-no">063</span><span id="line-63">import org.slf4j.LoggerFactory;</span>
+<span class="source-line-no">064</span><span id="line-64"></span>
+<span class="source-line-no">065</span><span id="line-65">import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;</span>
+<span class="source-line-no">066</span><span id="line-66">import org.apache.hbase.thirdparty.com.google.protobuf.Message;</span>
+<span class="source-line-no">067</span><span id="line-67">import org.apache.hbase.thirdparty.com.google.protobuf.RpcController;</span>
+<span class="source-line-no">068</span><span id="line-68">import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;</span>
+<span class="source-line-no">069</span><span id="line-69"></span>
+<span class="source-line-no">070</span><span id="line-70">import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;</span>
+<span class="source-line-no">071</span><span id="line-71">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService;</span>
+<span class="source-line-no">072</span><span id="line-72">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearSlowLogResponseRequest;</span>
+<span class="source-line-no">073</span><span id="line-73">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ClearSlowLogResponses;</span>
+<span class="source-line-no">074</span><span id="line-74">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.SlowLogResponseRequest;</span>
+<span class="source-line-no">075</span><span id="line-75">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.SlowLogResponses;</span>
+<span class="source-line-no">076</span><span id="line-76">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.UpdateConfigurationRequest;</span>
+<span class="source-line-no">077</span><span id="line-77">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.UpdateConfigurationResponse;</span>
+<span class="source-line-no">078</span><span id="line-78">import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;</span>
+<span class="source-line-no">079</span><span id="line-79">import org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader;</span>
+<span class="source-line-no">080</span><span id="line-80">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.ClientMetaService;</span>
+<span class="source-line-no">081</span><span id="line-81">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetActiveMasterRequest;</span>
+<span class="source-line-no">082</span><span id="line-82">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetActiveMasterResponse;</span>
+<span class="source-line-no">083</span><span id="line-83">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetBootstrapNodesRequest;</span>
+<span class="source-line-no">084</span><span id="line-84">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetBootstrapNodesResponse;</span>
+<span class="source-line-no">085</span><span id="line-85">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetClusterIdRequest;</span>
+<span class="source-line-no">086</span><span id="line-86">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetClusterIdResponse;</span>
+<span class="source-line-no">087</span><span id="line-87">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMastersRequest;</span>
+<span class="source-line-no">088</span><span id="line-88">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMastersResponse;</span>
+<span class="source-line-no">089</span><span id="line-89">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMastersResponseEntry;</span>
+<span class="source-line-no">090</span><span id="line-90">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMetaRegionLocationsRequest;</span>
+<span class="source-line-no">091</span><span id="line-91">import org.apache.hadoop.hbase.shaded.protobuf.generated.RegistryProtos.GetMetaRegionLocationsResponse;</span>
+<span class="source-line-no">092</span><span id="line-92">import org.apache.hadoop.hbase.shaded.protobuf.generated.TooSlowLog.SlowLogPayload;</span>
+<span class="source-line-no">093</span><span id="line-93"></span>
+<span class="source-line-no">094</span><span id="line-94">/**</span>
+<span class="source-line-no">095</span><span id="line-95"> * Base class for Master and RegionServer RpcServices.</span>
+<span class="source-line-no">096</span><span id="line-96"> */</span>
+<span class="source-line-no">097</span><span id="line-97">@InterfaceAudience.Private</span>
+<span class="source-line-no">098</span><span id="line-98">public abstract class HBaseRpcServicesBase&lt;S extends HBaseServerBase&lt;?&gt;&gt;</span>
+<span class="source-line-no">099</span><span id="line-99">  implements ClientMetaService.BlockingInterface, AdminService.BlockingInterface,</span>
+<span class="source-line-no">100</span><span id="line-100">  HBaseRPCErrorHandler, PriorityFunction, ConfigurationObserver {</span>
 <span class="source-line-no">101</span><span id="line-101"></span>
-<span class="source-line-no">102</span><span id="line-102">  public static final int DEFAULT_CLIENT_BOOTSTRAP_NODE_LIMIT = 10;</span>
+<span class="source-line-no">102</span><span id="line-102">  private static final Logger LOG = LoggerFactory.getLogger(HBaseRpcServicesBase.class);</span>
 <span class="source-line-no">103</span><span id="line-103"></span>
-<span class="source-line-no">104</span><span id="line-104">  protected final S server;</span>
+<span class="source-line-no">104</span><span id="line-104">  public static final String CLIENT_BOOTSTRAP_NODE_LIMIT = "hbase.client.bootstrap.node.limit";</span>
 <span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106">  // Server to handle client requests.</span>
-<span class="source-line-no">107</span><span id="line-107">  protected final RpcServer rpcServer;</span>
-<span class="source-line-no">108</span><span id="line-108"></span>
-<span class="source-line-no">109</span><span id="line-109">  private final InetSocketAddress isa;</span>
-<span class="source-line-no">110</span><span id="line-110"></span>
-<span class="source-line-no">111</span><span id="line-111">  protected final PriorityFunction priority;</span>
+<span class="source-line-no">106</span><span id="line-106">  public static final int DEFAULT_CLIENT_BOOTSTRAP_NODE_LIMIT = 10;</span>
+<span class="source-line-no">107</span><span id="line-107"></span>
+<span class="source-line-no">108</span><span id="line-108">  protected final S server;</span>
+<span class="source-line-no">109</span><span id="line-109"></span>
+<span class="source-line-no">110</span><span id="line-110">  // Server to handle client requests.</span>
+<span class="source-line-no">111</span><span id="line-111">  protected final RpcServer rpcServer;</span>
 <span class="source-line-no">112</span><span id="line-112"></span>
-<span class="source-line-no">113</span><span id="line-113">  private AccessChecker accessChecker;</span>
+<span class="source-line-no">113</span><span id="line-113">  private final InetSocketAddress isa;</span>
 <span class="source-line-no">114</span><span id="line-114"></span>
-<span class="source-line-no">115</span><span id="line-115">  private ZKPermissionWatcher zkPermissionWatcher;</span>
+<span class="source-line-no">115</span><span id="line-115">  protected final PriorityFunction priority;</span>
 <span class="source-line-no">116</span><span id="line-116"></span>
-<span class="source-line-no">117</span><span id="line-117">  protected HBaseRpcServicesBase(S server, String processName) throws IOException {</span>
-<span class="source-line-no">118</span><span id="line-118">    this.server = server;</span>
-<span class="source-line-no">119</span><span id="line-119">    Configuration conf = server.getConfiguration();</span>
-<span class="source-line-no">120</span><span id="line-120">    final RpcSchedulerFactory rpcSchedulerFactory;</span>
-<span class="source-line-no">121</span><span id="line-121">    try {</span>
-<span class="source-line-no">122</span><span id="line-122">      rpcSchedulerFactory = getRpcSchedulerFactoryClass(conf).asSubclass(RpcSchedulerFactory.class)</span>
-<span class="source-line-no">123</span><span id="line-123">        .getDeclaredConstructor().newInstance();</span>
-<span class="source-line-no">124</span><span id="line-124">    } catch (NoSuchMethodException | InvocationTargetException | InstantiationException</span>
-<span class="source-line-no">125</span><span id="line-125">      | IllegalAccessException e) {</span>
-<span class="source-line-no">126</span><span id="line-126">      throw new IllegalArgumentException(e);</span>
-<span class="source-line-no">127</span><span id="line-127">    }</span>
-<span class="source-line-no">128</span><span id="line-128">    String hostname = DNS.getHostname(conf, getDNSServerType());</span>
-<span class="source-line-no">129</span><span id="line-129">    int port = conf.getInt(getPortConfigName(), getDefaultPort());</span>
-<span class="source-line-no">130</span><span id="line-130">    // Creation of a HSA will force a resolve.</span>
-<span class="source-line-no">131</span><span id="line-131">    final InetSocketAddress initialIsa = new InetSocketAddress(hostname, port);</span>
-<span class="source-line-no">132</span><span id="line-132">    final InetSocketAddress bindAddress = new InetSocketAddress(getHostname(conf, hostname), port);</span>
-<span class="source-line-no">133</span><span id="line-133">    if (initialIsa.getAddress() == null) {</span>
-<span class="source-line-no">134</span><span id="line-134">      throw new IllegalArgumentException("Failed resolve of " + initialIsa);</span>
-<span class="source-line-no">135</span><span id="line-135">    }</span>
-<span class="source-line-no">136</span><span id="line-136">    priority = createPriority();</span>
-<span class="source-line-no">137</span><span id="line-137">    // Using Address means we don't get the IP too. Shorten it more even to just the host name</span>
-<span class="source-line-no">138</span><span id="line-138">    // w/o the domain.</span>
-<span class="source-line-no">139</span><span id="line-139">    final String name = processName + "/"</span>
-<span class="source-line-no">140</span><span id="line-140">      + Address.fromParts(initialIsa.getHostName(), initialIsa.getPort()).toStringWithoutDomain();</span>
-<span class="source-line-no">141</span><span id="line-141">    server.setName(name);</span>
-<span class="source-line-no">142</span><span id="line-142">    // Set how many times to retry talking to another server over Connection.</span>
-<span class="source-line-no">143</span><span id="line-143">    ConnectionUtils.setServerSideHConnectionRetriesConfig(conf, name, LOG);</span>
-<span class="source-line-no">144</span><span id="line-144">    boolean reservoirEnabled =</span>
-<span class="source-line-no">145</span><span id="line-145">      conf.getBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, defaultReservoirEnabled());</span>
-<span class="source-line-no">146</span><span id="line-146">    try {</span>
-<span class="source-line-no">147</span><span id="line-147">      // use final bindAddress for this server.</span>
-<span class="source-line-no">148</span><span id="line-148">      rpcServer = RpcServerFactory.createRpcServer(server, name, getServices(), bindAddress, conf,</span>
-<span class="source-line-no">149</span><span id="line-149">        rpcSchedulerFactory.create(conf, this, server), reservoirEnabled);</span>
-<span class="source-line-no">150</span><span id="line-150">    } catch (BindException be) {</span>
-<span class="source-line-no">151</span><span id="line-151">      throw new IOException(be.getMessage() + ". To switch ports use the '" + getPortConfigName()</span>
-<span class="source-line-no">152</span><span id="line-152">        + "' configuration property.", be.getCause() != null ? be.getCause() : be);</span>
-<span class="source-line-no">153</span><span id="line-153">    }</span>
-<span class="source-line-no">154</span><span id="line-154">    final InetSocketAddress address = rpcServer.getListenerAddress();</span>
-<span class="source-line-no">155</span><span id="line-155">    if (address == null) {</span>
-<span class="source-line-no">156</span><span id="line-156">      throw new IOException("Listener channel is closed");</span>
-<span class="source-line-no">157</span><span id="line-157">    }</span>
-<span class="source-line-no">158</span><span id="line-158">    // Set our address, however we need the final port that was given to rpcServer</span>
-<span class="source-line-no">159</span><span id="line-159">    isa = new InetSocketAddress(initialIsa.getHostName(), address.getPort());</span>
-<span class="source-line-no">160</span><span id="line-160">    rpcServer.setErrorHandler(this);</span>
-<span class="source-line-no">161</span><span id="line-161">  }</span>
-<span class="source-line-no">162</span><span id="line-162"></span>
-<span class="source-line-no">163</span><span id="line-163">  protected abstract boolean defaultReservoirEnabled();</span>
-<span class="source-line-no">164</span><span id="line-164"></span>
-<span class="source-line-no">165</span><span id="line-165">  protected abstract DNS.ServerType getDNSServerType();</span>
-<span class="source-line-no">166</span><span id="line-166"></span>
-<span class="source-line-no">167</span><span id="line-167">  protected abstract String getHostname(Configuration conf, String defaultHostname);</span>
-<span class="source-line-no">168</span><span id="line-168"></span>
-<span class="source-line-no">169</span><span id="line-169">  protected abstract String getPortConfigName();</span>
+<span class="source-line-no">117</span><span id="line-117">  private ClientMetaCoprocessorHost clientMetaCoprocessorHost;</span>
+<span class="source-line-no">118</span><span id="line-118"></span>
+<span class="source-line-no">119</span><span id="line-119">  private AccessChecker accessChecker;</span>
+<span class="source-line-no">120</span><span id="line-120"></span>
+<span class="source-line-no">121</span><span id="line-121">  private ZKPermissionWatcher zkPermissionWatcher;</span>
+<span class="source-line-no">122</span><span id="line-122"></span>
+<span class="source-line-no">123</span><span id="line-123">  protected HBaseRpcServicesBase(S server, String processName) throws IOException {</span>
+<span class="source-line-no">124</span><span id="line-124">    this.server = server;</span>
+<span class="source-line-no">125</span><span id="line-125">    Configuration conf = server.getConfiguration();</span>
+<span class="source-line-no">126</span><span id="line-126">    final RpcSchedulerFactory rpcSchedulerFactory;</span>
+<span class="source-line-no">127</span><span id="line-127">    try {</span>
+<span class="source-line-no">128</span><span id="line-128">      rpcSchedulerFactory = getRpcSchedulerFactoryClass(conf).asSubclass(RpcSchedulerFactory.class)</span>
+<span class="source-line-no">129</span><span id="line-129">        .getDeclaredConstructor().newInstance();</span>
+<span class="source-line-no">130</span><span id="line-130">    } catch (NoSuchMethodException | InvocationTargetException | InstantiationException</span>
+<span class="source-line-no">131</span><span id="line-131">      | IllegalAccessException e) {</span>
+<span class="source-line-no">132</span><span id="line-132">      throw new IllegalArgumentException(e);</span>
+<span class="source-line-no">133</span><span id="line-133">    }</span>
+<span class="source-line-no">134</span><span id="line-134">    String hostname = DNS.getHostname(conf, getDNSServerType());</span>
+<span class="source-line-no">135</span><span id="line-135">    int port = conf.getInt(getPortConfigName(), getDefaultPort());</span>
+<span class="source-line-no">136</span><span id="line-136">    // Creation of a HSA will force a resolve.</span>
+<span class="source-line-no">137</span><span id="line-137">    final InetSocketAddress initialIsa = new InetSocketAddress(hostname, port);</span>
+<span class="source-line-no">138</span><span id="line-138">    final InetSocketAddress bindAddress = new InetSocketAddress(getHostname(conf, hostname), port);</span>
+<span class="source-line-no">139</span><span id="line-139">    if (initialIsa.getAddress() == null) {</span>
+<span class="source-line-no">140</span><span id="line-140">      throw new IllegalArgumentException("Failed resolve of " + initialIsa);</span>
+<span class="source-line-no">141</span><span id="line-141">    }</span>
+<span class="source-line-no">142</span><span id="line-142">    priority = createPriority();</span>
+<span class="source-line-no">143</span><span id="line-143">    // Using Address means we don't get the IP too. Shorten it more even to just the host name</span>
+<span class="source-line-no">144</span><span id="line-144">    // w/o the domain.</span>
+<span class="source-line-no">145</span><span id="line-145">    final String name = processName + "/"</span>
+<span class="source-line-no">146</span><span id="line-146">      + Address.fromParts(initialIsa.getHostName(), initialIsa.getPort()).toStringWithoutDomain();</span>
+<span class="source-line-no">147</span><span id="line-147">    server.setName(name);</span>
+<span class="source-line-no">148</span><span id="line-148">    // Set how many times to retry talking to another server over Connection.</span>
+<span class="source-line-no">149</span><span id="line-149">    ConnectionUtils.setServerSideHConnectionRetriesConfig(conf, name, LOG);</span>
+<span class="source-line-no">150</span><span id="line-150">    boolean reservoirEnabled =</span>
+<span class="source-line-no">151</span><span id="line-151">      conf.getBoolean(ByteBuffAllocator.ALLOCATOR_POOL_ENABLED_KEY, defaultReservoirEnabled());</span>
+<span class="source-line-no">152</span><span id="line-152">    try {</span>
+<span class="source-line-no">153</span><span id="line-153">      // use final bindAddress for this server.</span>
+<span class="source-line-no">154</span><span id="line-154">      rpcServer = RpcServerFactory.createRpcServer(server, name, getServices(), bindAddress, conf,</span>
+<span class="source-line-no">155</span><span id="line-155">        rpcSchedulerFactory.create(conf, this, server), reservoirEnabled);</span>
+<span class="source-line-no">156</span><span id="line-156">    } catch (BindException be) {</span>
+<span class="source-line-no">157</span><span id="line-157">      throw new IOException(be.getMessage() + ". To switch ports use the '" + getPortConfigName()</span>
+<span class="source-line-no">158</span><span id="line-158">        + "' configuration property.", be.getCause() != null ? be.getCause() : be);</span>
+<span class="source-line-no">159</span><span id="line-159">    }</span>
+<span class="source-line-no">160</span><span id="line-160">    final InetSocketAddress address = rpcServer.getListenerAddress();</span>
+<span class="source-line-no">161</span><span id="line-161">    if (address == null) {</span>
+<span class="source-line-no">162</span><span id="line-162">      throw new IOException("Listener channel is closed");</span>
+<span class="source-line-no">163</span><span id="line-163">    }</span>
+<span class="source-line-no">164</span><span id="line-164">    // Set our address, however we need the final port that was given to rpcServer</span>
+<span class="source-line-no">165</span><span id="line-165">    isa = new InetSocketAddress(initialIsa.getHostName(), address.getPort());</span>
+<span class="source-line-no">166</span><span id="line-166">    rpcServer.setErrorHandler(this);</span>
+<span class="source-line-no">167</span><span id="line-167"></span>
+<span class="source-line-no">168</span><span id="line-168">    clientMetaCoprocessorHost = new ClientMetaCoprocessorHost(conf);</span>
+<span class="source-line-no">169</span><span id="line-169">  }</span>
 <span class="source-line-no">170</span><span id="line-170"></span>
-<span class="source-line-no">171</span><span id="line-171">  protected abstract int getDefaultPort();</span>
+<span class="source-line-no">171</span><span id="line-171">  protected abstract boolean defaultReservoirEnabled();</span>
 <span class="source-line-no">172</span><span id="line-172"></span>
-<span class="source-line-no">173</span><span id="line-173">  protected abstract PriorityFunction createPriority();</span>
+<span class="source-line-no">173</span><span id="line-173">  protected abstract DNS.ServerType getDNSServerType();</span>
 <span class="source-line-no">174</span><span id="line-174"></span>
-<span class="source-line-no">175</span><span id="line-175">  protected abstract Class&lt;?&gt; getRpcSchedulerFactoryClass(Configuration conf);</span>
+<span class="source-line-no">175</span><span id="line-175">  protected abstract String getHostname(Configuration conf, String defaultHostname);</span>
 <span class="source-line-no">176</span><span id="line-176"></span>
-<span class="source-line-no">177</span><span id="line-177">  protected abstract List&lt;BlockingServiceAndInterface&gt; getServices();</span>
+<span class="source-line-no">177</span><span id="line-177">  protected abstract String getPortConfigName();</span>
 <span class="source-line-no">178</span><span id="line-178"></span>
-<span class="source-line-no">179</span><span id="line-179">  protected final void internalStart(ZKWatcher zkWatcher) {</span>
-<span class="source-line-no">180</span><span id="line-180">    if (AccessChecker.isAuthorizationSupported(getConfiguration())) {</span>
-<span class="source-line-no">181</span><span id="line-181">      accessChecker = new AccessChecker(getConfiguration());</span>
-<span class="source-line-no">182</span><span id="line-182">    } else {</span>
-<span class="source-line-no">183</span><span id="line-183">      accessChecker = new NoopAccessChecker(getConfiguration());</span>
-<span class="source-line-no">184</span><span id="line-184">    }</span>
-<span class="source-line-no">185</span><span id="line-185">    zkPermissionWatcher =</span>
-<span class="source-line-no">186</span><span id="line-186">      new ZKPermissionWatcher(zkWatcher, accessChecker.getAuthManager(), getConfiguration());</span>
-<span class="source-line-no">187</span><span id="line-187">    try {</span>
-<span class="source-line-no">188</span><span id="line-188">      zkPermissionWatcher.start();</span>
-<span class="source-line-no">189</span><span id="line-189">    } catch (KeeperException e) {</span>
-<span class="source-line-no">190</span><span id="line-190">      LOG.error("ZooKeeper permission watcher initialization failed", e);</span>
-<span class="source-line-no">191</span><span id="line-191">    }</span>
-<span class="source-line-no">192</span><span id="line-192">    rpcServer.start();</span>
-<span class="source-line-no">193</span><span id="line-193">  }</span>
-<span class="source-line-no">194</span><span id="line-194"></span>
-<span class="source-line-no">195</span><span id="line-195">  protected final void requirePermission(String request, Permission.Action perm)</span>
-<span class="source-line-no">196</span><span id="line-196">    throws IOException {</span>
-<span class="source-line-no">197</span><span id="line-197">    if (accessChecker != null) {</span>
-<span class="source-line-no">198</span><span id="line-198">      accessChecker.requirePermission(RpcServer.getRequestUser().orElse(null), request, null, perm);</span>
+<span class="source-line-no">179</span><span id="line-179">  protected abstract int getDefaultPort();</span>
+<span class="source-line-no">180</span><span id="line-180"></span>
+<span class="source-line-no">181</span><span id="line-181">  protected abstract PriorityFunction createPriority();</span>
+<span class="source-line-no">182</span><span id="line-182"></span>
+<span class="source-line-no">183</span><span id="line-183">  protected abstract Class&lt;?&gt; getRpcSchedulerFactoryClass(Configuration conf);</span>
+<span class="source-line-no">184</span><span id="line-184"></span>
+<span class="source-line-no">185</span><span id="line-185">  protected abstract List&lt;BlockingServiceAndInterface&gt; getServices();</span>
+<span class="source-line-no">186</span><span id="line-186"></span>
+<span class="source-line-no">187</span><span id="line-187">  protected final void internalStart(ZKWatcher zkWatcher) {</span>
+<span class="source-line-no">188</span><span id="line-188">    if (AccessChecker.isAuthorizationSupported(getConfiguration())) {</span>
+<span class="source-line-no">189</span><span id="line-189">      accessChecker = new AccessChecker(getConfiguration());</span>
+<span class="source-line-no">190</span><span id="line-190">    } else {</span>
+<span class="source-line-no">191</span><span id="line-191">      accessChecker = new NoopAccessChecker(getConfiguration());</span>
+<span class="source-line-no">192</span><span id="line-192">    }</span>
+<span class="source-line-no">193</span><span id="line-193">    zkPermissionWatcher =</span>
+<span class="source-line-no">194</span><span id="line-194">      new ZKPermissionWatcher(zkWatcher, accessChecker.getAuthManager(), getConfiguration());</span>
+<span class="source-line-no">195</span><span id="line-195">    try {</span>
+<span class="source-line-no">196</span><span id="line-196">      zkPermissionWatcher.start();</span>
+<span class="source-line-no">197</span><span id="line-197">    } catch (KeeperException e) {</span>
+<span class="source-line-no">198</span><span id="line-198">      LOG.error("ZooKeeper permission watcher initialization failed", e);</span>
 <span class="source-line-no">199</span><span id="line-199">    }</span>
-<span class="source-line-no">200</span><span id="line-200">  }</span>
-<span class="source-line-no">201</span><span id="line-201"></span>
-<span class="source-line-no">202</span><span id="line-202">  public AccessChecker getAccessChecker() {</span>
-<span class="source-line-no">203</span><span id="line-203">    return accessChecker;</span>
-<span class="source-line-no">204</span><span id="line-204">  }</span>
-<span class="source-line-no">205</span><span id="line-205"></span>
-<span class="source-line-no">206</span><span id="line-206">  public ZKPermissionWatcher getZkPermissionWatcher() {</span>
-<span class="source-line-no">207</span><span id="line-207">    return zkPermissionWatcher;</span>
+<span class="source-line-no">200</span><span id="line-200">    rpcServer.start();</span>
+<span class="source-line-no">201</span><span id="line-201">  }</span>
+<span class="source-line-no">202</span><span id="line-202"></span>
+<span class="source-line-no">203</span><span id="line-203">  protected final void requirePermission(String request, Permission.Action perm)</span>
+<span class="source-line-no">204</span><span id="line-204">    throws IOException {</span>
+<span class="source-line-no">205</span><span id="line-205">    if (accessChecker != null) {</span>
+<span class="source-line-no">206</span><span id="line-206">      accessChecker.requirePermission(RpcServer.getRequestUser().orElse(null), request, null, perm);</span>
+<span class="source-line-no">207</span><span id="line-207">    }</span>
 <span class="source-line-no">208</span><span id="line-208">  }</span>
 <span class="source-line-no">209</span><span id="line-209"></span>
-<span class="source-line-no">210</span><span id="line-210">  protected final void internalStop() {</span>
-<span class="source-line-no">211</span><span id="line-211">    if (zkPermissionWatcher != null) {</span>
-<span class="source-line-no">212</span><span id="line-212">      zkPermissionWatcher.close();</span>
-<span class="source-line-no">213</span><span id="line-213">    }</span>
-<span class="source-line-no">214</span><span id="line-214">    rpcServer.stop();</span>
-<span class="source-line-no">215</span><span id="line-215">  }</span>
-<span class="source-line-no">216</span><span id="line-216"></span>
-<span class="source-line-no">217</span><span id="line-217">  public Configuration getConfiguration() {</span>
-<span class="source-line-no">218</span><span id="line-218">    return server.getConfiguration();</span>
-<span class="source-line-no">219</span><span id="line-219">  }</span>
-<span class="source-line-no">220</span><span id="line-220"></span>
-<span class="source-line-no">221</span><span id="line-221">  public S getServer() {</span>
-<span class="source-line-no">222</span><span id="line-222">    return server;</span>
-<span class="source-line-no">223</span><span id="line-223">  }</span>
-<span class="source-line-no">224</span><span id="line-224"></span>
-<span class="source-line-no">225</span><span id="line-225">  public InetSocketAddress getSocketAddress() {</span>
-<span class="source-line-no">226</span><span id="line-226">    return isa;</span>
-<span class="source-line-no">227</span><span id="line-227">  }</span>
-<span class="source-line-no">228</span><span id="line-228"></span>
-<span class="source-line-no">229</span><span id="line-229">  public RpcServerInterface getRpcServer() {</span>
-<span class="source-line-no">230</span><span id="line-230">    return rpcServer;</span>
-<span class="source-line-no">231</span><span id="line-231">  }</span>
-<span class="source-line-no">232</span><span id="line-232"></span>
-<span class="source-line-no">233</span><span id="line-233">  public RpcScheduler getRpcScheduler() {</span>
-<span class="source-line-no">234</span><span id="line-234">    return rpcServer.getScheduler();</span>
-<span class="source-line-no">235</span><span id="line-235">  }</span>
-<span class="source-line-no">236</span><span id="line-236"></span>
-<span class="source-line-no">237</span><span id="line-237">  @Override</span>
-<span class="source-line-no">238</span><span id="line-238">  public int getPriority(RequestHeader header, Message param, User user) {</span>
-<span class="source-line-no">239</span><span id="line-239">    return priority.getPriority(header, param, user);</span>
-<span class="source-line-no">240</span><span id="line-240">  }</span>
-<span class="source-line-no">241</span><span id="line-241"></span>
-<span class="source-line-no">242</span><span id="line-242">  @Override</span>
-<span class="source-line-no">243</span><span id="line-243">  public long getDeadline(RequestHeader header, Message param) {</span>
-<span class="source-line-no">244</span><span id="line-244">    return priority.getDeadline(header, param);</span>
+<span class="source-line-no">210</span><span id="line-210">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">211</span><span id="line-211">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">212</span><span id="line-212">  public ClientMetaCoprocessorHost getClientMetaCoprocessorHost() {</span>
+<span class="source-line-no">213</span><span id="line-213">    return clientMetaCoprocessorHost;</span>
+<span class="source-line-no">214</span><span id="line-214">  }</span>
+<span class="source-line-no">215</span><span id="line-215"></span>
+<span class="source-line-no">216</span><span id="line-216">  public AccessChecker getAccessChecker() {</span>
+<span class="source-line-no">217</span><span id="line-217">    return accessChecker;</span>
+<span class="source-line-no">218</span><span id="line-218">  }</span>
+<span class="source-line-no">219</span><span id="line-219"></span>
+<span class="source-line-no">220</span><span id="line-220">  public ZKPermissionWatcher getZkPermissionWatcher() {</span>
+<span class="source-line-no">221</span><span id="line-221">    return zkPermissionWatcher;</span>
+<span class="source-line-no">222</span><span id="line-222">  }</span>
+<span class="source-line-no">223</span><span id="line-223"></span>
+<span class="source-line-no">224</span><span id="line-224">  protected final void internalStop() {</span>
+<span class="source-line-no">225</span><span id="line-225">    if (zkPermissionWatcher != null) {</span>
+<span class="source-line-no">226</span><span id="line-226">      zkPermissionWatcher.close();</span>
+<span class="source-line-no">227</span><span id="line-227">    }</span>
+<span class="source-line-no">228</span><span id="line-228">    rpcServer.stop();</span>
+<span class="source-line-no">229</span><span id="line-229">  }</span>
+<span class="source-line-no">230</span><span id="line-230"></span>
+<span class="source-line-no">231</span><span id="line-231">  public Configuration getConfiguration() {</span>
+<span class="source-line-no">232</span><span id="line-232">    return server.getConfiguration();</span>
+<span class="source-line-no">233</span><span id="line-233">  }</span>
+<span class="source-line-no">234</span><span id="line-234"></span>
+<span class="source-line-no">235</span><span id="line-235">  public S getServer() {</span>
+<span class="source-line-no">236</span><span id="line-236">    return server;</span>
+<span class="source-line-no">237</span><span id="line-237">  }</span>
+<span class="source-line-no">238</span><span id="line-238"></span>
+<span class="source-line-no">239</span><span id="line-239">  public InetSocketAddress getSocketAddress() {</span>
+<span class="source-line-no">240</span><span id="line-240">    return isa;</span>
+<span class="source-line-no">241</span><span id="line-241">  }</span>
+<span class="source-line-no">242</span><span id="line-242"></span>
+<span class="source-line-no">243</span><span id="line-243">  public RpcServerInterface getRpcServer() {</span>
+<span class="source-line-no">244</span><span id="line-244">    return rpcServer;</span>
 <span class="source-line-no">245</span><span id="line-245">  }</span>
 <span class="source-line-no">246</span><span id="line-246"></span>
-<span class="source-line-no">247</span><span id="line-247">  /**</span>
-<span class="source-line-no">248</span><span id="line-248">   * Check if an OOME and, if so, abort immediately to avoid creating more objects.</span>
-<span class="source-line-no">249</span><span id="line-249">   * @return True if we OOME'd and are aborting.</span>
-<span class="source-line-no">250</span><span id="line-250">   */</span>
+<span class="source-line-no">247</span><span id="line-247">  public RpcScheduler getRpcScheduler() {</span>
+<span class="source-line-no">248</span><span id="line-248">    return rpcServer.getScheduler();</span>
+<span class="source-line-no">249</span><span id="line-249">  }</span>
+<span class="source-line-no">250</span><span id="line-250"></span>
 <span class="source-line-no">251</span><span id="line-251">  @Override</span>
-<span class="source-line-no">252</span><span id="line-252">  public boolean checkOOME(Throwable e) {</span>
-<span class="source-line-no">253</span><span id="line-253">    return OOMEChecker.exitIfOOME(e, getClass().getSimpleName());</span>
+<span class="source-line-no">252</span><span id="line-252">  public int getPriority(RequestHeader header, Message param, User user) {</span>
+<span class="source-line-no">253</span><span id="line-253">    return priority.getPriority(header, param, user);</span>
 <span class="source-line-no">254</span><span id="line-254">  }</span>
 <span class="source-line-no">255</span><span id="line-255"></span>
 <span class="source-line-no">256</span><span id="line-256">  @Override</span>
-<span class="source-line-no">257</span><span id="line-257">  public void onConfigurationChange(Configuration conf) {</span>
-<span class="source-line-no">258</span><span id="line-258">    rpcServer.onConfigurationChange(conf);</span>
+<span class="source-line-no">257</span><span id="line-257">  public long getDeadline(RequestHeader header, Message param) {</span>
+<span class="source-line-no">258</span><span id="line-258">    return priority.getDeadline(header, param);</span>
 <span class="source-line-no">259</span><span id="line-259">  }</span>
 <span class="source-line-no">260</span><span id="line-260"></span>
-<span class="source-line-no">261</span><span id="line-261">  @Override</span>
-<span class="source-line-no">262</span><span id="line-262">  public GetClusterIdResponse getClusterId(RpcController controller, GetClusterIdRequest request)</span>
-<span class="source-line-no">263</span><span id="line-263">    throws ServiceException {</span>
-<span class="source-line-no">264</span><span id="line-264">    return GetClusterIdResponse.newBuilder().setClusterId(server.getClusterId()).build();</span>
-<span class="source-line-no">265</span><span id="line-265">  }</span>
-<span class="source-line-no">266</span><span id="line-266"></span>
-<span class="source-line-no">267</span><span id="line-267">  @Override</span>
-<span class="source-line-no">268</span><span id="line-268">  public GetActiveMasterResponse getActiveMaster(RpcController controller,</span>
-<span class="source-line-no">269</span><span id="line-269">    GetActiveMasterRequest request) throws ServiceException {</span>
-<span class="source-line-no">270</span><span id="line-270">    GetActiveMasterResponse.Builder builder = GetActiveMasterResponse.newBuilder();</span>
-<span class="source-line-no">271</span><span id="line-271">    server.getActiveMaster()</span>
-<span class="source-line-no">272</span><span id="line-272">      .ifPresent(name -&gt; builder.setServerName(ProtobufUtil.toServerName(name)));</span>
-<span class="source-line-no">273</span><span id="line-273">    return builder.build();</span>
-<span class="source-line-no">274</span><span id="line-274">  }</span>
-<span class="source-line-no">275</span><span id="line-275"></span>
-<span class="source-line-no">276</span><span id="line-276">  @Override</span>
-<span class="source-line-no">277</span><span id="line-277">  public GetMastersResponse getMasters(RpcController controller, GetMastersRequest request)</span>
-<span class="source-line-no">278</span><span id="line-278">    throws ServiceException {</span>
-<span class="source-line-no">279</span><span id="line-279">    GetMastersResponse.Builder builder = GetMastersResponse.newBuilder();</span>
-<span class="source-line-no">280</span><span id="line-280">    server.getActiveMaster()</span>
-<span class="source-line-no">281</span><span id="line-281">      .ifPresent(activeMaster -&gt; builder.addMasterServers(GetMastersResponseEntry.newBuilder()</span>
-<span class="source-line-no">282</span><span id="line-282">        .setServerName(ProtobufUtil.toServerName(activeMaster)).setIsActive(true)));</span>
-<span class="source-line-no">283</span><span id="line-283">    server.getBackupMasters()</span>
-<span class="source-line-no">284</span><span id="line-284">      .forEach(backupMaster -&gt; builder.addMasterServers(GetMastersResponseEntry.newBuilder()</span>
-<span class="source-line-no">285</span><span id="line-285">        .setServerName(ProtobufUtil.toServerName(backupMaster)).setIsActive(false)));</span>
-<span class="source-line-no">286</span><span id="line-286">    return builder.build();</span>
-<span class="source-line-no">287</span><span id="line-287">  }</span>
-<span class="source-line-no">288</span><span id="line-288"></span>
-<span class="source-line-no">289</span><span id="line-289">  @Override</span>
-<span class="source-line-no">290</span><span id="line-290">  public GetMetaRegionLocationsResponse getMetaRegionLocations(RpcController controller,</span>
-<span class="source-line-no">291</span><span id="line-291">    GetMetaRegionLocationsRequest request) throws ServiceException {</span>
-<span class="source-line-no">292</span><span id="line-292">    GetMetaRegionLocationsResponse.Builder builder = GetMetaRegionLocationsResponse.newBuilder();</span>
-<span class="source-line-no">293</span><span id="line-293">    server.getMetaLocations()</span>
-<span class="source-line-no">294</span><span id="line-294">      .forEach(location -&gt; builder.addMetaLocations(ProtobufUtil.toRegionLocation(location)));</span>
-<span class="source-line-no">295</span><span id="line-295">    return builder.build();</span>
-<span class="source-line-no">296</span><span id="line-296">  }</span>
+<span class="source-line-no">261</span><span id="line-261">  /**</span>
+<span class="source-line-no">262</span><span id="line-262">   * Check if an OOME and, if so, abort immediately to avoid creating more objects.</span>
+<span class="source-line-no">263</span><span id="line-263">   * @return True if we OOME'd and are aborting.</span>
+<span class="source-line-no">264</span><span id="line-264">   */</span>
+<span class="source-line-no">265</span><span id="line-265">  @Override</span>
+<span class="source-line-no">266</span><span id="line-266">  public boolean checkOOME(Throwable e) {</span>
+<span class="source-line-no">267</span><span id="line-267">    return OOMEChecker.exitIfOOME(e, getClass().getSimpleName());</span>
+<span class="source-line-no">268</span><span id="line-268">  }</span>
+<span class="source-line-no">269</span><span id="line-269"></span>
+<span class="source-line-no">270</span><span id="line-270">  @Override</span>
+<span class="source-line-no">271</span><span id="line-271">  public void onConfigurationChange(Configuration conf) {</span>
+<span class="source-line-no">272</span><span id="line-272">    rpcServer.onConfigurationChange(conf);</span>
+<span class="source-line-no">273</span><span id="line-273">  }</span>
+<span class="source-line-no">274</span><span id="line-274"></span>
+<span class="source-line-no">275</span><span id="line-275">  @Override</span>
+<span class="source-line-no">276</span><span id="line-276">  public GetClusterIdResponse getClusterId(RpcController controller, GetClusterIdRequest request)</span>
+<span class="source-line-no">277</span><span id="line-277">    throws ServiceException {</span>
+<span class="source-line-no">278</span><span id="line-278">    try {</span>
+<span class="source-line-no">279</span><span id="line-279">      clientMetaCoprocessorHost.preGetClusterId();</span>
+<span class="source-line-no">280</span><span id="line-280"></span>
+<span class="source-line-no">281</span><span id="line-281">      String clusterId = server.getClusterId();</span>
+<span class="source-line-no">282</span><span id="line-282">      String clusterIdReply = clientMetaCoprocessorHost.postGetClusterId(clusterId);</span>
+<span class="source-line-no">283</span><span id="line-283"></span>
+<span class="source-line-no">284</span><span id="line-284">      return GetClusterIdResponse.newBuilder().setClusterId(clusterIdReply).build();</span>
+<span class="source-line-no">285</span><span id="line-285">    } catch (IOException e) {</span>
+<span class="source-line-no">286</span><span id="line-286">      throw new ServiceException(e);</span>
+<span class="source-line-no">287</span><span id="line-287">    }</span>
+<span class="source-line-no">288</span><span id="line-288">  }</span>
+<span class="source-line-no">289</span><span id="line-289"></span>
+<span class="source-line-no">290</span><span id="line-290">  @Override</span>
+<span class="source-line-no">291</span><span id="line-291">  public GetActiveMasterResponse getActiveMaster(RpcController controller,</span>
+<span class="source-line-no">292</span><span id="line-292">    GetActiveMasterRequest request) throws ServiceException {</span>
+<span class="source-line-no">293</span><span id="line-293">    GetActiveMasterResponse.Builder builder = GetActiveMasterResponse.newBuilder();</span>
+<span class="source-line-no">294</span><span id="line-294"></span>
+<span class="source-line-no">295</span><span id="line-295">    try {</span>
+<span class="source-line-no">296</span><span id="line-296">      clientMetaCoprocessorHost.preGetActiveMaster();</span>
 <span class="source-line-no">297</span><span id="line-297"></span>
-<span class="source-line-no">298</span><span id="line-298">  @Override</span>
-<span class="source-line-no">299</span><span id="line-299">  public final GetBootstrapNodesResponse getBootstrapNodes(RpcController controller,</span>
-<span class="source-line-no">300</span><span id="line-300">    GetBootstrapNodesRequest request) throws ServiceException {</span>
-<span class="source-line-no">301</span><span id="line-301">    int maxNodeCount = server.getConfiguration().getInt(CLIENT_BOOTSTRAP_NODE_LIMIT,</span>
-<span class="source-line-no">302</span><span id="line-302">      DEFAULT_CLIENT_BOOTSTRAP_NODE_LIMIT);</span>
-<span class="source-line-no">303</span><span id="line-303">    ReservoirSample&lt;ServerName&gt; sample = new ReservoirSample&lt;&gt;(maxNodeCount);</span>
-<span class="source-line-no">304</span><span id="line-304">    sample.add(server.getBootstrapNodes());</span>
-<span class="source-line-no">305</span><span id="line-305"></span>
-<span class="source-line-no">306</span><span id="line-306">    GetBootstrapNodesResponse.Builder builder = GetBootstrapNodesResponse.newBuilder();</span>
-<span class="source-line-no">307</span><span id="line-307">    sample.getSamplingResult().stream().map(ProtobufUtil::toServerName)</span>
-<span class="source-line-no">308</span><span id="line-308">      .forEach(builder::addServerName);</span>
-<span class="source-line-no">309</span><span id="line-309">    return builder.build();</span>
-<span class="source-line-no">310</span><span id="line-310">  }</span>
-<span class="source-line-no">311</span><span id="line-311"></span>
-<span class="source-line-no">312</span><span id="line-312">  @Override</span>
-<span class="source-line-no">313</span><span id="line-313">  @QosPriority(priority = HConstants.ADMIN_QOS)</span>
-<span class="source-line-no">314</span><span id="line-314">  public UpdateConfigurationResponse updateConfiguration(RpcController controller,</span>
-<span class="source-line-no">315</span><span id="line-315">    UpdateConfigurationRequest request) throws ServiceException {</span>
+<span class="source-line-no">298</span><span id="line-298">      ServerName serverName = server.getActiveMaster().orElse(null);</span>
+<span class="source-line-no">299</span><span id="line-299">      ServerName serverNameReply = clientMetaCoprocessorHost.postGetActiveMaster(serverName);</span>
+<span class="source-line-no">300</span><span id="line-300"></span>
+<span class="source-line-no">301</span><span id="line-301">      if (serverNameReply != null) {</span>
+<span class="source-line-no">302</span><span id="line-302">        builder.setServerName(ProtobufUtil.toServerName(serverNameReply));</span>
+<span class="source-line-no">303</span><span id="line-303">      }</span>
+<span class="source-line-no">304</span><span id="line-304">    } catch (IOException e) {</span>
+<span class="source-line-no">305</span><span id="line-305">      throw new ServiceException(e);</span>
+<span class="source-line-no">306</span><span id="line-306">    }</span>
+<span class="source-line-no">307</span><span id="line-307"></span>
+<span class="source-line-no">308</span><span id="line-308">    return builder.build();</span>
+<span class="source-line-no">309</span><span id="line-309">  }</span>
+<span class="source-line-no">310</span><span id="line-310"></span>
+<span class="source-line-no">311</span><span id="line-311">  @Override</span>
+<span class="source-line-no">312</span><span id="line-312">  public GetMastersResponse getMasters(RpcController controller, GetMastersRequest request)</span>
+<span class="source-line-no">313</span><span id="line-313">    throws ServiceException {</span>
+<span class="source-line-no">314</span><span id="line-314">    GetMastersResponse.Builder builder = GetMastersResponse.newBuilder();</span>
+<span class="source-line-no">315</span><span id="line-315"></span>
 <span class="source-line-no">316</span><span id="line-316">    try {</span>
-<span class="source-line-no">317</span><span id="line-317">      requirePermission("updateConfiguration", Permission.Action.ADMIN);</span>
-<span class="source-line-no">318</span><span id="line-318">      this.server.updateConfiguration();</span>
-<span class="source-line-no">319</span><span id="line-319">    } catch (Exception e) {</span>
-<span class="source-line-no">320</span><span id="line-320">      throw new ServiceException(e);</span>
-<span class="source-line-no">321</span><span id="line-321">    }</span>
-<span class="source-line-no">322</span><span id="line-322">    return UpdateConfigurationResponse.getDefaultInstance();</span>
-<span class="source-line-no">323</span><span id="line-323">  }</span>
-<span class="source-line-no">324</span><span id="line-324"></span>
-<span class="source-line-no">325</span><span id="line-325">  @Override</span>
-<span class="source-line-no">326</span><span id="line-326">  @QosPriority(priority = HConstants.ADMIN_QOS)</span>
-<span class="source-line-no">327</span><span id="line-327">  public ClearSlowLogResponses clearSlowLogsResponses(final RpcController controller,</span>
-<span class="source-line-no">328</span><span id="line-328">    final ClearSlowLogResponseRequest request) throws ServiceException {</span>
-<span class="source-line-no">329</span><span id="line-329">    try {</span>
-<span class="source-line-no">330</span><span id="line-330">      requirePermission("clearSlowLogsResponses", Permission.Action.ADMIN);</span>
-<span class="source-line-no">331</span><span id="line-331">    } catch (IOException e) {</span>
-<span class="source-line-no">332</span><span id="line-332">      throw new ServiceException(e);</span>
-<span class="source-line-no">333</span><span id="line-333">    }</span>
-<span class="source-line-no">334</span><span id="line-334">    final NamedQueueRecorder namedQueueRecorder = this.server.getNamedQueueRecorder();</span>
-<span class="source-line-no">335</span><span id="line-335">    boolean slowLogsCleaned = Optional.ofNullable(namedQueueRecorder)</span>
-<span class="source-line-no">336</span><span id="line-336">      .map(</span>
-<span class="source-line-no">337</span><span id="line-337">        queueRecorder -&gt; queueRecorder.clearNamedQueue(NamedQueuePayload.NamedQueueEvent.SLOW_LOG))</span>
-<span class="source-line-no">338</span><span id="line-338">      .orElse(false);</span>
-<span class="source-line-no">339</span><span id="line-339">    ClearSlowLogResponses clearSlowLogResponses =</span>
-<span class="source-line-no">340</span><span id="line-340">      ClearSlowLogResponses.newBuilder().setIsCleaned(slowLogsCleaned).build();</span>
-<span class="source-line-no">341</span><span id="line-341">    return clearSlowLogResponses;</span>
-<span class="source-line-no">342</span><span id="line-342">  }</span>
-<span class="source-line-no">343</span><span id="line-343"></span>
-<span class="source-line-no">344</span><span id="line-344">  private List&lt;SlowLogPayload&gt; getSlowLogPayloads(SlowLogResponseRequest request,</span>
-<span class="source-line-no">345</span><span id="line-345">    NamedQueueRecorder namedQueueRecorder) {</span>
-<span class="source-line-no">346</span><span id="line-346">    if (namedQueueRecorder == null) {</span>
-<span class="source-line-no">347</span><span id="line-347">      return Collections.emptyList();</span>
-<span class="source-line-no">348</span><span id="line-348">    }</span>
-<span class="source-line-no">349</span><span id="line-349">    List&lt;SlowLogPayload&gt; slowLogPayloads;</span>
-<span class="source-line-no">350</span><span id="line-350">    NamedQueueGetRequest namedQueueGetRequest = new NamedQueueGetRequest();</span>
-<span class="source-line-no">351</span><span id="line-351">    namedQueueGetRequest.setNamedQueueEvent(RpcLogDetails.SLOW_LOG_EVENT);</span>
-<span class="source-line-no">352</span><span id="line-352">    namedQueueGetRequest.setSlowLogResponseRequest(request);</span>
-<span class="source-line-no">353</span><span id="line-353">    NamedQueueGetResponse namedQueueGetResponse =</span>
-<span class="source-line-no">354</span><span id="line-354">      namedQueueRecorder.getNamedQueueRecords(namedQueueGetRequest);</span>
-<span class="source-line-no">355</span><span id="line-355">    slowLogPayloads = namedQueueGetResponse != null</span>
-<span class="source-line-no">356</span><span id="line-356">      ? namedQueueGetResponse.getSlowLogPayloads()</span>
-<span class="source-line-no">357</span><span id="line-357">      : Collections.emptyList();</span>
-<span class="source-line-no">358</span><span id="line-358">    return slowLogPayloads;</span>
-<span class="source-line-no">359</span><span id="line-359">  }</span>
-<span class="source-line-no">360</span><span id="line-360"></span>
-<span class="source-line-no">361</span><span id="line-361">  @Override</span>
-<span class="source-line-no">362</span><span id="line-362">  @QosPriority(priority = HConstants.ADMIN_QOS)</span>
-<span class="source-line-no">363</span><span id="line-363">  public HBaseProtos.LogEntry getLogEntries(RpcController controller,</span>
-<span class="source-line-no">364</span><span id="line-364">    HBaseProtos.LogRequest request) throws ServiceException {</span>
-<span class="source-line-no">365</span><span id="line-365">    try {</span>
-<span class="source-line-no">366</span><span id="line-366">      final String logClassName = request.getLogClassName();</span>
-<span class="source-line-no">367</span><span id="line-367">      Class&lt;?&gt; logClass = Class.forName(logClassName).asSubclass(Message.class);</span>
-<span class="source-line-no">368</span><span id="line-368">      Method method = logClass.getMethod("parseFrom", ByteString.class);</span>
-<span class="source-line-no">369</span><span id="line-369">      if (logClassName.contains("SlowLogResponseRequest")) {</span>
-<span class="source-line-no">370</span><span id="line-370">        SlowLogResponseRequest slowLogResponseRequest =</span>
-<span class="source-line-no">371</span><span id="line-371">          (SlowLogResponseRequest) method.invoke(null, request.getLogMessage());</span>
-<span class="source-line-no">372</span><span id="line-372">        final NamedQueueRecorder namedQueueRecorder = this.server.getNamedQueueRecorder();</span>
-<span class="source-line-no">373</span><span id="line-373">        final List&lt;SlowLogPayload&gt; slowLogPayloads =</span>
-<span class="source-line-no">374</span><span id="line-374">          getSlowLogPayloads(slowLogResponseRequest, namedQueueRecorder);</span>
-<span class="source-line-no">375</span><span id="line-375">        SlowLogResponses slowLogResponses =</span>
-<span class="source-line-no">376</span><span id="line-376">          SlowLogResponses.newBuilder().addAllSlowLogPayloads(slowLogPayloads).build();</span>
-<span class="source-line-no">377</span><span id="line-377">        return HBaseProtos.LogEntry.newBuilder()</span>
-<span class="source-line-no">378</span><span id="line-378">          .setLogClassName(slowLogResponses.getClass().getName())</span>
-<span class="source-line-no">379</span><span id="line-379">          .setLogMessage(slowLogResponses.toByteString()).build();</span>
-<span class="source-line-no">380</span><span id="line-380">      }</span>
-<span class="source-line-no">381</span><span id="line-381">    } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException</span>
-<span class="source-line-no">382</span><span id="line-382">      | InvocationTargetException e) {</span>
-<span class="source-line-no">383</span><span id="line-383">      LOG.error("Error while retrieving log entries.", e);</span>
-<span class="source-line-no">384</span><span id="line-384">      throw new ServiceException(e);</span>
-<span class="source-line-no">385</span><span id="line-385">    }</span>
-<span class="source-line-no">386</span><span id="line-386">    throw new ServiceException("Invalid request params");</span>
-<span class="source-line-no">387</span><span id="line-387">  }</span>
-<span class="source-line-no">388</span><span id="line-388">}</span>
+<span class="source-line-no">317</span><span id="line-317">      clientMetaCoprocessorHost.preGetMasters();</span>
+<span class="source-line-no">318</span><span id="line-318"></span>
+<span class="source-line-no">319</span><span id="line-319">      Map&lt;ServerName, Boolean&gt; serverNames = new LinkedHashMap&lt;&gt;();</span>
+<span class="source-line-no">320</span><span id="line-320"></span>
+<span class="source-line-no">321</span><span id="line-321">      server.getActiveMaster().ifPresent(serverName -&gt; serverNames.put(serverName, Boolean.TRUE));</span>
+<span class="source-line-no">322</span><span id="line-322">      server.getBackupMasters().forEach(serverName -&gt; serverNames.put(serverName, Boolean.FALSE));</span>
+<span class="source-line-no">323</span><span id="line-323"></span>
+<span class="source-line-no">324</span><span id="line-324">      Map&lt;ServerName, Boolean&gt; serverNamesReply =</span>
+<span class="source-line-no">325</span><span id="line-325">        clientMetaCoprocessorHost.postGetMasters(serverNames);</span>
+<span class="source-line-no">326</span><span id="line-326"></span>
+<span class="source-line-no">327</span><span id="line-327">      serverNamesReply</span>
+<span class="source-line-no">328</span><span id="line-328">        .forEach((serverName, active) -&gt; builder.addMasterServers(GetMastersResponseEntry</span>
+<span class="source-line-no">329</span><span id="line-329">          .newBuilder().setServerName(ProtobufUtil.toServerName(serverName)).setIsActive(active)));</span>
+<span class="source-line-no">330</span><span id="line-330">    } catch (IOException e) {</span>
+<span class="source-line-no">331</span><span id="line-331">      throw new ServiceException(e);</span>
+<span class="source-line-no">332</span><span id="line-332">    }</span>
+<span class="source-line-no">333</span><span id="line-333"></span>
+<span class="source-line-no">334</span><span id="line-334">    return builder.build();</span>
+<span class="source-line-no">335</span><span id="line-335">  }</span>
+<span class="source-line-no">336</span><span id="line-336"></span>
+<span class="source-line-no">337</span><span id="line-337">  @Override</span>
+<span class="source-line-no">338</span><span id="line-338">  public GetMetaRegionLocationsResponse getMetaRegionLocations(RpcController controller,</span>
+<span class="source-line-no">339</span><span id="line-339">    GetMetaRegionLocationsRequest request) throws ServiceException {</span>
+<span class="source-line-no">340</span><span id="line-340">    GetMetaRegionLocationsResponse.Builder builder = GetMetaRegionLocationsResponse.newBuilder();</span>
+<span class="source-line-no">341</span><span id="line-341"></span>
+<span class="source-line-no">342</span><span id="line-342">    try {</span>
+<span class="source-line-no">343</span><span id="line-343">      clientMetaCoprocessorHost.preGetMetaLocations();</span>
+<span class="source-line-no">344</span><span id="line-344"></span>
+<span class="source-line-no">345</span><span id="line-345">      List&lt;HRegionLocation&gt; metaLocations = server.getMetaLocations();</span>
+<span class="source-line-no">346</span><span id="line-346">      List&lt;HRegionLocation&gt; metaLocationsReply =</span>
+<span class="source-line-no">347</span><span id="line-347">        clientMetaCoprocessorHost.postGetMetaLocations(metaLocations);</span>
+<span class="source-line-no">348</span><span id="line-348"></span>
+<span class="source-line-no">349</span><span id="line-349">      metaLocationsReply</span>
+<span class="source-line-no">350</span><span id="line-350">        .forEach(location -&gt; builder.addMetaLocations(ProtobufUtil.toRegionLocation(location)));</span>
+<span class="source-line-no">351</span><span id="line-351">    } catch (IOException e) {</span>
+<span class="source-line-no">352</span><span id="line-352">      throw new ServiceException(e);</span>
+<span class="source-line-no">353</span><span id="line-353">    }</span>
+<span class="source-line-no">354</span><span id="line-354"></span>
+<span class="source-line-no">355</span><span id="line-355">    return builder.build();</span>
+<span class="source-line-no">356</span><span id="line-356">  }</span>
+<span class="source-line-no">357</span><span id="line-357"></span>
+<span class="source-line-no">358</span><span id="line-358">  @Override</span>
+<span class="source-line-no">359</span><span id="line-359">  public final GetBootstrapNodesResponse getBootstrapNodes(RpcController controller,</span>
+<span class="source-line-no">360</span><span id="line-360">    GetBootstrapNodesRequest request) throws ServiceException {</span>
+<span class="source-line-no">361</span><span id="line-361">    GetBootstrapNodesResponse.Builder builder = GetBootstrapNodesResponse.newBuilder();</span>
+<span class="source-line-no">362</span><span id="line-362"></span>
+<span class="source-line-no">363</span><span id="line-363">    try {</span>
+<span class="source-line-no">364</span><span id="line-364">      clientMetaCoprocessorHost.preGetBootstrapNodes();</span>
+<span class="source-line-no">365</span><span id="line-365"></span>
+<span class="source-line-no">366</span><span id="line-366">      int maxNodeCount = server.getConfiguration().getInt(CLIENT_BOOTSTRAP_NODE_LIMIT,</span>
+<span class="source-line-no">367</span><span id="line-367">        DEFAULT_CLIENT_BOOTSTRAP_NODE_LIMIT);</span>
+<span class="source-line-no">368</span><span id="line-368">      ReservoirSample&lt;ServerName&gt; sample = new ReservoirSample&lt;&gt;(maxNodeCount);</span>
+<span class="source-line-no">369</span><span id="line-369">      sample.add(server.getBootstrapNodes());</span>
+<span class="source-line-no">370</span><span id="line-370"></span>
+<span class="source-line-no">371</span><span id="line-371">      List&lt;ServerName&gt; bootstrapNodes = sample.getSamplingResult();</span>
+<span class="source-line-no">372</span><span id="line-372">      List&lt;ServerName&gt; bootstrapNodesReply =</span>
+<span class="source-line-no">373</span><span id="line-373">        clientMetaCoprocessorHost.postGetBootstrapNodes(bootstrapNodes);</span>
+<span class="source-line-no">374</span><span id="line-374"></span>
+<span class="source-line-no">375</span><span id="line-375">      bootstrapNodesReply</span>
+<span class="source-line-no">376</span><span id="line-376">        .forEach(serverName -&gt; builder.addServerName(ProtobufUtil.toServerName(serverName)));</span>
+<span class="source-line-no">377</span><span id="line-377">    } catch (IOException e) {</span>
+<span class="source-line-no">378</span><span id="line-378">      throw new ServiceException(e);</span>
+<span class="source-line-no">379</span><span id="line-379">    }</span>
+<span class="source-line-no">380</span><span id="line-380"></span>
+<span class="source-line-no">381</span><span id="line-381">    return builder.build();</span>
+<span class="source-line-no">382</span><span id="line-382">  }</span>
+<span class="source-line-no">383</span><span id="line-383"></span>
+<span class="source-line-no">384</span><span id="line-384">  @Override</span>
+<span class="source-line-no">385</span><span id="line-385">  @QosPriority(priority = HConstants.ADMIN_QOS)</span>
+<span class="source-line-no">386</span><span id="line-386">  public UpdateConfigurationResponse updateConfiguration(RpcController controller,</span>
+<span class="source-line-no">387</span><span id="line-387">    UpdateConfigurationRequest request) throws ServiceException {</span>
+<span class="source-line-no">388</span><span id="line-388">    try {</span>
+<span class="source-line-no">389</span><span id="line-389">      requirePermission("updateConfiguration", Permission.Action.ADMIN);</span>
+<span class="source-line-no">390</span><span id="line-390">      this.server.updateConfiguration();</span>
+<span class="source-line-no">391</span><span id="line-391"></span>
+<span class="source-line-no">392</span><span id="line-392">      clientMetaCoprocessorHost = new ClientMetaCoprocessorHost(getConfiguration());</span>
+<span class="source-line-no">393</span><span id="line-393">    } catch (Exception e) {</span>
+<span class="source-line-no">394</span><span id="line-394">      throw new ServiceException(e);</span>
+<span class="source-line-no">395</span><span id="line-395">    }</span>
+<span class="source-line-no">396</span><span id="line-396">    return UpdateConfigurationResponse.getDefaultInstance();</span>
+<span class="source-line-no">397</span><span id="line-397">  }</span>
+<span class="source-line-no">398</span><span id="line-398"></span>
+<span class="source-line-no">399</span><span id="line-399">  @Override</span>
+<span class="source-line-no">400</span><span id="line-400">  @QosPriority(priority = HConstants.ADMIN_QOS)</span>
+<span class="source-line-no">401</span><span id="line-401">  public ClearSlowLogResponses clearSlowLogsResponses(final RpcController controller,</span>
+<span class="source-line-no">402</span><span id="line-402">    final ClearSlowLogResponseRequest request) throws ServiceException {</span>
+<span class="source-line-no">403</span><span id="line-403">    try {</span>
+<span class="source-line-no">404</span><span id="line-404">      requirePermission("clearSlowLogsResponses", Permission.Action.ADMIN);</span>
+<span class="source-line-no">405</span><span id="line-405">    } catch (IOException e) {</span>
+<span class="source-line-no">406</span><span id="line-406">      throw new ServiceException(e);</span>
+<span class="source-line-no">407</span><span id="line-407">    }</span>
+<span class="source-line-no">408</span><span id="line-408">    final NamedQueueRecorder namedQueueRecorder = this.server.getNamedQueueRecorder();</span>
+<span class="source-line-no">409</span><span id="line-409">    boolean slowLogsCleaned = Optional.ofNullable(namedQueueRecorder)</span>
+<span class="source-line-no">410</span><span id="line-410">      .map(</span>
+<span class="source-line-no">411</span><span id="line-411">        queueRecorder -&gt; queueRecorder.clearNamedQueue(NamedQueuePayload.NamedQueueEvent.SLOW_LOG))</span>
+<span class="source-line-no">412</span><span id="line-412">      .orElse(false);</span>
+<span class="source-line-no">413</span><span id="line-413">    ClearSlowLogResponses clearSlowLogResponses =</span>
+<span class="source-line-no">414</span><span id="line-414">      ClearSlowLogResponses.newBuilder().setIsCleaned(slowLogsCleaned).build();</span>
+<span class="source-line-no">415</span><span id="line-415">    return clearSlowLogResponses;</span>
+<span class="source-line-no">416</span><span id="line-416">  }</span>
+<span class="source-line-no">417</span><span id="line-417"></span>
+<span class="source-line-no">418</span><span id="line-418">  private List&lt;SlowLogPayload&gt; getSlowLogPayloads(SlowLogResponseRequest request,</span>
+<span class="source-line-no">419</span><span id="line-419">    NamedQueueRecorder namedQueueRecorder) {</span>
+<span class="source-line-no">420</span><span id="line-420">    if (namedQueueRecorder == null) {</span>
+<span class="source-line-no">421</span><span id="line-421">      return Collections.emptyList();</span>
+<span class="source-line-no">422</span><span id="line-422">    }</span>
+<span class="source-line-no">423</span><span id="line-423">    List&lt;SlowLogPayload&gt; slowLogPayloads;</span>
+<span class="source-line-no">424</span><span id="line-424">    NamedQueueGetRequest namedQueueGetRequest = new NamedQueueGetRequest();</span>
+<span class="source-line-no">425</span><span id="line-425">    namedQueueGetRequest.setNamedQueueEvent(RpcLogDetails.SLOW_LOG_EVENT);</span>
+<span class="source-line-no">426</span><span id="line-426">    namedQueueGetRequest.setSlowLogResponseRequest(request);</span>
+<span class="source-line-no">427</span><span id="line-427">    NamedQueueGetResponse namedQueueGetResponse =</span>
+<span class="source-line-no">428</span><span id="line-428">      namedQueueRecorder.getNamedQueueRecords(namedQueueGetRequest);</span>
+<span class="source-line-no">429</span><span id="line-429">    slowLogPayloads = namedQueueGetResponse != null</span>
+<span class="source-line-no">430</span><span id="line-430">      ? namedQueueGetResponse.getSlowLogPayloads()</span>
+<span class="source-line-no">431</span><span id="line-431">      : Collections.emptyList();</span>
+<span class="source-line-no">432</span><span id="line-432">    return slowLogPayloads;</span>
+<span class="source-line-no">433</span><span id="line-433">  }</span>
+<span class="source-line-no">434</span><span id="line-434"></span>
+<span class="source-line-no">435</span><span id="line-435">  @Override</span>
+<span class="source-line-no">436</span><span id="line-436">  @QosPriority(priority = HConstants.ADMIN_QOS)</span>
+<span class="source-line-no">437</span><span id="line-437">  public HBaseProtos.LogEntry getLogEntries(RpcController controller,</span>
+<span class="source-line-no">438</span><span id="line-438">    HBaseProtos.LogRequest request) throws ServiceException {</span>
+<span class="source-line-no">439</span><span id="line-439">    try {</span>
+<span class="source-line-no">440</span><span id="line-440">      final String logClassName = request.getLogClassName();</span>
+<span class="source-line-no">441</span><span id="line-441">      Class&lt;?&gt; logClass = Class.forName(logClassName).asSubclass(Message.class);</span>
+<span class="source-line-no">442</span><span id="line-442">      Method method = logClass.getMethod("parseFrom", ByteString.class);</span>
+<span class="source-line-no">443</span><span id="line-443">      if (logClassName.contains("SlowLogResponseRequest")) {</span>
+<span class="source-line-no">444</span><span id="line-444">        SlowLogResponseRequest slowLogResponseRequest =</span>
+<span class="source-line-no">445</span><span id="line-445">          (SlowLogResponseRequest) method.invoke(null, request.getLogMessage());</span>
+<span class="source-line-no">446</span><span id="line-446">        final NamedQueueRecorder namedQueueRecorder = this.server.getNamedQueueRecorder();</span>
+<span class="source-line-no">447</span><span id="line-447">        final List&lt;SlowLogPayload&gt; slowLogPayloads =</span>
+<span class="source-line-no">448</span><span id="line-448">          getSlowLogPayloads(slowLogResponseRequest, namedQueueRecorder);</span>
+<span class="source-line-no">449</span><span id="line-449">        SlowLogResponses slowLogResponses =</span>
+<span class="source-line-no">450</span><span id="line-450">          SlowLogResponses.newBuilder().addAllSlowLogPayloads(slowLogPayloads).build();</span>
+<span class="source-line-no">451</span><span id="line-451">        return HBaseProtos.LogEntry.newBuilder()</span>
+<span class="source-line-no">452</span><span id="line-452">          .setLogClassName(slowLogResponses.getClass().getName())</span>
+<span class="source-line-no">453</span><span id="line-453">          .setLogMessage(slowLogResponses.toByteString()).build();</span>
+<span class="source-line-no">454</span><span id="line-454">      }</span>
+<span class="source-line-no">455</span><span id="line-455">    } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException</span>
+<span class="source-line-no">456</span><span id="line-456">      | InvocationTargetException e) {</span>
+<span class="source-line-no">457</span><span id="line-457">      LOG.error("Error while retrieving log entries.", e);</span>
+<span class="source-line-no">458</span><span id="line-458">      throw new ServiceException(e);</span>
+<span class="source-line-no">459</span><span id="line-459">    }</span>
+<span class="source-line-no">460</span><span id="line-460">    throw new ServiceException("Invalid request params");</span>
+<span class="source-line-no">461</span><span id="line-461">  }</span>
+<span class="source-line-no">462</span><span id="line-462">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessor.html b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessor.html
new file mode 100644
index 00000000000..27085dcd765
--- /dev/null
+++ b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessor.html
@@ -0,0 +1,110 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+<!-- Generated by javadoc (17) -->
+<title>Source code</title>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta name="description" content="source: package: org.apache.hadoop.hbase.coprocessor, interface: ClientMetaCoprocessor">
+<meta name="generator" content="javadoc/SourceToHTMLConverter">
+<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
+</head>
+<body class="source-page">
+<main role="main">
+<div class="source-container">
+<pre><span class="source-line-no">001</span><span id="line-1">/*</span>
+<span class="source-line-no">002</span><span id="line-2"> * Licensed to the Apache Software Foundation (ASF) under one</span>
+<span class="source-line-no">003</span><span id="line-3"> * or more contributor license agreements.  See the NOTICE file</span>
+<span class="source-line-no">004</span><span id="line-4"> * distributed with this work for additional information</span>
+<span class="source-line-no">005</span><span id="line-5"> * regarding copyright ownership.  The ASF licenses this file</span>
+<span class="source-line-no">006</span><span id="line-6"> * to you under the Apache License, Version 2.0 (the</span>
+<span class="source-line-no">007</span><span id="line-7"> * "License"); you may not use this file except in compliance</span>
+<span class="source-line-no">008</span><span id="line-8"> * with the License.  You may obtain a copy of the License at</span>
+<span class="source-line-no">009</span><span id="line-9"> *</span>
+<span class="source-line-no">010</span><span id="line-10"> *     http://www.apache.org/licenses/LICENSE-2.0</span>
+<span class="source-line-no">011</span><span id="line-11"> *</span>
+<span class="source-line-no">012</span><span id="line-12"> * Unless required by applicable law or agreed to in writing, software</span>
+<span class="source-line-no">013</span><span id="line-13"> * distributed under the License is distributed on an "AS IS" BASIS,</span>
+<span class="source-line-no">014</span><span id="line-14"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
+<span class="source-line-no">015</span><span id="line-15"> * See the License for the specific language governing permissions and</span>
+<span class="source-line-no">016</span><span id="line-16"> * limitations under the License.</span>
+<span class="source-line-no">017</span><span id="line-17"> */</span>
+<span class="source-line-no">018</span><span id="line-18">package org.apache.hadoop.hbase.coprocessor;</span>
+<span class="source-line-no">019</span><span id="line-19"></span>
+<span class="source-line-no">020</span><span id="line-20">import java.util.Optional;</span>
+<span class="source-line-no">021</span><span id="line-21">import org.apache.hadoop.hbase.Coprocessor;</span>
+<span class="source-line-no">022</span><span id="line-22">import org.apache.hadoop.hbase.HBaseInterfaceAudience;</span>
+<span class="source-line-no">023</span><span id="line-23">import org.apache.yetus.audience.InterfaceAudience;</span>
+<span class="source-line-no">024</span><span id="line-24">import org.apache.yetus.audience.InterfaceStability;</span>
+<span class="source-line-no">025</span><span id="line-25"></span>
+<span class="source-line-no">026</span><span id="line-26">@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)</span>
+<span class="source-line-no">027</span><span id="line-27">@InterfaceStability.Evolving</span>
+<span class="source-line-no">028</span><span id="line-28">public interface ClientMetaCoprocessor extends Coprocessor {</span>
+<span class="source-line-no">029</span><span id="line-29">  default Optional&lt;ClientMetaObserver&gt; getClientMetaObserver() {</span>
+<span class="source-line-no">030</span><span id="line-30">    return Optional.empty();</span>
+<span class="source-line-no">031</span><span id="line-31">  }</span>
+<span class="source-line-no">032</span><span id="line-32">}</span>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+</div>
+</main>
+</body>
+</html>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessorEnvironment.html b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessorEnvironment.html
new file mode 100644
index 00000000000..45b6c3cd197
--- /dev/null
+++ b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessorEnvironment.html
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+<!-- Generated by javadoc (17) -->
+<title>Source code</title>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta name="description" content="source: package: org.apache.hadoop.hbase.coprocessor, interface: ClientMetaCoprocessorEnvironment">
+<meta name="generator" content="javadoc/SourceToHTMLConverter">
+<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
+</head>
+<body class="source-page">
+<main role="main">
+<div class="source-container">
+<pre><span class="source-line-no">001</span><span id="line-1">/*</span>
+<span class="source-line-no">002</span><span id="line-2"> * Licensed to the Apache Software Foundation (ASF) under one</span>
+<span class="source-line-no">003</span><span id="line-3"> * or more contributor license agreements.  See the NOTICE file</span>
+<span class="source-line-no">004</span><span id="line-4"> * distributed with this work for additional information</span>
+<span class="source-line-no">005</span><span id="line-5"> * regarding copyright ownership.  The ASF licenses this file</span>
+<span class="source-line-no">006</span><span id="line-6"> * to you under the Apache License, Version 2.0 (the</span>
+<span class="source-line-no">007</span><span id="line-7"> * "License"); you may not use this file except in compliance</span>
+<span class="source-line-no">008</span><span id="line-8"> * with the License.  You may obtain a copy of the License at</span>
+<span class="source-line-no">009</span><span id="line-9"> *</span>
+<span class="source-line-no">010</span><span id="line-10"> *     http://www.apache.org/licenses/LICENSE-2.0</span>
+<span class="source-line-no">011</span><span id="line-11"> *</span>
+<span class="source-line-no">012</span><span id="line-12"> * Unless required by applicable law or agreed to in writing, software</span>
+<span class="source-line-no">013</span><span id="line-13"> * distributed under the License is distributed on an "AS IS" BASIS,</span>
+<span class="source-line-no">014</span><span id="line-14"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
+<span class="source-line-no">015</span><span id="line-15"> * See the License for the specific language governing permissions and</span>
+<span class="source-line-no">016</span><span id="line-16"> * limitations under the License.</span>
+<span class="source-line-no">017</span><span id="line-17"> */</span>
+<span class="source-line-no">018</span><span id="line-18">package org.apache.hadoop.hbase.coprocessor;</span>
+<span class="source-line-no">019</span><span id="line-19"></span>
+<span class="source-line-no">020</span><span id="line-20">import org.apache.hadoop.hbase.CoprocessorEnvironment;</span>
+<span class="source-line-no">021</span><span id="line-21">import org.apache.hadoop.hbase.HBaseInterfaceAudience;</span>
+<span class="source-line-no">022</span><span id="line-22">import org.apache.yetus.audience.InterfaceAudience;</span>
+<span class="source-line-no">023</span><span id="line-23">import org.apache.yetus.audience.InterfaceStability;</span>
+<span class="source-line-no">024</span><span id="line-24"></span>
+<span class="source-line-no">025</span><span id="line-25">@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)</span>
+<span class="source-line-no">026</span><span id="line-26">@InterfaceStability.Evolving</span>
+<span class="source-line-no">027</span><span id="line-27">public interface ClientMetaCoprocessorEnvironment</span>
+<span class="source-line-no">028</span><span id="line-28">  extends CoprocessorEnvironment&lt;ClientMetaCoprocessor&gt; {</span>
+<span class="source-line-no">029</span><span id="line-29">}</span>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+</div>
+</main>
+</body>
+</html>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessorHost.html b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessorHost.html
new file mode 100644
index 00000000000..659345b22ce
--- /dev/null
+++ b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessorHost.html
@@ -0,0 +1,290 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+<!-- Generated by javadoc (17) -->
+<title>Source code</title>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta name="description" content="source: package: org.apache.hadoop.hbase.coprocessor, class: ClientMetaCoprocessorHost">
+<meta name="generator" content="javadoc/SourceToHTMLConverter">
+<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
+</head>
+<body class="source-page">
+<main role="main">
+<div class="source-container">
+<pre><span class="source-line-no">001</span><span id="line-1">/*</span>
+<span class="source-line-no">002</span><span id="line-2"> * Licensed to the Apache Software Foundation (ASF) under one</span>
+<span class="source-line-no">003</span><span id="line-3"> * or more contributor license agreements.  See the NOTICE file</span>
+<span class="source-line-no">004</span><span id="line-4"> * distributed with this work for additional information</span>
+<span class="source-line-no">005</span><span id="line-5"> * regarding copyright ownership.  The ASF licenses this file</span>
+<span class="source-line-no">006</span><span id="line-6"> * to you under the Apache License, Version 2.0 (the</span>
+<span class="source-line-no">007</span><span id="line-7"> * "License"); you may not use this file except in compliance</span>
+<span class="source-line-no">008</span><span id="line-8"> * with the License.  You may obtain a copy of the License at</span>
+<span class="source-line-no">009</span><span id="line-9"> *</span>
+<span class="source-line-no">010</span><span id="line-10"> *     http://www.apache.org/licenses/LICENSE-2.0</span>
+<span class="source-line-no">011</span><span id="line-11"> *</span>
+<span class="source-line-no">012</span><span id="line-12"> * Unless required by applicable law or agreed to in writing, software</span>
+<span class="source-line-no">013</span><span id="line-13"> * distributed under the License is distributed on an "AS IS" BASIS,</span>
+<span class="source-line-no">014</span><span id="line-14"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
+<span class="source-line-no">015</span><span id="line-15"> * See the License for the specific language governing permissions and</span>
+<span class="source-line-no">016</span><span id="line-16"> * limitations under the License.</span>
+<span class="source-line-no">017</span><span id="line-17"> */</span>
+<span class="source-line-no">018</span><span id="line-18">package org.apache.hadoop.hbase.coprocessor;</span>
+<span class="source-line-no">019</span><span id="line-19"></span>
+<span class="source-line-no">020</span><span id="line-20">import java.io.IOException;</span>
+<span class="source-line-no">021</span><span id="line-21">import java.lang.reflect.InvocationTargetException;</span>
+<span class="source-line-no">022</span><span id="line-22">import java.util.List;</span>
+<span class="source-line-no">023</span><span id="line-23">import java.util.Map;</span>
+<span class="source-line-no">024</span><span id="line-24">import org.apache.hadoop.conf.Configuration;</span>
+<span class="source-line-no">025</span><span id="line-25">import org.apache.hadoop.hbase.HRegionLocation;</span>
+<span class="source-line-no">026</span><span id="line-26">import org.apache.hadoop.hbase.ServerName;</span>
+<span class="source-line-no">027</span><span id="line-27">import org.apache.yetus.audience.InterfaceAudience;</span>
+<span class="source-line-no">028</span><span id="line-28">import org.slf4j.Logger;</span>
+<span class="source-line-no">029</span><span id="line-29">import org.slf4j.LoggerFactory;</span>
+<span class="source-line-no">030</span><span id="line-30"></span>
+<span class="source-line-no">031</span><span id="line-31">@InterfaceAudience.Private</span>
+<span class="source-line-no">032</span><span id="line-32">public class ClientMetaCoprocessorHost</span>
+<span class="source-line-no">033</span><span id="line-33">  extends CoprocessorHost&lt;ClientMetaCoprocessor, ClientMetaCoprocessorEnvironment&gt; {</span>
+<span class="source-line-no">034</span><span id="line-34"></span>
+<span class="source-line-no">035</span><span id="line-35">  private static final Logger LOG = LoggerFactory.getLogger(ClientMetaCoprocessorHost.class);</span>
+<span class="source-line-no">036</span><span id="line-36"></span>
+<span class="source-line-no">037</span><span id="line-37">  private static class ClientMetaEnvironment extends BaseEnvironment&lt;ClientMetaCoprocessor&gt;</span>
+<span class="source-line-no">038</span><span id="line-38">    implements ClientMetaCoprocessorEnvironment {</span>
+<span class="source-line-no">039</span><span id="line-39"></span>
+<span class="source-line-no">040</span><span id="line-40">    public ClientMetaEnvironment(ClientMetaCoprocessor impl, int priority, int seq,</span>
+<span class="source-line-no">041</span><span id="line-41">      Configuration conf) {</span>
+<span class="source-line-no">042</span><span id="line-42">      super(impl, priority, seq, conf);</span>
+<span class="source-line-no">043</span><span id="line-43">    }</span>
+<span class="source-line-no">044</span><span id="line-44">  }</span>
+<span class="source-line-no">045</span><span id="line-45"></span>
+<span class="source-line-no">046</span><span id="line-46">  public ClientMetaCoprocessorHost(Configuration conf) {</span>
+<span class="source-line-no">047</span><span id="line-47">    // RPCServer cannot be aborted, so we don't pass Abortable down here.</span>
+<span class="source-line-no">048</span><span id="line-48">    super(null);</span>
+<span class="source-line-no">049</span><span id="line-49">    this.conf = conf;</span>
+<span class="source-line-no">050</span><span id="line-50">    boolean coprocessorsEnabled =</span>
+<span class="source-line-no">051</span><span id="line-51">      conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, DEFAULT_COPROCESSORS_ENABLED);</span>
+<span class="source-line-no">052</span><span id="line-52">    LOG.trace("System coprocessor loading is {}", (coprocessorsEnabled ? "enabled" : "disabled"));</span>
+<span class="source-line-no">053</span><span id="line-53">    loadSystemCoprocessors(conf, CLIENT_META_COPROCESSOR_CONF_KEY);</span>
+<span class="source-line-no">054</span><span id="line-54">  }</span>
+<span class="source-line-no">055</span><span id="line-55"></span>
+<span class="source-line-no">056</span><span id="line-56">  @Override</span>
+<span class="source-line-no">057</span><span id="line-57">  public ClientMetaCoprocessorEnvironment createEnvironment(ClientMetaCoprocessor instance,</span>
+<span class="source-line-no">058</span><span id="line-58">    int priority, int sequence, Configuration conf) {</span>
+<span class="source-line-no">059</span><span id="line-59">    return new ClientMetaEnvironment(instance, priority, sequence, conf);</span>
+<span class="source-line-no">060</span><span id="line-60">  }</span>
+<span class="source-line-no">061</span><span id="line-61"></span>
+<span class="source-line-no">062</span><span id="line-62">  @Override</span>
+<span class="source-line-no">063</span><span id="line-63">  public ClientMetaCoprocessor checkAndGetInstance(Class&lt;?&gt; implClass)</span>
+<span class="source-line-no">064</span><span id="line-64">    throws InstantiationException, IllegalAccessException {</span>
+<span class="source-line-no">065</span><span id="line-65">    try {</span>
+<span class="source-line-no">066</span><span id="line-66">      if (ClientMetaCoprocessor.class.isAssignableFrom(implClass)) {</span>
+<span class="source-line-no">067</span><span id="line-67">        return implClass.asSubclass(ClientMetaCoprocessor.class).getDeclaredConstructor()</span>
+<span class="source-line-no">068</span><span id="line-68">          .newInstance();</span>
+<span class="source-line-no">069</span><span id="line-69">      } else {</span>
+<span class="source-line-no">070</span><span id="line-70">        LOG.error("{} is not of type ClientMetaCoprocessor. Check the configuration of {}",</span>
+<span class="source-line-no">071</span><span id="line-71">          implClass.getName(), CLIENT_META_COPROCESSOR_CONF_KEY);</span>
+<span class="source-line-no">072</span><span id="line-72">        return null;</span>
+<span class="source-line-no">073</span><span id="line-73">      }</span>
+<span class="source-line-no">074</span><span id="line-74">    } catch (NoSuchMethodException | InvocationTargetException e) {</span>
+<span class="source-line-no">075</span><span id="line-75">      throw (InstantiationException) new InstantiationException(implClass.getName()).initCause(e);</span>
+<span class="source-line-no">076</span><span id="line-76">    }</span>
+<span class="source-line-no">077</span><span id="line-77">  }</span>
+<span class="source-line-no">078</span><span id="line-78"></span>
+<span class="source-line-no">079</span><span id="line-79">  private final ObserverGetter&lt;ClientMetaCoprocessor, ClientMetaObserver&gt; clientMetaObserverGetter =</span>
+<span class="source-line-no">080</span><span id="line-80">    ClientMetaCoprocessor::getClientMetaObserver;</span>
+<span class="source-line-no">081</span><span id="line-81"></span>
+<span class="source-line-no">082</span><span id="line-82">  public void preGetClusterId() throws IOException {</span>
+<span class="source-line-no">083</span><span id="line-83">    execOperation(coprocEnvironments.isEmpty()</span>
+<span class="source-line-no">084</span><span id="line-84">      ? null</span>
+<span class="source-line-no">085</span><span id="line-85">      : new ObserverOperationWithoutResult&lt;ClientMetaObserver&gt;(clientMetaObserverGetter) {</span>
+<span class="source-line-no">086</span><span id="line-86">        @Override</span>
+<span class="source-line-no">087</span><span id="line-87">        protected void call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">088</span><span id="line-88">          observer.preGetClusterId(this);</span>
+<span class="source-line-no">089</span><span id="line-89">        }</span>
+<span class="source-line-no">090</span><span id="line-90">      });</span>
+<span class="source-line-no">091</span><span id="line-91">  }</span>
+<span class="source-line-no">092</span><span id="line-92"></span>
+<span class="source-line-no">093</span><span id="line-93">  public String postGetClusterId(String clusterId) throws IOException {</span>
+<span class="source-line-no">094</span><span id="line-94">    if (coprocEnvironments.isEmpty()) {</span>
+<span class="source-line-no">095</span><span id="line-95">      return clusterId;</span>
+<span class="source-line-no">096</span><span id="line-96">    }</span>
+<span class="source-line-no">097</span><span id="line-97"></span>
+<span class="source-line-no">098</span><span id="line-98">    return execOperationWithResult(new ObserverOperationWithResult&lt;ClientMetaObserver, String&gt;(</span>
+<span class="source-line-no">099</span><span id="line-99">      clientMetaObserverGetter, clusterId) {</span>
+<span class="source-line-no">100</span><span id="line-100">      @Override</span>
+<span class="source-line-no">101</span><span id="line-101">      protected String call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">102</span><span id="line-102">        return observer.postGetClusterId(this, getResult());</span>
+<span class="source-line-no">103</span><span id="line-103">      }</span>
+<span class="source-line-no">104</span><span id="line-104">    });</span>
+<span class="source-line-no">105</span><span id="line-105">  }</span>
+<span class="source-line-no">106</span><span id="line-106"></span>
+<span class="source-line-no">107</span><span id="line-107">  public void preGetActiveMaster() throws IOException {</span>
+<span class="source-line-no">108</span><span id="line-108">    execOperation(coprocEnvironments.isEmpty()</span>
+<span class="source-line-no">109</span><span id="line-109">      ? null</span>
+<span class="source-line-no">110</span><span id="line-110">      : new ObserverOperationWithoutResult&lt;ClientMetaObserver&gt;(clientMetaObserverGetter) {</span>
+<span class="source-line-no">111</span><span id="line-111">        @Override</span>
+<span class="source-line-no">112</span><span id="line-112">        protected void call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">113</span><span id="line-113">          observer.preGetActiveMaster(this);</span>
+<span class="source-line-no">114</span><span id="line-114">        }</span>
+<span class="source-line-no">115</span><span id="line-115">      });</span>
+<span class="source-line-no">116</span><span id="line-116">  }</span>
+<span class="source-line-no">117</span><span id="line-117"></span>
+<span class="source-line-no">118</span><span id="line-118">  public ServerName postGetActiveMaster(ServerName serverName) throws IOException {</span>
+<span class="source-line-no">119</span><span id="line-119">    if (coprocEnvironments.isEmpty()) {</span>
+<span class="source-line-no">120</span><span id="line-120">      return serverName;</span>
+<span class="source-line-no">121</span><span id="line-121">    }</span>
+<span class="source-line-no">122</span><span id="line-122"></span>
+<span class="source-line-no">123</span><span id="line-123">    return execOperationWithResult(new ObserverOperationWithResult&lt;ClientMetaObserver, ServerName&gt;(</span>
+<span class="source-line-no">124</span><span id="line-124">      clientMetaObserverGetter, serverName) {</span>
+<span class="source-line-no">125</span><span id="line-125">      @Override</span>
+<span class="source-line-no">126</span><span id="line-126">      protected ServerName call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">127</span><span id="line-127">        return observer.postGetActiveMaster(this, getResult());</span>
+<span class="source-line-no">128</span><span id="line-128">      }</span>
+<span class="source-line-no">129</span><span id="line-129">    });</span>
+<span class="source-line-no">130</span><span id="line-130">  }</span>
+<span class="source-line-no">131</span><span id="line-131"></span>
+<span class="source-line-no">132</span><span id="line-132">  public void preGetMasters() throws IOException {</span>
+<span class="source-line-no">133</span><span id="line-133">    execOperation(coprocEnvironments.isEmpty()</span>
+<span class="source-line-no">134</span><span id="line-134">      ? null</span>
+<span class="source-line-no">135</span><span id="line-135">      : new ObserverOperationWithoutResult&lt;ClientMetaObserver&gt;(clientMetaObserverGetter) {</span>
+<span class="source-line-no">136</span><span id="line-136">        @Override</span>
+<span class="source-line-no">137</span><span id="line-137">        protected void call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">138</span><span id="line-138">          observer.preGetMasters(this);</span>
+<span class="source-line-no">139</span><span id="line-139">        }</span>
+<span class="source-line-no">140</span><span id="line-140">      });</span>
+<span class="source-line-no">141</span><span id="line-141">  }</span>
+<span class="source-line-no">142</span><span id="line-142"></span>
+<span class="source-line-no">143</span><span id="line-143">  public Map&lt;ServerName, Boolean&gt; postGetMasters(Map&lt;ServerName, Boolean&gt; serverNames)</span>
+<span class="source-line-no">144</span><span id="line-144">    throws IOException {</span>
+<span class="source-line-no">145</span><span id="line-145">    if (coprocEnvironments.isEmpty()) {</span>
+<span class="source-line-no">146</span><span id="line-146">      return serverNames;</span>
+<span class="source-line-no">147</span><span id="line-147">    }</span>
+<span class="source-line-no">148</span><span id="line-148"></span>
+<span class="source-line-no">149</span><span id="line-149">    return execOperationWithResult(</span>
+<span class="source-line-no">150</span><span id="line-150">      new ObserverOperationWithResult&lt;ClientMetaObserver, Map&lt;ServerName, Boolean&gt;&gt;(</span>
+<span class="source-line-no">151</span><span id="line-151">        clientMetaObserverGetter, serverNames) {</span>
+<span class="source-line-no">152</span><span id="line-152">        @Override</span>
+<span class="source-line-no">153</span><span id="line-153">        protected Map&lt;ServerName, Boolean&gt; call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">154</span><span id="line-154">          return observer.postGetMasters(this, getResult());</span>
+<span class="source-line-no">155</span><span id="line-155">        }</span>
+<span class="source-line-no">156</span><span id="line-156">      });</span>
+<span class="source-line-no">157</span><span id="line-157">  }</span>
+<span class="source-line-no">158</span><span id="line-158"></span>
+<span class="source-line-no">159</span><span id="line-159">  public void preGetBootstrapNodes() throws IOException {</span>
+<span class="source-line-no">160</span><span id="line-160">    execOperation(coprocEnvironments.isEmpty()</span>
+<span class="source-line-no">161</span><span id="line-161">      ? null</span>
+<span class="source-line-no">162</span><span id="line-162">      : new ObserverOperationWithoutResult&lt;ClientMetaObserver&gt;(clientMetaObserverGetter) {</span>
+<span class="source-line-no">163</span><span id="line-163">        @Override</span>
+<span class="source-line-no">164</span><span id="line-164">        protected void call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">165</span><span id="line-165">          observer.preGetBootstrapNodes(this);</span>
+<span class="source-line-no">166</span><span id="line-166">        }</span>
+<span class="source-line-no">167</span><span id="line-167">      });</span>
+<span class="source-line-no">168</span><span id="line-168">  }</span>
+<span class="source-line-no">169</span><span id="line-169"></span>
+<span class="source-line-no">170</span><span id="line-170">  public List&lt;ServerName&gt; postGetBootstrapNodes(List&lt;ServerName&gt; bootstrapNodes)</span>
+<span class="source-line-no">171</span><span id="line-171">    throws IOException {</span>
+<span class="source-line-no">172</span><span id="line-172">    if (coprocEnvironments.isEmpty()) {</span>
+<span class="source-line-no">173</span><span id="line-173">      return bootstrapNodes;</span>
+<span class="source-line-no">174</span><span id="line-174">    }</span>
+<span class="source-line-no">175</span><span id="line-175"></span>
+<span class="source-line-no">176</span><span id="line-176">    return execOperationWithResult(</span>
+<span class="source-line-no">177</span><span id="line-177">      new ObserverOperationWithResult&lt;ClientMetaObserver, List&lt;ServerName&gt;&gt;(</span>
+<span class="source-line-no">178</span><span id="line-178">        clientMetaObserverGetter, bootstrapNodes) {</span>
+<span class="source-line-no">179</span><span id="line-179">        @Override</span>
+<span class="source-line-no">180</span><span id="line-180">        protected List&lt;ServerName&gt; call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">181</span><span id="line-181">          return observer.postGetBootstrapNodes(this, getResult());</span>
+<span class="source-line-no">182</span><span id="line-182">        }</span>
+<span class="source-line-no">183</span><span id="line-183">      });</span>
+<span class="source-line-no">184</span><span id="line-184">  }</span>
+<span class="source-line-no">185</span><span id="line-185"></span>
+<span class="source-line-no">186</span><span id="line-186">  public void preGetMetaLocations() throws IOException {</span>
+<span class="source-line-no">187</span><span id="line-187">    execOperation(coprocEnvironments.isEmpty()</span>
+<span class="source-line-no">188</span><span id="line-188">      ? null</span>
+<span class="source-line-no">189</span><span id="line-189">      : new ObserverOperationWithoutResult&lt;ClientMetaObserver&gt;(clientMetaObserverGetter) {</span>
+<span class="source-line-no">190</span><span id="line-190">        @Override</span>
+<span class="source-line-no">191</span><span id="line-191">        protected void call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">192</span><span id="line-192">          observer.preGetMetaLocations(this);</span>
+<span class="source-line-no">193</span><span id="line-193">        }</span>
+<span class="source-line-no">194</span><span id="line-194">      });</span>
+<span class="source-line-no">195</span><span id="line-195">  }</span>
+<span class="source-line-no">196</span><span id="line-196"></span>
+<span class="source-line-no">197</span><span id="line-197">  public List&lt;HRegionLocation&gt; postGetMetaLocations(List&lt;HRegionLocation&gt; metaLocations)</span>
+<span class="source-line-no">198</span><span id="line-198">    throws IOException {</span>
+<span class="source-line-no">199</span><span id="line-199">    if (coprocEnvironments.isEmpty()) {</span>
+<span class="source-line-no">200</span><span id="line-200">      return metaLocations;</span>
+<span class="source-line-no">201</span><span id="line-201">    }</span>
+<span class="source-line-no">202</span><span id="line-202"></span>
+<span class="source-line-no">203</span><span id="line-203">    return execOperationWithResult(</span>
+<span class="source-line-no">204</span><span id="line-204">      new ObserverOperationWithResult&lt;ClientMetaObserver, List&lt;HRegionLocation&gt;&gt;(</span>
+<span class="source-line-no">205</span><span id="line-205">        clientMetaObserverGetter, metaLocations) {</span>
+<span class="source-line-no">206</span><span id="line-206">        @Override</span>
+<span class="source-line-no">207</span><span id="line-207">        protected List&lt;HRegionLocation&gt; call(ClientMetaObserver observer) throws IOException {</span>
+<span class="source-line-no">208</span><span id="line-208">          return observer.postGetMetaLocations(this, getResult());</span>
+<span class="source-line-no">209</span><span id="line-209">        }</span>
+<span class="source-line-no">210</span><span id="line-210">      });</span>
+<span class="source-line-no">211</span><span id="line-211">  }</span>
+<span class="source-line-no">212</span><span id="line-212">}</span>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+</div>
+</main>
+</body>
+</html>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaObserver.html b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaObserver.html
new file mode 100644
index 00000000000..5ebea119fe6
--- /dev/null
+++ b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/ClientMetaObserver.html
@@ -0,0 +1,231 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+<!-- Generated by javadoc (17) -->
+<title>Source code</title>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta name="description" content="source: package: org.apache.hadoop.hbase.coprocessor, interface: ClientMetaObserver">
+<meta name="generator" content="javadoc/SourceToHTMLConverter">
+<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
+</head>
+<body class="source-page">
+<main role="main">
+<div class="source-container">
+<pre><span class="source-line-no">001</span><span id="line-1">/*</span>
+<span class="source-line-no">002</span><span id="line-2"> * Licensed to the Apache Software Foundation (ASF) under one</span>
+<span class="source-line-no">003</span><span id="line-3"> * or more contributor license agreements.  See the NOTICE file</span>
+<span class="source-line-no">004</span><span id="line-4"> * distributed with this work for additional information</span>
+<span class="source-line-no">005</span><span id="line-5"> * regarding copyright ownership.  The ASF licenses this file</span>
+<span class="source-line-no">006</span><span id="line-6"> * to you under the Apache License, Version 2.0 (the</span>
+<span class="source-line-no">007</span><span id="line-7"> * "License"); you may not use this file except in compliance</span>
+<span class="source-line-no">008</span><span id="line-8"> * with the License.  You may obtain a copy of the License at</span>
+<span class="source-line-no">009</span><span id="line-9"> *</span>
+<span class="source-line-no">010</span><span id="line-10"> *     http://www.apache.org/licenses/LICENSE-2.0</span>
+<span class="source-line-no">011</span><span id="line-11"> *</span>
+<span class="source-line-no">012</span><span id="line-12"> * Unless required by applicable law or agreed to in writing, software</span>
+<span class="source-line-no">013</span><span id="line-13"> * distributed under the License is distributed on an "AS IS" BASIS,</span>
+<span class="source-line-no">014</span><span id="line-14"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
+<span class="source-line-no">015</span><span id="line-15"> * See the License for the specific language governing permissions and</span>
+<span class="source-line-no">016</span><span id="line-16"> * limitations under the License.</span>
+<span class="source-line-no">017</span><span id="line-17"> */</span>
+<span class="source-line-no">018</span><span id="line-18">package org.apache.hadoop.hbase.coprocessor;</span>
+<span class="source-line-no">019</span><span id="line-19"></span>
+<span class="source-line-no">020</span><span id="line-20">import java.io.IOException;</span>
+<span class="source-line-no">021</span><span id="line-21">import java.util.List;</span>
+<span class="source-line-no">022</span><span id="line-22">import java.util.Map;</span>
+<span class="source-line-no">023</span><span id="line-23">import org.apache.hadoop.hbase.HBaseInterfaceAudience;</span>
+<span class="source-line-no">024</span><span id="line-24">import org.apache.hadoop.hbase.HRegionLocation;</span>
+<span class="source-line-no">025</span><span id="line-25">import org.apache.hadoop.hbase.ServerName;</span>
+<span class="source-line-no">026</span><span id="line-26">import org.apache.yetus.audience.InterfaceAudience;</span>
+<span class="source-line-no">027</span><span id="line-27">import org.apache.yetus.audience.InterfaceStability;</span>
+<span class="source-line-no">028</span><span id="line-28"></span>
+<span class="source-line-no">029</span><span id="line-29">/**</span>
+<span class="source-line-no">030</span><span id="line-30"> * Defines coprocessor hooks for interacting operations for ClientMetaService which is responsible</span>
+<span class="source-line-no">031</span><span id="line-31"> * for ZooKeeperless HBase service discovery. &lt;br&gt;</span>
+<span class="source-line-no">032</span><span id="line-32"> * &lt;br&gt;</span>
+<span class="source-line-no">033</span><span id="line-33"> * Since most implementations will be interested in only a subset of hooks, this class uses</span>
+<span class="source-line-no">034</span><span id="line-34"> * 'default' functions to avoid having to add unnecessary overrides. When the functions are</span>
+<span class="source-line-no">035</span><span id="line-35"> * non-empty, it's simply to satisfy the compiler by returning value of expected (non-void) type. It</span>
+<span class="source-line-no">036</span><span id="line-36"> * is done in a way that these default definitions act as no-op. So our suggestion to implementation</span>
+<span class="source-line-no">037</span><span id="line-37"> * would be to not call these 'default' methods from overrides. &lt;br&gt;</span>
+<span class="source-line-no">038</span><span id="line-38"> * &lt;br&gt;</span>
+<span class="source-line-no">039</span><span id="line-39"> * &lt;h3&gt;Exception Handling&lt;/h3&gt; For all functions, exception handling is done as follows:</span>
+<span class="source-line-no">040</span><span id="line-40"> * &lt;ul&gt;</span>
+<span class="source-line-no">041</span><span id="line-41"> * &lt;li&gt;Exceptions of type {@link IOException} are reported back to client.&lt;/li&gt;</span>
+<span class="source-line-no">042</span><span id="line-42"> * &lt;li&gt;For any other kind of exception:</span>
+<span class="source-line-no">043</span><span id="line-43"> * &lt;ul&gt;</span>
+<span class="source-line-no">044</span><span id="line-44"> * &lt;li&gt;If the configuration {@link CoprocessorHost#ABORT_ON_ERROR_KEY} is set to true, then the</span>
+<span class="source-line-no">045</span><span id="line-45"> * server aborts.&lt;/li&gt;</span>
+<span class="source-line-no">046</span><span id="line-46"> * &lt;li&gt;Otherwise, coprocessor is removed from the server and</span>
+<span class="source-line-no">047</span><span id="line-47"> * {@link org.apache.hadoop.hbase.DoNotRetryIOException} is returned to the client.&lt;/li&gt;</span>
+<span class="source-line-no">048</span><span id="line-48"> * &lt;/ul&gt;</span>
+<span class="source-line-no">049</span><span id="line-49"> * &lt;/li&gt;</span>
+<span class="source-line-no">050</span><span id="line-50"> * &lt;/ul&gt;</span>
+<span class="source-line-no">051</span><span id="line-51"> */</span>
+<span class="source-line-no">052</span><span id="line-52">@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)</span>
+<span class="source-line-no">053</span><span id="line-53">@InterfaceStability.Evolving</span>
+<span class="source-line-no">054</span><span id="line-54">public interface ClientMetaObserver {</span>
+<span class="source-line-no">055</span><span id="line-55">  /**</span>
+<span class="source-line-no">056</span><span id="line-56">   * Called before getting the cluster ID.</span>
+<span class="source-line-no">057</span><span id="line-57">   * @param ctx the environment to interact with the framework</span>
+<span class="source-line-no">058</span><span id="line-58">   */</span>
+<span class="source-line-no">059</span><span id="line-59">  default void preGetClusterId(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx)</span>
+<span class="source-line-no">060</span><span id="line-60">    throws IOException {</span>
+<span class="source-line-no">061</span><span id="line-61">  }</span>
+<span class="source-line-no">062</span><span id="line-62"></span>
+<span class="source-line-no">063</span><span id="line-63">  /**</span>
+<span class="source-line-no">064</span><span id="line-64">   * Called after we got the cluster ID.</span>
+<span class="source-line-no">065</span><span id="line-65">   * @param ctx       the environment to interact with the framework</span>
+<span class="source-line-no">066</span><span id="line-66">   * @param clusterId the actual cluster ID</span>
+<span class="source-line-no">067</span><span id="line-67">   * @return the cluster ID which is returned to the client.</span>
+<span class="source-line-no">068</span><span id="line-68">   */</span>
+<span class="source-line-no">069</span><span id="line-69">  default String postGetClusterId(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx,</span>
+<span class="source-line-no">070</span><span id="line-70">    String clusterId) throws IOException {</span>
+<span class="source-line-no">071</span><span id="line-71">    return clusterId;</span>
+<span class="source-line-no">072</span><span id="line-72">  }</span>
+<span class="source-line-no">073</span><span id="line-73"></span>
+<span class="source-line-no">074</span><span id="line-74">  /**</span>
+<span class="source-line-no">075</span><span id="line-75">   * Called before getting the active master.</span>
+<span class="source-line-no">076</span><span id="line-76">   * @param ctx the environment to interact with the framework</span>
+<span class="source-line-no">077</span><span id="line-77">   */</span>
+<span class="source-line-no">078</span><span id="line-78">  default void preGetActiveMaster(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx)</span>
+<span class="source-line-no">079</span><span id="line-79">    throws IOException {</span>
+<span class="source-line-no">080</span><span id="line-80">  }</span>
+<span class="source-line-no">081</span><span id="line-81"></span>
+<span class="source-line-no">082</span><span id="line-82">  /**</span>
+<span class="source-line-no">083</span><span id="line-83">   * Called after we got the active master.</span>
+<span class="source-line-no">084</span><span id="line-84">   * @param ctx        the environment to interact with the framework</span>
+<span class="source-line-no">085</span><span id="line-85">   * @param serverName the actual active master address. It can be {@code null} if there is no</span>
+<span class="source-line-no">086</span><span id="line-86">   *                   active master.</span>
+<span class="source-line-no">087</span><span id="line-87">   * @return the active master address which is returned to the client. It can be {@code null}.</span>
+<span class="source-line-no">088</span><span id="line-88">   */</span>
+<span class="source-line-no">089</span><span id="line-89">  default ServerName postGetActiveMaster(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx,</span>
+<span class="source-line-no">090</span><span id="line-90">    ServerName serverName) throws IOException {</span>
+<span class="source-line-no">091</span><span id="line-91">    return serverName;</span>
+<span class="source-line-no">092</span><span id="line-92">  }</span>
+<span class="source-line-no">093</span><span id="line-93"></span>
+<span class="source-line-no">094</span><span id="line-94">  /**</span>
+<span class="source-line-no">095</span><span id="line-95">   * Called before getting the master servers.</span>
+<span class="source-line-no">096</span><span id="line-96">   * @param ctx the environment to interact with the framework</span>
+<span class="source-line-no">097</span><span id="line-97">   */</span>
+<span class="source-line-no">098</span><span id="line-98">  default void preGetMasters(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx)</span>
+<span class="source-line-no">099</span><span id="line-99">    throws IOException {</span>
+<span class="source-line-no">100</span><span id="line-100">  }</span>
+<span class="source-line-no">101</span><span id="line-101"></span>
+<span class="source-line-no">102</span><span id="line-102">  /**</span>
+<span class="source-line-no">103</span><span id="line-103">   * Called after we got the master servers.</span>
+<span class="source-line-no">104</span><span id="line-104">   * @param ctx         the environment to interact with the framework</span>
+<span class="source-line-no">105</span><span id="line-105">   * @param serverNames the actual master servers addresses and active statuses</span>
+<span class="source-line-no">106</span><span id="line-106">   * @return the master servers addresses and active statuses which are returned to the client.</span>
+<span class="source-line-no">107</span><span id="line-107">   */</span>
+<span class="source-line-no">108</span><span id="line-108">  default Map&lt;ServerName, Boolean&gt; postGetMasters(</span>
+<span class="source-line-no">109</span><span id="line-109">    ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx, Map&lt;ServerName, Boolean&gt; serverNames)</span>
+<span class="source-line-no">110</span><span id="line-110">    throws IOException {</span>
+<span class="source-line-no">111</span><span id="line-111">    return serverNames;</span>
+<span class="source-line-no">112</span><span id="line-112">  }</span>
+<span class="source-line-no">113</span><span id="line-113"></span>
+<span class="source-line-no">114</span><span id="line-114">  /**</span>
+<span class="source-line-no">115</span><span id="line-115">   * Called before getting bootstrap nodes.</span>
+<span class="source-line-no">116</span><span id="line-116">   * @param ctx the environment to interact with the framework</span>
+<span class="source-line-no">117</span><span id="line-117">   */</span>
+<span class="source-line-no">118</span><span id="line-118">  default void preGetBootstrapNodes(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx)</span>
+<span class="source-line-no">119</span><span id="line-119">    throws IOException {</span>
+<span class="source-line-no">120</span><span id="line-120">  }</span>
+<span class="source-line-no">121</span><span id="line-121"></span>
+<span class="source-line-no">122</span><span id="line-122">  /**</span>
+<span class="source-line-no">123</span><span id="line-123">   * Called after we got bootstrap nodes.</span>
+<span class="source-line-no">124</span><span id="line-124">   * @param ctx            the environment to interact with the framework</span>
+<span class="source-line-no">125</span><span id="line-125">   * @param bootstrapNodes the actual bootstrap nodes</span>
+<span class="source-line-no">126</span><span id="line-126">   * @return the bootstrap nodes which are returned to the client.</span>
+<span class="source-line-no">127</span><span id="line-127">   */</span>
+<span class="source-line-no">128</span><span id="line-128">  default List&lt;ServerName&gt; postGetBootstrapNodes(</span>
+<span class="source-line-no">129</span><span id="line-129">    ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx, List&lt;ServerName&gt; bootstrapNodes)</span>
+<span class="source-line-no">130</span><span id="line-130">    throws IOException {</span>
+<span class="source-line-no">131</span><span id="line-131">    return bootstrapNodes;</span>
+<span class="source-line-no">132</span><span id="line-132">  }</span>
+<span class="source-line-no">133</span><span id="line-133"></span>
+<span class="source-line-no">134</span><span id="line-134">  /**</span>
+<span class="source-line-no">135</span><span id="line-135">   * Called before getting the meta region locations.</span>
+<span class="source-line-no">136</span><span id="line-136">   * @param ctx the environment to interact with the framework</span>
+<span class="source-line-no">137</span><span id="line-137">   */</span>
+<span class="source-line-no">138</span><span id="line-138">  default void preGetMetaLocations(ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx)</span>
+<span class="source-line-no">139</span><span id="line-139">    throws IOException {</span>
+<span class="source-line-no">140</span><span id="line-140">  }</span>
+<span class="source-line-no">141</span><span id="line-141"></span>
+<span class="source-line-no">142</span><span id="line-142">  /**</span>
+<span class="source-line-no">143</span><span id="line-143">   * Called after we got the meta region locations.</span>
+<span class="source-line-no">144</span><span id="line-144">   * @param ctx           the environment to interact with the framework</span>
+<span class="source-line-no">145</span><span id="line-145">   * @param metaLocations the actual meta region locations</span>
+<span class="source-line-no">146</span><span id="line-146">   * @return the meta region locations which are returned to the client.</span>
+<span class="source-line-no">147</span><span id="line-147">   */</span>
+<span class="source-line-no">148</span><span id="line-148">  default List&lt;HRegionLocation&gt; postGetMetaLocations(</span>
+<span class="source-line-no">149</span><span id="line-149">    ObserverContext&lt;ClientMetaCoprocessorEnvironment&gt; ctx, List&lt;HRegionLocation&gt; metaLocations)</span>
+<span class="source-line-no">150</span><span id="line-150">    throws IOException {</span>
+<span class="source-line-no">151</span><span id="line-151">    return metaLocations;</span>
+<span class="source-line-no">152</span><span id="line-152">  }</span>
+<span class="source-line-no">153</span><span id="line-153">}</span>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+</div>
+</main>
+</body>
+</html>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverGetter.html b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverGetter.html
index 6ab3b5755ff..da3c6573d26 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverGetter.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverGetter.html
@@ -74,632 +74,634 @@
 <span class="source-line-no">061</span><span id="line-61">  public static final String USER_REGION_COPROCESSOR_CONF_KEY =</span>
 <span class="source-line-no">062</span><span id="line-62">    "hbase.coprocessor.user.region.classes";</span>
 <span class="source-line-no">063</span><span id="line-63">  public static final String MASTER_COPROCESSOR_CONF_KEY = "hbase.coprocessor.master.classes";</span>
-<span class="source-line-no">064</span><span id="line-64">  public static final String WAL_COPROCESSOR_CONF_KEY = "hbase.coprocessor.wal.classes";</span>
-<span class="source-line-no">065</span><span id="line-65">  public static final String RPC_COPROCESSOR_CONF_KEY = "hbase.coprocessor.rpc.classes";</span>
-<span class="source-line-no">066</span><span id="line-66">  public static final String ABORT_ON_ERROR_KEY = "hbase.coprocessor.abortonerror";</span>
-<span class="source-line-no">067</span><span id="line-67">  public static final boolean DEFAULT_ABORT_ON_ERROR = true;</span>
-<span class="source-line-no">068</span><span id="line-68">  public static final String COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.enabled";</span>
-<span class="source-line-no">069</span><span id="line-69">  public static final boolean DEFAULT_COPROCESSORS_ENABLED = true;</span>
-<span class="source-line-no">070</span><span id="line-70">  public static final String USER_COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.user.enabled";</span>
-<span class="source-line-no">071</span><span id="line-71">  public static final boolean DEFAULT_USER_COPROCESSORS_ENABLED = true;</span>
-<span class="source-line-no">072</span><span id="line-72">  public static final String SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR =</span>
-<span class="source-line-no">073</span><span id="line-73">    "hbase.skip.load.duplicate.table.coprocessor";</span>
-<span class="source-line-no">074</span><span id="line-74">  public static final boolean DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR = false;</span>
-<span class="source-line-no">075</span><span id="line-75"></span>
-<span class="source-line-no">076</span><span id="line-76">  private static final Logger LOG = LoggerFactory.getLogger(CoprocessorHost.class);</span>
-<span class="source-line-no">077</span><span id="line-77">  protected Abortable abortable;</span>
-<span class="source-line-no">078</span><span id="line-78">  /** Ordered set of loaded coprocessors with lock */</span>
-<span class="source-line-no">079</span><span id="line-79">  protected final SortedList&lt;E&gt; coprocEnvironments =</span>
-<span class="source-line-no">080</span><span id="line-80">    new SortedList&lt;&gt;(new EnvironmentPriorityComparator());</span>
-<span class="source-line-no">081</span><span id="line-81">  protected Configuration conf;</span>
-<span class="source-line-no">082</span><span id="line-82">  // unique file prefix to use for local copies of jars when classloading</span>
-<span class="source-line-no">083</span><span id="line-83">  protected String pathPrefix;</span>
-<span class="source-line-no">084</span><span id="line-84">  protected AtomicInteger loadSequence = new AtomicInteger();</span>
-<span class="source-line-no">085</span><span id="line-85"></span>
-<span class="source-line-no">086</span><span id="line-86">  public CoprocessorHost(Abortable abortable) {</span>
-<span class="source-line-no">087</span><span id="line-87">    this.abortable = abortable;</span>
-<span class="source-line-no">088</span><span id="line-88">    this.pathPrefix = UUID.randomUUID().toString();</span>
-<span class="source-line-no">089</span><span id="line-89">  }</span>
-<span class="source-line-no">090</span><span id="line-90"></span>
-<span class="source-line-no">091</span><span id="line-91">  /**</span>
-<span class="source-line-no">092</span><span id="line-92">   * Not to be confused with the per-object _coprocessors_ (above), coprocessorNames is static and</span>
-<span class="source-line-no">093</span><span id="line-93">   * stores the set of all coprocessors ever loaded by any thread in this JVM. It is strictly</span>
-<span class="source-line-no">094</span><span id="line-94">   * additive: coprocessors are added to coprocessorNames, by checkAndLoadInstance() but are never</span>
-<span class="source-line-no">095</span><span id="line-95">   * removed, since the intention is to preserve a history of all loaded coprocessors for diagnosis</span>
-<span class="source-line-no">096</span><span id="line-96">   * in case of server crash (HBASE-4014).</span>
-<span class="source-line-no">097</span><span id="line-97">   */</span>
-<span class="source-line-no">098</span><span id="line-98">  private static Set&lt;String&gt; coprocessorNames = Collections.synchronizedSet(new HashSet&lt;String&gt;());</span>
-<span class="source-line-no">099</span><span id="line-99"></span>
-<span class="source-line-no">100</span><span id="line-100">  public static Set&lt;String&gt; getLoadedCoprocessors() {</span>
-<span class="source-line-no">101</span><span id="line-101">    synchronized (coprocessorNames) {</span>
-<span class="source-line-no">102</span><span id="line-102">      return new HashSet(coprocessorNames);</span>
-<span class="source-line-no">103</span><span id="line-103">    }</span>
-<span class="source-line-no">104</span><span id="line-104">  }</span>
-<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106">  /**</span>
-<span class="source-line-no">107</span><span id="line-107">   * Used to create a parameter to the HServerLoad constructor so that HServerLoad can provide</span>
-<span class="source-line-no">108</span><span id="line-108">   * information about the coprocessors loaded by this regionserver. (HBASE-4070: Improve region</span>
-<span class="source-line-no">109</span><span id="line-109">   * server metrics to report loaded coprocessors to master).</span>
-<span class="source-line-no">110</span><span id="line-110">   */</span>
-<span class="source-line-no">111</span><span id="line-111">  public Set&lt;String&gt; getCoprocessors() {</span>
-<span class="source-line-no">112</span><span id="line-112">    Set&lt;String&gt; returnValue = new TreeSet&lt;&gt;();</span>
-<span class="source-line-no">113</span><span id="line-113">    for (E e : coprocEnvironments) {</span>
-<span class="source-line-no">114</span><span id="line-114">      returnValue.add(e.getInstance().getClass().getSimpleName());</span>
-<span class="source-line-no">115</span><span id="line-115">    }</span>
-<span class="source-line-no">116</span><span id="line-116">    return returnValue;</span>
-<span class="source-line-no">117</span><span id="line-117">  }</span>
-<span class="source-line-no">118</span><span id="line-118"></span>
-<span class="source-line-no">119</span><span id="line-119">  /**</span>
-<span class="source-line-no">120</span><span id="line-120">   * Load system coprocessors once only. Read the class names from configuration. Called by</span>
-<span class="source-line-no">121</span><span id="line-121">   * constructor.</span>
-<span class="source-line-no">122</span><span id="line-122">   */</span>
-<span class="source-line-no">123</span><span id="line-123">  protected void loadSystemCoprocessors(Configuration conf, String confKey) {</span>
-<span class="source-line-no">124</span><span id="line-124">    boolean coprocessorsEnabled =</span>
-<span class="source-line-no">125</span><span id="line-125">      conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, DEFAULT_COPROCESSORS_ENABLED);</span>
-<span class="source-line-no">126</span><span id="line-126">    if (!coprocessorsEnabled) {</span>
-<span class="source-line-no">127</span><span id="line-127">      return;</span>
-<span class="source-line-no">128</span><span id="line-128">    }</span>
-<span class="source-line-no">129</span><span id="line-129"></span>
-<span class="source-line-no">130</span><span id="line-130">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">064</span><span id="line-64">  public static final String CLIENT_META_COPROCESSOR_CONF_KEY =</span>
+<span class="source-line-no">065</span><span id="line-65">    "hbase.coprocessor.clientmeta.classes";</span>
+<span class="source-line-no">066</span><span id="line-66">  public static final String WAL_COPROCESSOR_CONF_KEY = "hbase.coprocessor.wal.classes";</span>
+<span class="source-line-no">067</span><span id="line-67">  public static final String RPC_COPROCESSOR_CONF_KEY = "hbase.coprocessor.rpc.classes";</span>
+<span class="source-line-no">068</span><span id="line-68">  public static final String ABORT_ON_ERROR_KEY = "hbase.coprocessor.abortonerror";</span>
+<span class="source-line-no">069</span><span id="line-69">  public static final boolean DEFAULT_ABORT_ON_ERROR = true;</span>
+<span class="source-line-no">070</span><span id="line-70">  public static final String COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.enabled";</span>
+<span class="source-line-no">071</span><span id="line-71">  public static final boolean DEFAULT_COPROCESSORS_ENABLED = true;</span>
+<span class="source-line-no">072</span><span id="line-72">  public static final String USER_COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.user.enabled";</span>
+<span class="source-line-no">073</span><span id="line-73">  public static final boolean DEFAULT_USER_COPROCESSORS_ENABLED = true;</span>
+<span class="source-line-no">074</span><span id="line-74">  public static final String SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR =</span>
+<span class="source-line-no">075</span><span id="line-75">    "hbase.skip.load.duplicate.table.coprocessor";</span>
+<span class="source-line-no">076</span><span id="line-76">  public static final boolean DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR = false;</span>
+<span class="source-line-no">077</span><span id="line-77"></span>
+<span class="source-line-no">078</span><span id="line-78">  private static final Logger LOG = LoggerFactory.getLogger(CoprocessorHost.class);</span>
+<span class="source-line-no">079</span><span id="line-79">  protected Abortable abortable;</span>
+<span class="source-line-no">080</span><span id="line-80">  /** Ordered set of loaded coprocessors with lock */</span>
+<span class="source-line-no">081</span><span id="line-81">  protected final SortedList&lt;E&gt; coprocEnvironments =</span>
+<span class="source-line-no">082</span><span id="line-82">    new SortedList&lt;&gt;(new EnvironmentPriorityComparator());</span>
+<span class="source-line-no">083</span><span id="line-83">  protected Configuration conf;</span>
+<span class="source-line-no">084</span><span id="line-84">  // unique file prefix to use for local copies of jars when classloading</span>
+<span class="source-line-no">085</span><span id="line-85">  protected String pathPrefix;</span>
+<span class="source-line-no">086</span><span id="line-86">  protected AtomicInteger loadSequence = new AtomicInteger();</span>
+<span class="source-line-no">087</span><span id="line-87"></span>
+<span class="source-line-no">088</span><span id="line-88">  public CoprocessorHost(Abortable abortable) {</span>
+<span class="source-line-no">089</span><span id="line-89">    this.abortable = abortable;</span>
+<span class="source-line-no">090</span><span id="line-90">    this.pathPrefix = UUID.randomUUID().toString();</span>
+<span class="source-line-no">091</span><span id="line-91">  }</span>
+<span class="source-line-no">092</span><span id="line-92"></span>
+<span class="source-line-no">093</span><span id="line-93">  /**</span>
+<span class="source-line-no">094</span><span id="line-94">   * Not to be confused with the per-object _coprocessors_ (above), coprocessorNames is static and</span>
+<span class="source-line-no">095</span><span id="line-95">   * stores the set of all coprocessors ever loaded by any thread in this JVM. It is strictly</span>
+<span class="source-line-no">096</span><span id="line-96">   * additive: coprocessors are added to coprocessorNames, by checkAndLoadInstance() but are never</span>
+<span class="source-line-no">097</span><span id="line-97">   * removed, since the intention is to preserve a history of all loaded coprocessors for diagnosis</span>
+<span class="source-line-no">098</span><span id="line-98">   * in case of server crash (HBASE-4014).</span>
+<span class="source-line-no">099</span><span id="line-99">   */</span>
+<span class="source-line-no">100</span><span id="line-100">  private static Set&lt;String&gt; coprocessorNames = Collections.synchronizedSet(new HashSet&lt;String&gt;());</span>
+<span class="source-line-no">101</span><span id="line-101"></span>
+<span class="source-line-no">102</span><span id="line-102">  public static Set&lt;String&gt; getLoadedCoprocessors() {</span>
+<span class="source-line-no">103</span><span id="line-103">    synchronized (coprocessorNames) {</span>
+<span class="source-line-no">104</span><span id="line-104">      return new HashSet(coprocessorNames);</span>
+<span class="source-line-no">105</span><span id="line-105">    }</span>
+<span class="source-line-no">106</span><span id="line-106">  }</span>
+<span class="source-line-no">107</span><span id="line-107"></span>
+<span class="source-line-no">108</span><span id="line-108">  /**</span>
+<span class="source-line-no">109</span><span id="line-109">   * Used to create a parameter to the HServerLoad constructor so that HServerLoad can provide</span>
+<span class="source-line-no">110</span><span id="line-110">   * information about the coprocessors loaded by this regionserver. (HBASE-4070: Improve region</span>
+<span class="source-line-no">111</span><span id="line-111">   * server metrics to report loaded coprocessors to master).</span>
+<span class="source-line-no">112</span><span id="line-112">   */</span>
+<span class="source-line-no">113</span><span id="line-113">  public Set&lt;String&gt; getCoprocessors() {</span>
+<span class="source-line-no">114</span><span id="line-114">    Set&lt;String&gt; returnValue = new TreeSet&lt;&gt;();</span>
+<span class="source-line-no">115</span><span id="line-115">    for (E e : coprocEnvironments) {</span>
+<span class="source-line-no">116</span><span id="line-116">      returnValue.add(e.getInstance().getClass().getSimpleName());</span>
+<span class="source-line-no">117</span><span id="line-117">    }</span>
+<span class="source-line-no">118</span><span id="line-118">    return returnValue;</span>
+<span class="source-line-no">119</span><span id="line-119">  }</span>
+<span class="source-line-no">120</span><span id="line-120"></span>
+<span class="source-line-no">121</span><span id="line-121">  /**</span>
+<span class="source-line-no">122</span><span id="line-122">   * Load system coprocessors once only. Read the class names from configuration. Called by</span>
+<span class="source-line-no">123</span><span id="line-123">   * constructor.</span>
+<span class="source-line-no">124</span><span id="line-124">   */</span>
+<span class="source-line-no">125</span><span id="line-125">  protected void loadSystemCoprocessors(Configuration conf, String confKey) {</span>
+<span class="source-line-no">126</span><span id="line-126">    boolean coprocessorsEnabled =</span>
+<span class="source-line-no">127</span><span id="line-127">      conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, DEFAULT_COPROCESSORS_ENABLED);</span>
+<span class="source-line-no">128</span><span id="line-128">    if (!coprocessorsEnabled) {</span>
+<span class="source-line-no">129</span><span id="line-129">      return;</span>
+<span class="source-line-no">130</span><span id="line-130">    }</span>
 <span class="source-line-no">131</span><span id="line-131"></span>
-<span class="source-line-no">132</span><span id="line-132">    // load default coprocessors from configure file</span>
-<span class="source-line-no">133</span><span id="line-133">    String[] defaultCPClasses = conf.getStrings(confKey);</span>
-<span class="source-line-no">134</span><span id="line-134">    if (defaultCPClasses == null || defaultCPClasses.length == 0) return;</span>
-<span class="source-line-no">135</span><span id="line-135"></span>
-<span class="source-line-no">136</span><span id="line-136">    int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;</span>
-<span class="source-line-no">137</span><span id="line-137">    for (String className : defaultCPClasses) {</span>
-<span class="source-line-no">138</span><span id="line-138">      // After HBASE-23710 and HBASE-26714 when configuring for system coprocessor, we accept</span>
-<span class="source-line-no">139</span><span id="line-139">      // an optional format of className|priority|path</span>
-<span class="source-line-no">140</span><span id="line-140">      String[] classNameToken = className.split("\\|");</span>
-<span class="source-line-no">141</span><span id="line-141">      boolean hasPriorityOverride = false;</span>
-<span class="source-line-no">142</span><span id="line-142">      boolean hasPath = false;</span>
-<span class="source-line-no">143</span><span id="line-143">      className = classNameToken[0];</span>
-<span class="source-line-no">144</span><span id="line-144">      int overridePriority = Coprocessor.PRIORITY_SYSTEM;</span>
-<span class="source-line-no">145</span><span id="line-145">      Path path = null;</span>
-<span class="source-line-no">146</span><span id="line-146">      if (classNameToken.length &gt; 1 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[1])) {</span>
-<span class="source-line-no">147</span><span id="line-147">        overridePriority = Integer.parseInt(classNameToken[1]);</span>
-<span class="source-line-no">148</span><span id="line-148">        hasPriorityOverride = true;</span>
-<span class="source-line-no">149</span><span id="line-149">      }</span>
-<span class="source-line-no">150</span><span id="line-150">      if (classNameToken.length &gt; 2 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[2])) {</span>
-<span class="source-line-no">151</span><span id="line-151">        path = new Path(classNameToken[2].trim());</span>
-<span class="source-line-no">152</span><span id="line-152">        hasPath = true;</span>
-<span class="source-line-no">153</span><span id="line-153">      }</span>
-<span class="source-line-no">154</span><span id="line-154">      className = className.trim();</span>
-<span class="source-line-no">155</span><span id="line-155">      if (findCoprocessor(className) != null) {</span>
-<span class="source-line-no">156</span><span id="line-156">        // If already loaded will just continue</span>
-<span class="source-line-no">157</span><span id="line-157">        LOG.warn("Attempted duplicate loading of " + className + "; skipped");</span>
-<span class="source-line-no">158</span><span id="line-158">        continue;</span>
-<span class="source-line-no">159</span><span id="line-159">      }</span>
-<span class="source-line-no">160</span><span id="line-160">      ClassLoader cl = this.getClass().getClassLoader();</span>
-<span class="source-line-no">161</span><span id="line-161">      try {</span>
-<span class="source-line-no">162</span><span id="line-162">        // override the class loader if a path for the system coprocessor is provided.</span>
-<span class="source-line-no">163</span><span id="line-163">        if (hasPath) {</span>
-<span class="source-line-no">164</span><span id="line-164">          cl = CoprocessorClassLoader.getClassLoader(path, this.getClass().getClassLoader(),</span>
-<span class="source-line-no">165</span><span id="line-165">            pathPrefix, conf);</span>
-<span class="source-line-no">166</span><span id="line-166">        }</span>
-<span class="source-line-no">167</span><span id="line-167">        Thread.currentThread().setContextClassLoader(cl);</span>
-<span class="source-line-no">168</span><span id="line-168">        implClass = cl.loadClass(className);</span>
-<span class="source-line-no">169</span><span id="line-169">        int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;</span>
-<span class="source-line-no">170</span><span id="line-170">        // Add coprocessors as we go to guard against case where a coprocessor is specified twice</span>
-<span class="source-line-no">171</span><span id="line-171">        // in the configuration</span>
-<span class="source-line-no">172</span><span id="line-172">        E env = checkAndLoadInstance(implClass, coprocPriority, conf);</span>
-<span class="source-line-no">173</span><span id="line-173">        if (env != null) {</span>
-<span class="source-line-no">174</span><span id="line-174">          this.coprocEnvironments.add(env);</span>
-<span class="source-line-no">175</span><span id="line-175">          LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);</span>
-<span class="source-line-no">176</span><span id="line-176">          if (!hasPriorityOverride) {</span>
-<span class="source-line-no">177</span><span id="line-177">            ++currentSystemPriority;</span>
-<span class="source-line-no">178</span><span id="line-178">          }</span>
-<span class="source-line-no">179</span><span id="line-179">        }</span>
-<span class="source-line-no">180</span><span id="line-180">      } catch (Throwable t) {</span>
-<span class="source-line-no">181</span><span id="line-181">        // We always abort if system coprocessors cannot be loaded</span>
-<span class="source-line-no">182</span><span id="line-182">        abortServer(className, t);</span>
-<span class="source-line-no">183</span><span id="line-183">      }</span>
-<span class="source-line-no">184</span><span id="line-184">    }</span>
-<span class="source-line-no">185</span><span id="line-185">  }</span>
-<span class="source-line-no">186</span><span id="line-186"></span>
-<span class="source-line-no">187</span><span id="line-187">  /**</span>
-<span class="source-line-no">188</span><span id="line-188">   * Load a coprocessor implementation into the host</span>
-<span class="source-line-no">189</span><span id="line-189">   * @param path      path to implementation jar</span>
-<span class="source-line-no">190</span><span id="line-190">   * @param className the main class name</span>
-<span class="source-line-no">191</span><span id="line-191">   * @param priority  chaining priority</span>
-<span class="source-line-no">192</span><span id="line-192">   * @param conf      configuration for coprocessor</span>
-<span class="source-line-no">193</span><span id="line-193">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">194</span><span id="line-194">   */</span>
-<span class="source-line-no">195</span><span id="line-195">  public E load(Path path, String className, int priority, Configuration conf) throws IOException {</span>
-<span class="source-line-no">196</span><span id="line-196">    String[] includedClassPrefixes = null;</span>
-<span class="source-line-no">197</span><span id="line-197">    if (conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY) != null) {</span>
-<span class="source-line-no">198</span><span id="line-198">      String prefixes = conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY);</span>
-<span class="source-line-no">199</span><span id="line-199">      includedClassPrefixes = prefixes.split(";");</span>
-<span class="source-line-no">200</span><span id="line-200">    }</span>
-<span class="source-line-no">201</span><span id="line-201">    return load(path, className, priority, conf, includedClassPrefixes);</span>
-<span class="source-line-no">202</span><span id="line-202">  }</span>
-<span class="source-line-no">203</span><span id="line-203"></span>
-<span class="source-line-no">204</span><span id="line-204">  /**</span>
-<span class="source-line-no">205</span><span id="line-205">   * Load a coprocessor implementation into the host</span>
-<span class="source-line-no">206</span><span id="line-206">   * @param path                  path to implementation jar</span>
-<span class="source-line-no">207</span><span id="line-207">   * @param className             the main class name</span>
-<span class="source-line-no">208</span><span id="line-208">   * @param priority              chaining priority</span>
-<span class="source-line-no">209</span><span id="line-209">   * @param conf                  configuration for coprocessor</span>
-<span class="source-line-no">210</span><span id="line-210">   * @param includedClassPrefixes class name prefixes to include</span>
-<span class="source-line-no">211</span><span id="line-211">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">212</span><span id="line-212">   */</span>
-<span class="source-line-no">213</span><span id="line-213">  public E load(Path path, String className, int priority, Configuration conf,</span>
-<span class="source-line-no">214</span><span id="line-214">    String[] includedClassPrefixes) throws IOException {</span>
-<span class="source-line-no">215</span><span id="line-215">    Class&lt;?&gt; implClass;</span>
-<span class="source-line-no">216</span><span id="line-216">    LOG.debug("Loading coprocessor class " + className + " with path " + path + " and priority "</span>
-<span class="source-line-no">217</span><span id="line-217">      + priority);</span>
-<span class="source-line-no">218</span><span id="line-218"></span>
-<span class="source-line-no">219</span><span id="line-219">    boolean skipLoadDuplicateCoprocessor = conf.getBoolean(SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR,</span>
-<span class="source-line-no">220</span><span id="line-220">      DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR);</span>
-<span class="source-line-no">221</span><span id="line-221">    if (skipLoadDuplicateCoprocessor &amp;&amp; findCoprocessor(className) != null) {</span>
-<span class="source-line-no">222</span><span id="line-222">      // If already loaded will just continue</span>
-<span class="source-line-no">223</span><span id="line-223">      LOG.warn("Attempted duplicate loading of {}; skipped", className);</span>
-<span class="source-line-no">224</span><span id="line-224">      return null;</span>
-<span class="source-line-no">225</span><span id="line-225">    }</span>
-<span class="source-line-no">226</span><span id="line-226"></span>
-<span class="source-line-no">227</span><span id="line-227">    ClassLoader cl = null;</span>
-<span class="source-line-no">228</span><span id="line-228">    if (path == null) {</span>
-<span class="source-line-no">229</span><span id="line-229">      try {</span>
-<span class="source-line-no">230</span><span id="line-230">        implClass = getClass().getClassLoader().loadClass(className);</span>
-<span class="source-line-no">231</span><span id="line-231">      } catch (ClassNotFoundException e) {</span>
-<span class="source-line-no">232</span><span id="line-232">        throw new IOException("No jar path specified for " + className);</span>
-<span class="source-line-no">233</span><span id="line-233">      }</span>
-<span class="source-line-no">234</span><span id="line-234">    } else {</span>
-<span class="source-line-no">235</span><span id="line-235">      cl =</span>
-<span class="source-line-no">236</span><span id="line-236">        CoprocessorClassLoader.getClassLoader(path, getClass().getClassLoader(), pathPrefix, conf);</span>
-<span class="source-line-no">237</span><span id="line-237">      try {</span>
-<span class="source-line-no">238</span><span id="line-238">        implClass = ((CoprocessorClassLoader) cl).loadClass(className, includedClassPrefixes);</span>
-<span class="source-line-no">239</span><span id="line-239">      } catch (ClassNotFoundException e) {</span>
-<span class="source-line-no">240</span><span id="line-240">        throw new IOException("Cannot load external coprocessor class " + className, e);</span>
-<span class="source-line-no">241</span><span id="line-241">      }</span>
-<span class="source-line-no">242</span><span id="line-242">    }</span>
-<span class="source-line-no">243</span><span id="line-243"></span>
-<span class="source-line-no">244</span><span id="line-244">    // load custom code for coprocessor</span>
-<span class="source-line-no">245</span><span id="line-245">    Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">246</span><span id="line-246">    ClassLoader hostClassLoader = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">247</span><span id="line-247">    try {</span>
-<span class="source-line-no">248</span><span id="line-248">      // switch temporarily to the thread classloader for custom CP</span>
-<span class="source-line-no">249</span><span id="line-249">      currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">250</span><span id="line-250">      E cpInstance = checkAndLoadInstance(implClass, priority, conf);</span>
-<span class="source-line-no">251</span><span id="line-251">      return cpInstance;</span>
-<span class="source-line-no">252</span><span id="line-252">    } finally {</span>
-<span class="source-line-no">253</span><span id="line-253">      // restore the fresh (host) classloader</span>
-<span class="source-line-no">254</span><span id="line-254">      currentThread.setContextClassLoader(hostClassLoader);</span>
-<span class="source-line-no">255</span><span id="line-255">    }</span>
-<span class="source-line-no">256</span><span id="line-256">  }</span>
-<span class="source-line-no">257</span><span id="line-257"></span>
-<span class="source-line-no">258</span><span id="line-258">  public void load(Class&lt;? extends C&gt; implClass, int priority, Configuration conf)</span>
-<span class="source-line-no">259</span><span id="line-259">    throws IOException {</span>
-<span class="source-line-no">260</span><span id="line-260">    E env = checkAndLoadInstance(implClass, priority, conf);</span>
-<span class="source-line-no">261</span><span id="line-261">    coprocEnvironments.add(env);</span>
-<span class="source-line-no">262</span><span id="line-262">  }</span>
-<span class="source-line-no">263</span><span id="line-263"></span>
-<span class="source-line-no">264</span><span id="line-264">  /**</span>
-<span class="source-line-no">265</span><span id="line-265">   * @param implClass Implementation class</span>
-<span class="source-line-no">266</span><span id="line-266">   * @param priority  priority</span>
-<span class="source-line-no">267</span><span id="line-267">   * @param conf      configuration</span>
-<span class="source-line-no">268</span><span id="line-268">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">269</span><span id="line-269">   */</span>
-<span class="source-line-no">270</span><span id="line-270">  public E checkAndLoadInstance(Class&lt;?&gt; implClass, int priority, Configuration conf)</span>
-<span class="source-line-no">271</span><span id="line-271">    throws IOException {</span>
-<span class="source-line-no">272</span><span id="line-272">    // create the instance</span>
-<span class="source-line-no">273</span><span id="line-273">    C impl;</span>
-<span class="source-line-no">274</span><span id="line-274">    try {</span>
-<span class="source-line-no">275</span><span id="line-275">      impl = checkAndGetInstance(implClass);</span>
-<span class="source-line-no">276</span><span id="line-276">      if (impl == null) {</span>
-<span class="source-line-no">277</span><span id="line-277">        LOG.error("Cannot load coprocessor " + implClass.getSimpleName());</span>
-<span class="source-line-no">278</span><span id="line-278">        return null;</span>
-<span class="source-line-no">279</span><span id="line-279">      }</span>
-<span class="source-line-no">280</span><span id="line-280">    } catch (InstantiationException | IllegalAccessException e) {</span>
-<span class="source-line-no">281</span><span id="line-281">      throw new IOException(e);</span>
-<span class="source-line-no">282</span><span id="line-282">    }</span>
-<span class="source-line-no">283</span><span id="line-283">    // create the environment</span>
-<span class="source-line-no">284</span><span id="line-284">    E env = createEnvironment(impl, priority, loadSequence.incrementAndGet(), conf);</span>
-<span class="source-line-no">285</span><span id="line-285">    assert env instanceof BaseEnvironment;</span>
-<span class="source-line-no">286</span><span id="line-286">    ((BaseEnvironment&lt;C&gt;) env).startup();</span>
-<span class="source-line-no">287</span><span id="line-287">    // HBASE-4014: maintain list of loaded coprocessors for later crash analysis</span>
-<span class="source-line-no">288</span><span id="line-288">    // if server (master or regionserver) aborts.</span>
-<span class="source-line-no">289</span><span id="line-289">    coprocessorNames.add(implClass.getName());</span>
-<span class="source-line-no">290</span><span id="line-290">    return env;</span>
-<span class="source-line-no">291</span><span id="line-291">  }</span>
-<span class="source-line-no">292</span><span id="line-292"></span>
-<span class="source-line-no">293</span><span id="line-293">  /**</span>
-<span class="source-line-no">294</span><span id="line-294">   * Called when a new Coprocessor class is loaded</span>
-<span class="source-line-no">295</span><span id="line-295">   */</span>
-<span class="source-line-no">296</span><span id="line-296">  public abstract E createEnvironment(C instance, int priority, int sequence, Configuration conf);</span>
-<span class="source-line-no">297</span><span id="line-297"></span>
-<span class="source-line-no">298</span><span id="line-298">  /**</span>
-<span class="source-line-no">299</span><span id="line-299">   * Called when a new Coprocessor class needs to be loaded. Checks if type of the given class is</span>
-<span class="source-line-no">300</span><span id="line-300">   * what the corresponding host implementation expects. If it is of correct type, returns an</span>
-<span class="source-line-no">301</span><span id="line-301">   * instance of the coprocessor to be loaded. If not, returns null. If an exception occurs when</span>
-<span class="source-line-no">302</span><span id="line-302">   * trying to create instance of a coprocessor, it's passed up and eventually results into server</span>
-<span class="source-line-no">303</span><span id="line-303">   * aborting.</span>
-<span class="source-line-no">304</span><span id="line-304">   */</span>
-<span class="source-line-no">305</span><span id="line-305">  public abstract C checkAndGetInstance(Class&lt;?&gt; implClass)</span>
-<span class="source-line-no">306</span><span id="line-306">    throws InstantiationException, IllegalAccessException;</span>
-<span class="source-line-no">307</span><span id="line-307"></span>
-<span class="source-line-no">308</span><span id="line-308">  public void shutdown(E e) {</span>
-<span class="source-line-no">309</span><span id="line-309">    assert e instanceof BaseEnvironment;</span>
-<span class="source-line-no">310</span><span id="line-310">    if (LOG.isDebugEnabled()) {</span>
-<span class="source-line-no">311</span><span id="line-311">      LOG.debug("Stop coprocessor " + e.getInstance().getClass().getName());</span>
-<span class="source-line-no">312</span><span id="line-312">    }</span>
-<span class="source-line-no">313</span><span id="line-313">    ((BaseEnvironment&lt;C&gt;) e).shutdown();</span>
-<span class="source-line-no">314</span><span id="line-314">  }</span>
-<span class="source-line-no">315</span><span id="line-315"></span>
-<span class="source-line-no">316</span><span id="line-316">  /**</span>
-<span class="source-line-no">317</span><span id="line-317">   * Find coprocessors by full class name or simple name.</span>
-<span class="source-line-no">318</span><span id="line-318">   */</span>
-<span class="source-line-no">319</span><span id="line-319">  public C findCoprocessor(String className) {</span>
-<span class="source-line-no">320</span><span id="line-320">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">321</span><span id="line-321">      if (</span>
-<span class="source-line-no">322</span><span id="line-322">        env.getInstance().getClass().getName().equals(className)</span>
-<span class="source-line-no">323</span><span id="line-323">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
-<span class="source-line-no">324</span><span id="line-324">      ) {</span>
-<span class="source-line-no">325</span><span id="line-325">        return env.getInstance();</span>
-<span class="source-line-no">326</span><span id="line-326">      }</span>
-<span class="source-line-no">327</span><span id="line-327">    }</span>
-<span class="source-line-no">328</span><span id="line-328">    return null;</span>
-<span class="source-line-no">329</span><span id="line-329">  }</span>
-<span class="source-line-no">330</span><span id="line-330"></span>
-<span class="source-line-no">331</span><span id="line-331">  public &lt;T extends C&gt; T findCoprocessor(Class&lt;T&gt; cls) {</span>
-<span class="source-line-no">332</span><span id="line-332">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">333</span><span id="line-333">      if (cls.isAssignableFrom(env.getInstance().getClass())) {</span>
-<span class="source-line-no">334</span><span id="line-334">        return (T) env.getInstance();</span>
-<span class="source-line-no">335</span><span id="line-335">      }</span>
-<span class="source-line-no">336</span><span id="line-336">    }</span>
-<span class="source-line-no">337</span><span id="line-337">    return null;</span>
-<span class="source-line-no">338</span><span id="line-338">  }</span>
-<span class="source-line-no">339</span><span id="line-339"></span>
-<span class="source-line-no">340</span><span id="line-340">  /**</span>
-<span class="source-line-no">341</span><span id="line-341">   * Find list of coprocessors that extend/implement the given class/interface</span>
-<span class="source-line-no">342</span><span id="line-342">   * @param cls the class/interface to look for</span>
-<span class="source-line-no">343</span><span id="line-343">   * @return the list of coprocessors, or null if not found</span>
-<span class="source-line-no">344</span><span id="line-344">   */</span>
-<span class="source-line-no">345</span><span id="line-345">  public &lt;T extends C&gt; List&lt;T&gt; findCoprocessors(Class&lt;T&gt; cls) {</span>
-<span class="source-line-no">346</span><span id="line-346">    ArrayList&lt;T&gt; ret = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">347</span><span id="line-347"></span>
-<span class="source-line-no">348</span><span id="line-348">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">349</span><span id="line-349">      C cp = env.getInstance();</span>
-<span class="source-line-no">350</span><span id="line-350"></span>
-<span class="source-line-no">351</span><span id="line-351">      if (cp != null) {</span>
-<span class="source-line-no">352</span><span id="line-352">        if (cls.isAssignableFrom(cp.getClass())) {</span>
-<span class="source-line-no">353</span><span id="line-353">          ret.add((T) cp);</span>
-<span class="source-line-no">354</span><span id="line-354">        }</span>
-<span class="source-line-no">355</span><span id="line-355">      }</span>
-<span class="source-line-no">356</span><span id="line-356">    }</span>
-<span class="source-line-no">357</span><span id="line-357">    return ret;</span>
-<span class="source-line-no">358</span><span id="line-358">  }</span>
-<span class="source-line-no">359</span><span id="line-359"></span>
-<span class="source-line-no">360</span><span id="line-360">  /**</span>
-<span class="source-line-no">361</span><span id="line-361">   * Find a coprocessor environment by class name</span>
-<span class="source-line-no">362</span><span id="line-362">   * @param className the class name</span>
-<span class="source-line-no">363</span><span id="line-363">   * @return the coprocessor, or null if not found</span>
-<span class="source-line-no">364</span><span id="line-364">   */</span>
-<span class="source-line-no">365</span><span id="line-365">  public E findCoprocessorEnvironment(String className) {</span>
-<span class="source-line-no">366</span><span id="line-366">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">367</span><span id="line-367">      if (</span>
-<span class="source-line-no">368</span><span id="line-368">        env.getInstance().getClass().getName().equals(className)</span>
-<span class="source-line-no">369</span><span id="line-369">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
-<span class="source-line-no">370</span><span id="line-370">      ) {</span>
-<span class="source-line-no">371</span><span id="line-371">        return env;</span>
-<span class="source-line-no">372</span><span id="line-372">      }</span>
-<span class="source-line-no">373</span><span id="line-373">    }</span>
-<span class="source-line-no">374</span><span id="line-374">    return null;</span>
-<span class="source-line-no">375</span><span id="line-375">  }</span>
-<span class="source-line-no">376</span><span id="line-376"></span>
-<span class="source-line-no">377</span><span id="line-377">  /**</span>
-<span class="source-line-no">378</span><span id="line-378">   * Retrieves the set of classloaders used to instantiate Coprocessor classes defined in external</span>
-<span class="source-line-no">379</span><span id="line-379">   * jar files.</span>
-<span class="source-line-no">380</span><span id="line-380">   * @return A set of ClassLoader instances</span>
-<span class="source-line-no">381</span><span id="line-381">   */</span>
-<span class="source-line-no">382</span><span id="line-382">  Set&lt;ClassLoader&gt; getExternalClassLoaders() {</span>
-<span class="source-line-no">383</span><span id="line-383">    Set&lt;ClassLoader&gt; externalClassLoaders = new HashSet&lt;&gt;();</span>
-<span class="source-line-no">384</span><span id="line-384">    final ClassLoader systemClassLoader = this.getClass().getClassLoader();</span>
-<span class="source-line-no">385</span><span id="line-385">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">386</span><span id="line-386">      ClassLoader cl = env.getInstance().getClass().getClassLoader();</span>
-<span class="source-line-no">387</span><span id="line-387">      if (cl != systemClassLoader) {</span>
-<span class="source-line-no">388</span><span id="line-388">        // do not include system classloader</span>
-<span class="source-line-no">389</span><span id="line-389">        externalClassLoaders.add(cl);</span>
-<span class="source-line-no">390</span><span id="line-390">      }</span>
-<span class="source-line-no">391</span><span id="line-391">    }</span>
-<span class="source-line-no">392</span><span id="line-392">    return externalClassLoaders;</span>
-<span class="source-line-no">393</span><span id="line-393">  }</span>
-<span class="source-line-no">394</span><span id="line-394"></span>
-<span class="source-line-no">395</span><span id="line-395">  /**</span>
-<span class="source-line-no">396</span><span id="line-396">   * Environment priority comparator. Coprocessors are chained in sorted order.</span>
-<span class="source-line-no">397</span><span id="line-397">   */</span>
-<span class="source-line-no">398</span><span id="line-398">  static class EnvironmentPriorityComparator implements Comparator&lt;CoprocessorEnvironment&gt; {</span>
-<span class="source-line-no">399</span><span id="line-399">    @Override</span>
-<span class="source-line-no">400</span><span id="line-400">    public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) {</span>
-<span class="source-line-no">401</span><span id="line-401">      if (env1.getPriority() &lt; env2.getPriority()) {</span>
-<span class="source-line-no">402</span><span id="line-402">        return -1;</span>
-<span class="source-line-no">403</span><span id="line-403">      } else if (env1.getPriority() &gt; env2.getPriority()) {</span>
-<span class="source-line-no">404</span><span id="line-404">        return 1;</span>
-<span class="source-line-no">405</span><span id="line-405">      }</span>
-<span class="source-line-no">406</span><span id="line-406">      if (env1.getLoadSequence() &lt; env2.getLoadSequence()) {</span>
-<span class="source-line-no">407</span><span id="line-407">        return -1;</span>
-<span class="source-line-no">408</span><span id="line-408">      } else if (env1.getLoadSequence() &gt; env2.getLoadSequence()) {</span>
-<span class="source-line-no">409</span><span id="line-409">        return 1;</span>
-<span class="source-line-no">410</span><span id="line-410">      }</span>
-<span class="source-line-no">411</span><span id="line-411">      return 0;</span>
-<span class="source-line-no">412</span><span id="line-412">    }</span>
-<span class="source-line-no">413</span><span id="line-413">  }</span>
-<span class="source-line-no">414</span><span id="line-414"></span>
-<span class="source-line-no">415</span><span id="line-415">  protected void abortServer(final E environment, final Throwable e) {</span>
-<span class="source-line-no">416</span><span id="line-416">    abortServer(environment.getInstance().getClass().getName(), e);</span>
-<span class="source-line-no">417</span><span id="line-417">  }</span>
-<span class="source-line-no">418</span><span id="line-418"></span>
-<span class="source-line-no">419</span><span id="line-419">  protected void abortServer(final String coprocessorName, final Throwable e) {</span>
-<span class="source-line-no">420</span><span id="line-420">    String message = "The coprocessor " + coprocessorName + " threw " + e.toString();</span>
-<span class="source-line-no">421</span><span id="line-421">    LOG.error(message, e);</span>
-<span class="source-line-no">422</span><span id="line-422">    if (abortable != null) {</span>
-<span class="source-line-no">423</span><span id="line-423">      abortable.abort(message, e);</span>
-<span class="source-line-no">424</span><span id="line-424">    } else {</span>
-<span class="source-line-no">425</span><span id="line-425">      LOG.warn("No available Abortable, process was not aborted");</span>
-<span class="source-line-no">426</span><span id="line-426">    }</span>
-<span class="source-line-no">427</span><span id="line-427">  }</span>
-<span class="source-line-no">428</span><span id="line-428"></span>
-<span class="source-line-no">429</span><span id="line-429">  /**</span>
-<span class="source-line-no">430</span><span id="line-430">   * This is used by coprocessor hooks which are declared to throw IOException (or its subtypes).</span>
-<span class="source-line-no">431</span><span id="line-431">   * For such hooks, we should handle throwable objects depending on the Throwable's type. Those</span>
-<span class="source-line-no">432</span><span id="line-432">   * which are instances of IOException should be passed on to the client. This is in conformance</span>
-<span class="source-line-no">433</span><span id="line-433">   * with the HBase idiom regarding IOException: that it represents a circumstance that should be</span>
-<span class="source-line-no">434</span><span id="line-434">   * passed along to the client for its own handling. For example, a coprocessor that implements</span>
-<span class="source-line-no">435</span><span id="line-435">   * access controls would throw a subclass of IOException, such as AccessDeniedException, in its</span>
-<span class="source-line-no">436</span><span id="line-436">   * preGet() method to prevent an unauthorized client's performing a Get on a particular table.</span>
-<span class="source-line-no">437</span><span id="line-437">   * @param env Coprocessor Environment</span>
-<span class="source-line-no">438</span><span id="line-438">   * @param e   Throwable object thrown by coprocessor.</span>
-<span class="source-line-no">439</span><span id="line-439">   * @exception IOException Exception</span>
-<span class="source-line-no">440</span><span id="line-440">   */</span>
-<span class="source-line-no">441</span><span id="line-441">  // Note to devs: Class comments of all observers ({@link MasterObserver}, {@link WALObserver},</span>
-<span class="source-line-no">442</span><span id="line-442">  // etc) mention this nuance of our exception handling so that coprocessor can throw appropriate</span>
-<span class="source-line-no">443</span><span id="line-443">  // exceptions depending on situation. If any changes are made to this logic, make sure to</span>
-<span class="source-line-no">444</span><span id="line-444">  // update all classes' comments.</span>
-<span class="source-line-no">445</span><span id="line-445">  protected void handleCoprocessorThrowable(final E env, final Throwable e) throws IOException {</span>
-<span class="source-line-no">446</span><span id="line-446">    if (e instanceof IOException) {</span>
-<span class="source-line-no">447</span><span id="line-447">      throw (IOException) e;</span>
-<span class="source-line-no">448</span><span id="line-448">    }</span>
-<span class="source-line-no">449</span><span id="line-449">    // If we got here, e is not an IOException. A loaded coprocessor has a</span>
-<span class="source-line-no">450</span><span id="line-450">    // fatal bug, and the server (master or regionserver) should remove the</span>
-<span class="source-line-no">451</span><span id="line-451">    // faulty coprocessor from its set of active coprocessors. Setting</span>
-<span class="source-line-no">452</span><span id="line-452">    // 'hbase.coprocessor.abortonerror' to true will cause abortServer(),</span>
-<span class="source-line-no">453</span><span id="line-453">    // which may be useful in development and testing environments where</span>
-<span class="source-line-no">454</span><span id="line-454">    // 'failing fast' for error analysis is desired.</span>
-<span class="source-line-no">455</span><span id="line-455">    if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) {</span>
-<span class="source-line-no">456</span><span id="line-456">      // server is configured to abort.</span>
-<span class="source-line-no">457</span><span id="line-457">      abortServer(env, e);</span>
-<span class="source-line-no">458</span><span id="line-458">    } else {</span>
-<span class="source-line-no">459</span><span id="line-459">      // If available, pull a table name out of the environment</span>
-<span class="source-line-no">460</span><span id="line-460">      if (env instanceof RegionCoprocessorEnvironment) {</span>
-<span class="source-line-no">461</span><span id="line-461">        String tableName =</span>
-<span class="source-line-no">462</span><span id="line-462">          ((RegionCoprocessorEnvironment) env).getRegionInfo().getTable().getNameAsString();</span>
-<span class="source-line-no">463</span><span id="line-463">        LOG.error("Removing coprocessor '" + env.toString() + "' from table '" + tableName + "'",</span>
-<span class="source-line-no">464</span><span id="line-464">          e);</span>
-<span class="source-line-no">465</span><span id="line-465">      } else {</span>
-<span class="source-line-no">466</span><span id="line-466">        LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment", e);</span>
-<span class="source-line-no">467</span><span id="line-467">      }</span>
-<span class="source-line-no">468</span><span id="line-468"></span>
-<span class="source-line-no">469</span><span id="line-469">      coprocEnvironments.remove(env);</span>
-<span class="source-line-no">470</span><span id="line-470">      try {</span>
-<span class="source-line-no">471</span><span id="line-471">        shutdown(env);</span>
-<span class="source-line-no">472</span><span id="line-472">      } catch (Exception x) {</span>
-<span class="source-line-no">473</span><span id="line-473">        LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x);</span>
-<span class="source-line-no">474</span><span id="line-474">      }</span>
-<span class="source-line-no">475</span><span id="line-475">      throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e</span>
-<span class="source-line-no">476</span><span id="line-476">        + "' and has been removed from the active " + "coprocessor set.", e);</span>
-<span class="source-line-no">477</span><span id="line-477">    }</span>
-<span class="source-line-no">478</span><span id="line-478">  }</span>
-<span class="source-line-no">479</span><span id="line-479"></span>
-<span class="source-line-no">480</span><span id="line-480">  /**</span>
-<span class="source-line-no">481</span><span id="line-481">   * Used to limit legacy handling to once per Coprocessor class per classloader.</span>
-<span class="source-line-no">482</span><span id="line-482">   */</span>
-<span class="source-line-no">483</span><span id="line-483">  private static final Set&lt;Class&lt;? extends Coprocessor&gt;&gt; legacyWarning =</span>
-<span class="source-line-no">484</span><span id="line-484">    new ConcurrentSkipListSet&lt;&gt;(new Comparator&lt;Class&lt;? extends Coprocessor&gt;&gt;() {</span>
-<span class="source-line-no">485</span><span id="line-485">      @Override</span>
-<span class="source-line-no">486</span><span id="line-486">      public int compare(Class&lt;? extends Coprocessor&gt; c1, Class&lt;? extends Coprocessor&gt; c2) {</span>
-<span class="source-line-no">487</span><span id="line-487">        if (c1.equals(c2)) {</span>
-<span class="source-line-no">488</span><span id="line-488">          return 0;</span>
-<span class="source-line-no">489</span><span id="line-489">        }</span>
-<span class="source-line-no">490</span><span id="line-490">        return c1.getName().compareTo(c2.getName());</span>
-<span class="source-line-no">491</span><span id="line-491">      }</span>
-<span class="source-line-no">492</span><span id="line-492">    });</span>
-<span class="source-line-no">493</span><span id="line-493"></span>
-<span class="source-line-no">494</span><span id="line-494">  /**</span>
-<span class="source-line-no">495</span><span id="line-495">   * Implementations defined function to get an observer of type {@code O} from a coprocessor of</span>
-<span class="source-line-no">496</span><span id="line-496">   * type {@code C}. Concrete implementations of CoprocessorHost define one getter for each observer</span>
-<span class="source-line-no">497</span><span id="line-497">   * they can handle. For e.g. RegionCoprocessorHost will use 3 getters, one for each of</span>
-<span class="source-line-no">498</span><span id="line-498">   * RegionObserver, EndpointObserver and BulkLoadObserver. These getters are used by</span>
-<span class="source-line-no">499</span><span id="line-499">   * {@code ObserverOperation} to get appropriate observer from the coprocessor.</span>
-<span class="source-line-no">500</span><span id="line-500">   */</span>
-<span class="source-line-no">501</span><span id="line-501">  @FunctionalInterface</span>
-<span class="source-line-no">502</span><span id="line-502">  public interface ObserverGetter&lt;C, O&gt; extends Function&lt;C, Optional&lt;O&gt;&gt; {</span>
-<span class="source-line-no">503</span><span id="line-503">  }</span>
-<span class="source-line-no">504</span><span id="line-504"></span>
-<span class="source-line-no">505</span><span id="line-505">  private abstract class ObserverOperation&lt;O&gt; extends ObserverContextImpl&lt;E&gt; {</span>
-<span class="source-line-no">506</span><span id="line-506">    ObserverGetter&lt;C, O&gt; observerGetter;</span>
-<span class="source-line-no">507</span><span id="line-507"></span>
-<span class="source-line-no">508</span><span id="line-508">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
-<span class="source-line-no">509</span><span id="line-509">      this(observerGetter, null);</span>
-<span class="source-line-no">510</span><span id="line-510">    }</span>
-<span class="source-line-no">511</span><span id="line-511"></span>
-<span class="source-line-no">512</span><span id="line-512">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
-<span class="source-line-no">513</span><span id="line-513">      this(observerGetter, user, false);</span>
-<span class="source-line-no">514</span><span id="line-514">    }</span>
-<span class="source-line-no">515</span><span id="line-515"></span>
-<span class="source-line-no">516</span><span id="line-516">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, boolean bypassable) {</span>
-<span class="source-line-no">517</span><span id="line-517">      this(observerGetter, null, bypassable);</span>
-<span class="source-line-no">518</span><span id="line-518">    }</span>
-<span class="source-line-no">519</span><span id="line-519"></span>
-<span class="source-line-no">520</span><span id="line-520">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user, boolean bypassable) {</span>
-<span class="source-line-no">521</span><span id="line-521">      super(user != null ? user : RpcServer.getRequestUser().orElse(null), bypassable);</span>
-<span class="source-line-no">522</span><span id="line-522">      this.observerGetter = observerGetter;</span>
-<span class="source-line-no">523</span><span id="line-523">    }</span>
-<span class="source-line-no">524</span><span id="line-524"></span>
-<span class="source-line-no">525</span><span id="line-525">    abstract void callObserver() throws IOException;</span>
+<span class="source-line-no">132</span><span id="line-132">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">133</span><span id="line-133"></span>
+<span class="source-line-no">134</span><span id="line-134">    // load default coprocessors from configure file</span>
+<span class="source-line-no">135</span><span id="line-135">    String[] defaultCPClasses = conf.getStrings(confKey);</span>
+<span class="source-line-no">136</span><span id="line-136">    if (defaultCPClasses == null || defaultCPClasses.length == 0) return;</span>
+<span class="source-line-no">137</span><span id="line-137"></span>
+<span class="source-line-no">138</span><span id="line-138">    int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;</span>
+<span class="source-line-no">139</span><span id="line-139">    for (String className : defaultCPClasses) {</span>
+<span class="source-line-no">140</span><span id="line-140">      // After HBASE-23710 and HBASE-26714 when configuring for system coprocessor, we accept</span>
+<span class="source-line-no">141</span><span id="line-141">      // an optional format of className|priority|path</span>
+<span class="source-line-no">142</span><span id="line-142">      String[] classNameToken = className.split("\\|");</span>
+<span class="source-line-no">143</span><span id="line-143">      boolean hasPriorityOverride = false;</span>
+<span class="source-line-no">144</span><span id="line-144">      boolean hasPath = false;</span>
+<span class="source-line-no">145</span><span id="line-145">      className = classNameToken[0];</span>
+<span class="source-line-no">146</span><span id="line-146">      int overridePriority = Coprocessor.PRIORITY_SYSTEM;</span>
+<span class="source-line-no">147</span><span id="line-147">      Path path = null;</span>
+<span class="source-line-no">148</span><span id="line-148">      if (classNameToken.length &gt; 1 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[1])) {</span>
+<span class="source-line-no">149</span><span id="line-149">        overridePriority = Integer.parseInt(classNameToken[1]);</span>
+<span class="source-line-no">150</span><span id="line-150">        hasPriorityOverride = true;</span>
+<span class="source-line-no">151</span><span id="line-151">      }</span>
+<span class="source-line-no">152</span><span id="line-152">      if (classNameToken.length &gt; 2 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[2])) {</span>
+<span class="source-line-no">153</span><span id="line-153">        path = new Path(classNameToken[2].trim());</span>
+<span class="source-line-no">154</span><span id="line-154">        hasPath = true;</span>
+<span class="source-line-no">155</span><span id="line-155">      }</span>
+<span class="source-line-no">156</span><span id="line-156">      className = className.trim();</span>
+<span class="source-line-no">157</span><span id="line-157">      if (findCoprocessor(className) != null) {</span>
+<span class="source-line-no">158</span><span id="line-158">        // If already loaded will just continue</span>
+<span class="source-line-no">159</span><span id="line-159">        LOG.warn("Attempted duplicate loading of " + className + "; skipped");</span>
+<span class="source-line-no">160</span><span id="line-160">        continue;</span>
+<span class="source-line-no">161</span><span id="line-161">      }</span>
+<span class="source-line-no">162</span><span id="line-162">      ClassLoader cl = this.getClass().getClassLoader();</span>
+<span class="source-line-no">163</span><span id="line-163">      try {</span>
+<span class="source-line-no">164</span><span id="line-164">        // override the class loader if a path for the system coprocessor is provided.</span>
+<span class="source-line-no">165</span><span id="line-165">        if (hasPath) {</span>
+<span class="source-line-no">166</span><span id="line-166">          cl = CoprocessorClassLoader.getClassLoader(path, this.getClass().getClassLoader(),</span>
+<span class="source-line-no">167</span><span id="line-167">            pathPrefix, conf);</span>
+<span class="source-line-no">168</span><span id="line-168">        }</span>
+<span class="source-line-no">169</span><span id="line-169">        Thread.currentThread().setContextClassLoader(cl);</span>
+<span class="source-line-no">170</span><span id="line-170">        implClass = cl.loadClass(className);</span>
+<span class="source-line-no">171</span><span id="line-171">        int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;</span>
+<span class="source-line-no">172</span><span id="line-172">        // Add coprocessors as we go to guard against case where a coprocessor is specified twice</span>
+<span class="source-line-no">173</span><span id="line-173">        // in the configuration</span>
+<span class="source-line-no">174</span><span id="line-174">        E env = checkAndLoadInstance(implClass, coprocPriority, conf);</span>
+<span class="source-line-no">175</span><span id="line-175">        if (env != null) {</span>
+<span class="source-line-no">176</span><span id="line-176">          this.coprocEnvironments.add(env);</span>
+<span class="source-line-no">177</span><span id="line-177">          LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);</span>
+<span class="source-line-no">178</span><span id="line-178">          if (!hasPriorityOverride) {</span>
+<span class="source-line-no">179</span><span id="line-179">            ++currentSystemPriority;</span>
+<span class="source-line-no">180</span><span id="line-180">          }</span>
+<span class="source-line-no">181</span><span id="line-181">        }</span>
+<span class="source-line-no">182</span><span id="line-182">      } catch (Throwable t) {</span>
+<span class="source-line-no">183</span><span id="line-183">        // We always abort if system coprocessors cannot be loaded</span>
+<span class="source-line-no">184</span><span id="line-184">        abortServer(className, t);</span>
+<span class="source-line-no">185</span><span id="line-185">      }</span>
+<span class="source-line-no">186</span><span id="line-186">    }</span>
+<span class="source-line-no">187</span><span id="line-187">  }</span>
+<span class="source-line-no">188</span><span id="line-188"></span>
+<span class="source-line-no">189</span><span id="line-189">  /**</span>
+<span class="source-line-no">190</span><span id="line-190">   * Load a coprocessor implementation into the host</span>
+<span class="source-line-no">191</span><span id="line-191">   * @param path      path to implementation jar</span>
+<span class="source-line-no">192</span><span id="line-192">   * @param className the main class name</span>
+<span class="source-line-no">193</span><span id="line-193">   * @param priority  chaining priority</span>
+<span class="source-line-no">194</span><span id="line-194">   * @param conf      configuration for coprocessor</span>
+<span class="source-line-no">195</span><span id="line-195">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">196</span><span id="line-196">   */</span>
+<span class="source-line-no">197</span><span id="line-197">  public E load(Path path, String className, int priority, Configuration conf) throws IOException {</span>
+<span class="source-line-no">198</span><span id="line-198">    String[] includedClassPrefixes = null;</span>
+<span class="source-line-no">199</span><span id="line-199">    if (conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY) != null) {</span>
+<span class="source-line-no">200</span><span id="line-200">      String prefixes = conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY);</span>
+<span class="source-line-no">201</span><span id="line-201">      includedClassPrefixes = prefixes.split(";");</span>
+<span class="source-line-no">202</span><span id="line-202">    }</span>
+<span class="source-line-no">203</span><span id="line-203">    return load(path, className, priority, conf, includedClassPrefixes);</span>
+<span class="source-line-no">204</span><span id="line-204">  }</span>
+<span class="source-line-no">205</span><span id="line-205"></span>
+<span class="source-line-no">206</span><span id="line-206">  /**</span>
+<span class="source-line-no">207</span><span id="line-207">   * Load a coprocessor implementation into the host</span>
+<span class="source-line-no">208</span><span id="line-208">   * @param path                  path to implementation jar</span>
+<span class="source-line-no">209</span><span id="line-209">   * @param className             the main class name</span>
+<span class="source-line-no">210</span><span id="line-210">   * @param priority              chaining priority</span>
+<span class="source-line-no">211</span><span id="line-211">   * @param conf                  configuration for coprocessor</span>
+<span class="source-line-no">212</span><span id="line-212">   * @param includedClassPrefixes class name prefixes to include</span>
+<span class="source-line-no">213</span><span id="line-213">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">214</span><span id="line-214">   */</span>
+<span class="source-line-no">215</span><span id="line-215">  public E load(Path path, String className, int priority, Configuration conf,</span>
+<span class="source-line-no">216</span><span id="line-216">    String[] includedClassPrefixes) throws IOException {</span>
+<span class="source-line-no">217</span><span id="line-217">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">218</span><span id="line-218">    LOG.debug("Loading coprocessor class " + className + " with path " + path + " and priority "</span>
+<span class="source-line-no">219</span><span id="line-219">      + priority);</span>
+<span class="source-line-no">220</span><span id="line-220"></span>
+<span class="source-line-no">221</span><span id="line-221">    boolean skipLoadDuplicateCoprocessor = conf.getBoolean(SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR,</span>
+<span class="source-line-no">222</span><span id="line-222">      DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR);</span>
+<span class="source-line-no">223</span><span id="line-223">    if (skipLoadDuplicateCoprocessor &amp;&amp; findCoprocessor(className) != null) {</span>
+<span class="source-line-no">224</span><span id="line-224">      // If already loaded will just continue</span>
+<span class="source-line-no">225</span><span id="line-225">      LOG.warn("Attempted duplicate loading of {}; skipped", className);</span>
+<span class="source-line-no">226</span><span id="line-226">      return null;</span>
+<span class="source-line-no">227</span><span id="line-227">    }</span>
+<span class="source-line-no">228</span><span id="line-228"></span>
+<span class="source-line-no">229</span><span id="line-229">    ClassLoader cl = null;</span>
+<span class="source-line-no">230</span><span id="line-230">    if (path == null) {</span>
+<span class="source-line-no">231</span><span id="line-231">      try {</span>
+<span class="source-line-no">232</span><span id="line-232">        implClass = getClass().getClassLoader().loadClass(className);</span>
+<span class="source-line-no">233</span><span id="line-233">      } catch (ClassNotFoundException e) {</span>
+<span class="source-line-no">234</span><span id="line-234">        throw new IOException("No jar path specified for " + className);</span>
+<span class="source-line-no">235</span><span id="line-235">      }</span>
+<span class="source-line-no">236</span><span id="line-236">    } else {</span>
+<span class="source-line-no">237</span><span id="line-237">      cl =</span>
+<span class="source-line-no">238</span><span id="line-238">        CoprocessorClassLoader.getClassLoader(path, getClass().getClassLoader(), pathPrefix, conf);</span>
+<span class="source-line-no">239</span><span id="line-239">      try {</span>
+<span class="source-line-no">240</span><span id="line-240">        implClass = ((CoprocessorClassLoader) cl).loadClass(className, includedClassPrefixes);</span>
+<span class="source-line-no">241</span><span id="line-241">      } catch (ClassNotFoundException e) {</span>
+<span class="source-line-no">242</span><span id="line-242">        throw new IOException("Cannot load external coprocessor class " + className, e);</span>
+<span class="source-line-no">243</span><span id="line-243">      }</span>
+<span class="source-line-no">244</span><span id="line-244">    }</span>
+<span class="source-line-no">245</span><span id="line-245"></span>
+<span class="source-line-no">246</span><span id="line-246">    // load custom code for coprocessor</span>
+<span class="source-line-no">247</span><span id="line-247">    Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">248</span><span id="line-248">    ClassLoader hostClassLoader = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">249</span><span id="line-249">    try {</span>
+<span class="source-line-no">250</span><span id="line-250">      // switch temporarily to the thread classloader for custom CP</span>
+<span class="source-line-no">251</span><span id="line-251">      currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">252</span><span id="line-252">      E cpInstance = checkAndLoadInstance(implClass, priority, conf);</span>
+<span class="source-line-no">253</span><span id="line-253">      return cpInstance;</span>
+<span class="source-line-no">254</span><span id="line-254">    } finally {</span>
+<span class="source-line-no">255</span><span id="line-255">      // restore the fresh (host) classloader</span>
+<span class="source-line-no">256</span><span id="line-256">      currentThread.setContextClassLoader(hostClassLoader);</span>
+<span class="source-line-no">257</span><span id="line-257">    }</span>
+<span class="source-line-no">258</span><span id="line-258">  }</span>
+<span class="source-line-no">259</span><span id="line-259"></span>
+<span class="source-line-no">260</span><span id="line-260">  public void load(Class&lt;? extends C&gt; implClass, int priority, Configuration conf)</span>
+<span class="source-line-no">261</span><span id="line-261">    throws IOException {</span>
+<span class="source-line-no">262</span><span id="line-262">    E env = checkAndLoadInstance(implClass, priority, conf);</span>
+<span class="source-line-no">263</span><span id="line-263">    coprocEnvironments.add(env);</span>
+<span class="source-line-no">264</span><span id="line-264">  }</span>
+<span class="source-line-no">265</span><span id="line-265"></span>
+<span class="source-line-no">266</span><span id="line-266">  /**</span>
+<span class="source-line-no">267</span><span id="line-267">   * @param implClass Implementation class</span>
+<span class="source-line-no">268</span><span id="line-268">   * @param priority  priority</span>
+<span class="source-line-no">269</span><span id="line-269">   * @param conf      configuration</span>
+<span class="source-line-no">270</span><span id="line-270">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">271</span><span id="line-271">   */</span>
+<span class="source-line-no">272</span><span id="line-272">  public E checkAndLoadInstance(Class&lt;?&gt; implClass, int priority, Configuration conf)</span>
+<span class="source-line-no">273</span><span id="line-273">    throws IOException {</span>
+<span class="source-line-no">274</span><span id="line-274">    // create the instance</span>
+<span class="source-line-no">275</span><span id="line-275">    C impl;</span>
+<span class="source-line-no">276</span><span id="line-276">    try {</span>
+<span class="source-line-no">277</span><span id="line-277">      impl = checkAndGetInstance(implClass);</span>
+<span class="source-line-no">278</span><span id="line-278">      if (impl == null) {</span>
+<span class="source-line-no">279</span><span id="line-279">        LOG.error("Cannot load coprocessor " + implClass.getSimpleName());</span>
+<span class="source-line-no">280</span><span id="line-280">        return null;</span>
+<span class="source-line-no">281</span><span id="line-281">      }</span>
+<span class="source-line-no">282</span><span id="line-282">    } catch (InstantiationException | IllegalAccessException e) {</span>
+<span class="source-line-no">283</span><span id="line-283">      throw new IOException(e);</span>
+<span class="source-line-no">284</span><span id="line-284">    }</span>
+<span class="source-line-no">285</span><span id="line-285">    // create the environment</span>
+<span class="source-line-no">286</span><span id="line-286">    E env = createEnvironment(impl, priority, loadSequence.incrementAndGet(), conf);</span>
+<span class="source-line-no">287</span><span id="line-287">    assert env instanceof BaseEnvironment;</span>
+<span class="source-line-no">288</span><span id="line-288">    ((BaseEnvironment&lt;C&gt;) env).startup();</span>
+<span class="source-line-no">289</span><span id="line-289">    // HBASE-4014: maintain list of loaded coprocessors for later crash analysis</span>
+<span class="source-line-no">290</span><span id="line-290">    // if server (master or regionserver) aborts.</span>
+<span class="source-line-no">291</span><span id="line-291">    coprocessorNames.add(implClass.getName());</span>
+<span class="source-line-no">292</span><span id="line-292">    return env;</span>
+<span class="source-line-no">293</span><span id="line-293">  }</span>
+<span class="source-line-no">294</span><span id="line-294"></span>
+<span class="source-line-no">295</span><span id="line-295">  /**</span>
+<span class="source-line-no">296</span><span id="line-296">   * Called when a new Coprocessor class is loaded</span>
+<span class="source-line-no">297</span><span id="line-297">   */</span>
+<span class="source-line-no">298</span><span id="line-298">  public abstract E createEnvironment(C instance, int priority, int sequence, Configuration conf);</span>
+<span class="source-line-no">299</span><span id="line-299"></span>
+<span class="source-line-no">300</span><span id="line-300">  /**</span>
+<span class="source-line-no">301</span><span id="line-301">   * Called when a new Coprocessor class needs to be loaded. Checks if type of the given class is</span>
+<span class="source-line-no">302</span><span id="line-302">   * what the corresponding host implementation expects. If it is of correct type, returns an</span>
+<span class="source-line-no">303</span><span id="line-303">   * instance of the coprocessor to be loaded. If not, returns null. If an exception occurs when</span>
+<span class="source-line-no">304</span><span id="line-304">   * trying to create instance of a coprocessor, it's passed up and eventually results into server</span>
+<span class="source-line-no">305</span><span id="line-305">   * aborting.</span>
+<span class="source-line-no">306</span><span id="line-306">   */</span>
+<span class="source-line-no">307</span><span id="line-307">  public abstract C checkAndGetInstance(Class&lt;?&gt; implClass)</span>
+<span class="source-line-no">308</span><span id="line-308">    throws InstantiationException, IllegalAccessException;</span>
+<span class="source-line-no">309</span><span id="line-309"></span>
+<span class="source-line-no">310</span><span id="line-310">  public void shutdown(E e) {</span>
+<span class="source-line-no">311</span><span id="line-311">    assert e instanceof BaseEnvironment;</span>
+<span class="source-line-no">312</span><span id="line-312">    if (LOG.isDebugEnabled()) {</span>
+<span class="source-line-no">313</span><span id="line-313">      LOG.debug("Stop coprocessor " + e.getInstance().getClass().getName());</span>
+<span class="source-line-no">314</span><span id="line-314">    }</span>
+<span class="source-line-no">315</span><span id="line-315">    ((BaseEnvironment&lt;C&gt;) e).shutdown();</span>
+<span class="source-line-no">316</span><span id="line-316">  }</span>
+<span class="source-line-no">317</span><span id="line-317"></span>
+<span class="source-line-no">318</span><span id="line-318">  /**</span>
+<span class="source-line-no">319</span><span id="line-319">   * Find coprocessors by full class name or simple name.</span>
+<span class="source-line-no">320</span><span id="line-320">   */</span>
+<span class="source-line-no">321</span><span id="line-321">  public C findCoprocessor(String className) {</span>
+<span class="source-line-no">322</span><span id="line-322">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">323</span><span id="line-323">      if (</span>
+<span class="source-line-no">324</span><span id="line-324">        env.getInstance().getClass().getName().equals(className)</span>
+<span class="source-line-no">325</span><span id="line-325">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
+<span class="source-line-no">326</span><span id="line-326">      ) {</span>
+<span class="source-line-no">327</span><span id="line-327">        return env.getInstance();</span>
+<span class="source-line-no">328</span><span id="line-328">      }</span>
+<span class="source-line-no">329</span><span id="line-329">    }</span>
+<span class="source-line-no">330</span><span id="line-330">    return null;</span>
+<span class="source-line-no">331</span><span id="line-331">  }</span>
+<span class="source-line-no">332</span><span id="line-332"></span>
+<span class="source-line-no">333</span><span id="line-333">  public &lt;T extends C&gt; T findCoprocessor(Class&lt;T&gt; cls) {</span>
+<span class="source-line-no">334</span><span id="line-334">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">335</span><span id="line-335">      if (cls.isAssignableFrom(env.getInstance().getClass())) {</span>
+<span class="source-line-no">336</span><span id="line-336">        return (T) env.getInstance();</span>
+<span class="source-line-no">337</span><span id="line-337">      }</span>
+<span class="source-line-no">338</span><span id="line-338">    }</span>
+<span class="source-line-no">339</span><span id="line-339">    return null;</span>
+<span class="source-line-no">340</span><span id="line-340">  }</span>
+<span class="source-line-no">341</span><span id="line-341"></span>
+<span class="source-line-no">342</span><span id="line-342">  /**</span>
+<span class="source-line-no">343</span><span id="line-343">   * Find list of coprocessors that extend/implement the given class/interface</span>
+<span class="source-line-no">344</span><span id="line-344">   * @param cls the class/interface to look for</span>
+<span class="source-line-no">345</span><span id="line-345">   * @return the list of coprocessors, or null if not found</span>
+<span class="source-line-no">346</span><span id="line-346">   */</span>
+<span class="source-line-no">347</span><span id="line-347">  public &lt;T extends C&gt; List&lt;T&gt; findCoprocessors(Class&lt;T&gt; cls) {</span>
+<span class="source-line-no">348</span><span id="line-348">    ArrayList&lt;T&gt; ret = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">349</span><span id="line-349"></span>
+<span class="source-line-no">350</span><span id="line-350">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">351</span><span id="line-351">      C cp = env.getInstance();</span>
+<span class="source-line-no">352</span><span id="line-352"></span>
+<span class="source-line-no">353</span><span id="line-353">      if (cp != null) {</span>
+<span class="source-line-no">354</span><span id="line-354">        if (cls.isAssignableFrom(cp.getClass())) {</span>
+<span class="source-line-no">355</span><span id="line-355">          ret.add((T) cp);</span>
+<span class="source-line-no">356</span><span id="line-356">        }</span>
+<span class="source-line-no">357</span><span id="line-357">      }</span>
+<span class="source-line-no">358</span><span id="line-358">    }</span>
+<span class="source-line-no">359</span><span id="line-359">    return ret;</span>
+<span class="source-line-no">360</span><span id="line-360">  }</span>
+<span class="source-line-no">361</span><span id="line-361"></span>
+<span class="source-line-no">362</span><span id="line-362">  /**</span>
+<span class="source-line-no">363</span><span id="line-363">   * Find a coprocessor environment by class name</span>
+<span class="source-line-no">364</span><span id="line-364">   * @param className the class name</span>
+<span class="source-line-no">365</span><span id="line-365">   * @return the coprocessor, or null if not found</span>
+<span class="source-line-no">366</span><span id="line-366">   */</span>
+<span class="source-line-no">367</span><span id="line-367">  public E findCoprocessorEnvironment(String className) {</span>
+<span class="source-line-no">368</span><span id="line-368">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">369</span><span id="line-369">      if (</span>
+<span class="source-line-no">370</span><span id="line-370">        env.getInstance().getClass().getName().equals(className)</span>
+<span class="source-line-no">371</span><span id="line-371">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
+<span class="source-line-no">372</span><span id="line-372">      ) {</span>
+<span class="source-line-no">373</span><span id="line-373">        return env;</span>
+<span class="source-line-no">374</span><span id="line-374">      }</span>
+<span class="source-line-no">375</span><span id="line-375">    }</span>
+<span class="source-line-no">376</span><span id="line-376">    return null;</span>
+<span class="source-line-no">377</span><span id="line-377">  }</span>
+<span class="source-line-no">378</span><span id="line-378"></span>
+<span class="source-line-no">379</span><span id="line-379">  /**</span>
+<span class="source-line-no">380</span><span id="line-380">   * Retrieves the set of classloaders used to instantiate Coprocessor classes defined in external</span>
+<span class="source-line-no">381</span><span id="line-381">   * jar files.</span>
+<span class="source-line-no">382</span><span id="line-382">   * @return A set of ClassLoader instances</span>
+<span class="source-line-no">383</span><span id="line-383">   */</span>
+<span class="source-line-no">384</span><span id="line-384">  Set&lt;ClassLoader&gt; getExternalClassLoaders() {</span>
+<span class="source-line-no">385</span><span id="line-385">    Set&lt;ClassLoader&gt; externalClassLoaders = new HashSet&lt;&gt;();</span>
+<span class="source-line-no">386</span><span id="line-386">    final ClassLoader systemClassLoader = this.getClass().getClassLoader();</span>
+<span class="source-line-no">387</span><span id="line-387">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">388</span><span id="line-388">      ClassLoader cl = env.getInstance().getClass().getClassLoader();</span>
+<span class="source-line-no">389</span><span id="line-389">      if (cl != systemClassLoader) {</span>
+<span class="source-line-no">390</span><span id="line-390">        // do not include system classloader</span>
+<span class="source-line-no">391</span><span id="line-391">        externalClassLoaders.add(cl);</span>
+<span class="source-line-no">392</span><span id="line-392">      }</span>
+<span class="source-line-no">393</span><span id="line-393">    }</span>
+<span class="source-line-no">394</span><span id="line-394">    return externalClassLoaders;</span>
+<span class="source-line-no">395</span><span id="line-395">  }</span>
+<span class="source-line-no">396</span><span id="line-396"></span>
+<span class="source-line-no">397</span><span id="line-397">  /**</span>
+<span class="source-line-no">398</span><span id="line-398">   * Environment priority comparator. Coprocessors are chained in sorted order.</span>
+<span class="source-line-no">399</span><span id="line-399">   */</span>
+<span class="source-line-no">400</span><span id="line-400">  static class EnvironmentPriorityComparator implements Comparator&lt;CoprocessorEnvironment&gt; {</span>
+<span class="source-line-no">401</span><span id="line-401">    @Override</span>
+<span class="source-line-no">402</span><span id="line-402">    public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) {</span>
+<span class="source-line-no">403</span><span id="line-403">      if (env1.getPriority() &lt; env2.getPriority()) {</span>
+<span class="source-line-no">404</span><span id="line-404">        return -1;</span>
+<span class="source-line-no">405</span><span id="line-405">      } else if (env1.getPriority() &gt; env2.getPriority()) {</span>
+<span class="source-line-no">406</span><span id="line-406">        return 1;</span>
+<span class="source-line-no">407</span><span id="line-407">      }</span>
+<span class="source-line-no">408</span><span id="line-408">      if (env1.getLoadSequence() &lt; env2.getLoadSequence()) {</span>
+<span class="source-line-no">409</span><span id="line-409">        return -1;</span>
+<span class="source-line-no">410</span><span id="line-410">      } else if (env1.getLoadSequence() &gt; env2.getLoadSequence()) {</span>
+<span class="source-line-no">411</span><span id="line-411">        return 1;</span>
+<span class="source-line-no">412</span><span id="line-412">      }</span>
+<span class="source-line-no">413</span><span id="line-413">      return 0;</span>
+<span class="source-line-no">414</span><span id="line-414">    }</span>
+<span class="source-line-no">415</span><span id="line-415">  }</span>
+<span class="source-line-no">416</span><span id="line-416"></span>
+<span class="source-line-no">417</span><span id="line-417">  protected void abortServer(final E environment, final Throwable e) {</span>
+<span class="source-line-no">418</span><span id="line-418">    abortServer(environment.getInstance().getClass().getName(), e);</span>
+<span class="source-line-no">419</span><span id="line-419">  }</span>
+<span class="source-line-no">420</span><span id="line-420"></span>
+<span class="source-line-no">421</span><span id="line-421">  protected void abortServer(final String coprocessorName, final Throwable e) {</span>
+<span class="source-line-no">422</span><span id="line-422">    String message = "The coprocessor " + coprocessorName + " threw " + e.toString();</span>
+<span class="source-line-no">423</span><span id="line-423">    LOG.error(message, e);</span>
+<span class="source-line-no">424</span><span id="line-424">    if (abortable != null) {</span>
+<span class="source-line-no">425</span><span id="line-425">      abortable.abort(message, e);</span>
+<span class="source-line-no">426</span><span id="line-426">    } else {</span>
+<span class="source-line-no">427</span><span id="line-427">      LOG.warn("No available Abortable, process was not aborted");</span>
+<span class="source-line-no">428</span><span id="line-428">    }</span>
+<span class="source-line-no">429</span><span id="line-429">  }</span>
+<span class="source-line-no">430</span><span id="line-430"></span>
+<span class="source-line-no">431</span><span id="line-431">  /**</span>
+<span class="source-line-no">432</span><span id="line-432">   * This is used by coprocessor hooks which are declared to throw IOException (or its subtypes).</span>
+<span class="source-line-no">433</span><span id="line-433">   * For such hooks, we should handle throwable objects depending on the Throwable's type. Those</span>
+<span class="source-line-no">434</span><span id="line-434">   * which are instances of IOException should be passed on to the client. This is in conformance</span>
+<span class="source-line-no">435</span><span id="line-435">   * with the HBase idiom regarding IOException: that it represents a circumstance that should be</span>
+<span class="source-line-no">436</span><span id="line-436">   * passed along to the client for its own handling. For example, a coprocessor that implements</span>
+<span class="source-line-no">437</span><span id="line-437">   * access controls would throw a subclass of IOException, such as AccessDeniedException, in its</span>
+<span class="source-line-no">438</span><span id="line-438">   * preGet() method to prevent an unauthorized client's performing a Get on a particular table.</span>
+<span class="source-line-no">439</span><span id="line-439">   * @param env Coprocessor Environment</span>
+<span class="source-line-no">440</span><span id="line-440">   * @param e   Throwable object thrown by coprocessor.</span>
+<span class="source-line-no">441</span><span id="line-441">   * @exception IOException Exception</span>
+<span class="source-line-no">442</span><span id="line-442">   */</span>
+<span class="source-line-no">443</span><span id="line-443">  // Note to devs: Class comments of all observers ({@link MasterObserver}, {@link WALObserver},</span>
+<span class="source-line-no">444</span><span id="line-444">  // etc) mention this nuance of our exception handling so that coprocessor can throw appropriate</span>
+<span class="source-line-no">445</span><span id="line-445">  // exceptions depending on situation. If any changes are made to this logic, make sure to</span>
+<span class="source-line-no">446</span><span id="line-446">  // update all classes' comments.</span>
+<span class="source-line-no">447</span><span id="line-447">  protected void handleCoprocessorThrowable(final E env, final Throwable e) throws IOException {</span>
+<span class="source-line-no">448</span><span id="line-448">    if (e instanceof IOException) {</span>
+<span class="source-line-no">449</span><span id="line-449">      throw (IOException) e;</span>
+<span class="source-line-no">450</span><span id="line-450">    }</span>
+<span class="source-line-no">451</span><span id="line-451">    // If we got here, e is not an IOException. A loaded coprocessor has a</span>
+<span class="source-line-no">452</span><span id="line-452">    // fatal bug, and the server (master or regionserver) should remove the</span>
+<span class="source-line-no">453</span><span id="line-453">    // faulty coprocessor from its set of active coprocessors. Setting</span>
+<span class="source-line-no">454</span><span id="line-454">    // 'hbase.coprocessor.abortonerror' to true will cause abortServer(),</span>
+<span class="source-line-no">455</span><span id="line-455">    // which may be useful in development and testing environments where</span>
+<span class="source-line-no">456</span><span id="line-456">    // 'failing fast' for error analysis is desired.</span>
+<span class="source-line-no">457</span><span id="line-457">    if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) {</span>
+<span class="source-line-no">458</span><span id="line-458">      // server is configured to abort.</span>
+<span class="source-line-no">459</span><span id="line-459">      abortServer(env, e);</span>
+<span class="source-line-no">460</span><span id="line-460">    } else {</span>
+<span class="source-line-no">461</span><span id="line-461">      // If available, pull a table name out of the environment</span>
+<span class="source-line-no">462</span><span id="line-462">      if (env instanceof RegionCoprocessorEnvironment) {</span>
+<span class="source-line-no">463</span><span id="line-463">        String tableName =</span>
+<span class="source-line-no">464</span><span id="line-464">          ((RegionCoprocessorEnvironment) env).getRegionInfo().getTable().getNameAsString();</span>
+<span class="source-line-no">465</span><span id="line-465">        LOG.error("Removing coprocessor '" + env.toString() + "' from table '" + tableName + "'",</span>
+<span class="source-line-no">466</span><span id="line-466">          e);</span>
+<span class="source-line-no">467</span><span id="line-467">      } else {</span>
+<span class="source-line-no">468</span><span id="line-468">        LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment", e);</span>
+<span class="source-line-no">469</span><span id="line-469">      }</span>
+<span class="source-line-no">470</span><span id="line-470"></span>
+<span class="source-line-no">471</span><span id="line-471">      coprocEnvironments.remove(env);</span>
+<span class="source-line-no">472</span><span id="line-472">      try {</span>
+<span class="source-line-no">473</span><span id="line-473">        shutdown(env);</span>
+<span class="source-line-no">474</span><span id="line-474">      } catch (Exception x) {</span>
+<span class="source-line-no">475</span><span id="line-475">        LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x);</span>
+<span class="source-line-no">476</span><span id="line-476">      }</span>
+<span class="source-line-no">477</span><span id="line-477">      throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e</span>
+<span class="source-line-no">478</span><span id="line-478">        + "' and has been removed from the active " + "coprocessor set.", e);</span>
+<span class="source-line-no">479</span><span id="line-479">    }</span>
+<span class="source-line-no">480</span><span id="line-480">  }</span>
+<span class="source-line-no">481</span><span id="line-481"></span>
+<span class="source-line-no">482</span><span id="line-482">  /**</span>
+<span class="source-line-no">483</span><span id="line-483">   * Used to limit legacy handling to once per Coprocessor class per classloader.</span>
+<span class="source-line-no">484</span><span id="line-484">   */</span>
+<span class="source-line-no">485</span><span id="line-485">  private static final Set&lt;Class&lt;? extends Coprocessor&gt;&gt; legacyWarning =</span>
+<span class="source-line-no">486</span><span id="line-486">    new ConcurrentSkipListSet&lt;&gt;(new Comparator&lt;Class&lt;? extends Coprocessor&gt;&gt;() {</span>
+<span class="source-line-no">487</span><span id="line-487">      @Override</span>
+<span class="source-line-no">488</span><span id="line-488">      public int compare(Class&lt;? extends Coprocessor&gt; c1, Class&lt;? extends Coprocessor&gt; c2) {</span>
+<span class="source-line-no">489</span><span id="line-489">        if (c1.equals(c2)) {</span>
+<span class="source-line-no">490</span><span id="line-490">          return 0;</span>
+<span class="source-line-no">491</span><span id="line-491">        }</span>
+<span class="source-line-no">492</span><span id="line-492">        return c1.getName().compareTo(c2.getName());</span>
+<span class="source-line-no">493</span><span id="line-493">      }</span>
+<span class="source-line-no">494</span><span id="line-494">    });</span>
+<span class="source-line-no">495</span><span id="line-495"></span>
+<span class="source-line-no">496</span><span id="line-496">  /**</span>
+<span class="source-line-no">497</span><span id="line-497">   * Implementations defined function to get an observer of type {@code O} from a coprocessor of</span>
+<span class="source-line-no">498</span><span id="line-498">   * type {@code C}. Concrete implementations of CoprocessorHost define one getter for each observer</span>
+<span class="source-line-no">499</span><span id="line-499">   * they can handle. For e.g. RegionCoprocessorHost will use 3 getters, one for each of</span>
+<span class="source-line-no">500</span><span id="line-500">   * RegionObserver, EndpointObserver and BulkLoadObserver. These getters are used by</span>
+<span class="source-line-no">501</span><span id="line-501">   * {@code ObserverOperation} to get appropriate observer from the coprocessor.</span>
+<span class="source-line-no">502</span><span id="line-502">   */</span>
+<span class="source-line-no">503</span><span id="line-503">  @FunctionalInterface</span>
+<span class="source-line-no">504</span><span id="line-504">  public interface ObserverGetter&lt;C, O&gt; extends Function&lt;C, Optional&lt;O&gt;&gt; {</span>
+<span class="source-line-no">505</span><span id="line-505">  }</span>
+<span class="source-line-no">506</span><span id="line-506"></span>
+<span class="source-line-no">507</span><span id="line-507">  private abstract class ObserverOperation&lt;O&gt; extends ObserverContextImpl&lt;E&gt; {</span>
+<span class="source-line-no">508</span><span id="line-508">    ObserverGetter&lt;C, O&gt; observerGetter;</span>
+<span class="source-line-no">509</span><span id="line-509"></span>
+<span class="source-line-no">510</span><span id="line-510">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
+<span class="source-line-no">511</span><span id="line-511">      this(observerGetter, null);</span>
+<span class="source-line-no">512</span><span id="line-512">    }</span>
+<span class="source-line-no">513</span><span id="line-513"></span>
+<span class="source-line-no">514</span><span id="line-514">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
+<span class="source-line-no">515</span><span id="line-515">      this(observerGetter, user, false);</span>
+<span class="source-line-no">516</span><span id="line-516">    }</span>
+<span class="source-line-no">517</span><span id="line-517"></span>
+<span class="source-line-no">518</span><span id="line-518">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, boolean bypassable) {</span>
+<span class="source-line-no">519</span><span id="line-519">      this(observerGetter, null, bypassable);</span>
+<span class="source-line-no">520</span><span id="line-520">    }</span>
+<span class="source-line-no">521</span><span id="line-521"></span>
+<span class="source-line-no">522</span><span id="line-522">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user, boolean bypassable) {</span>
+<span class="source-line-no">523</span><span id="line-523">      super(user != null ? user : RpcServer.getRequestUser().orElse(null), bypassable);</span>
+<span class="source-line-no">524</span><span id="line-524">      this.observerGetter = observerGetter;</span>
+<span class="source-line-no">525</span><span id="line-525">    }</span>
 <span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527">    protected void postEnvCall() {</span>
-<span class="source-line-no">528</span><span id="line-528">    }</span>
-<span class="source-line-no">529</span><span id="line-529">  }</span>
-<span class="source-line-no">530</span><span id="line-530"></span>
-<span class="source-line-no">531</span><span id="line-531">  // Can't derive ObserverOperation from ObserverOperationWithResult (R = Void) because then all</span>
-<span class="source-line-no">532</span><span id="line-532">  // ObserverCaller implementations will have to have a return statement.</span>
-<span class="source-line-no">533</span><span id="line-533">  // O = observer, E = environment, C = coprocessor, R=result type</span>
-<span class="source-line-no">534</span><span id="line-534">  public abstract class ObserverOperationWithoutResult&lt;O&gt; extends ObserverOperation&lt;O&gt; {</span>
-<span class="source-line-no">535</span><span id="line-535">    protected abstract void call(O observer) throws IOException;</span>
-<span class="source-line-no">536</span><span id="line-536"></span>
-<span class="source-line-no">537</span><span id="line-537">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
-<span class="source-line-no">538</span><span id="line-538">      super(observerGetter);</span>
-<span class="source-line-no">539</span><span id="line-539">    }</span>
-<span class="source-line-no">540</span><span id="line-540"></span>
-<span class="source-line-no">541</span><span id="line-541">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
-<span class="source-line-no">542</span><span id="line-542">      super(observerGetter, user);</span>
-<span class="source-line-no">543</span><span id="line-543">    }</span>
-<span class="source-line-no">544</span><span id="line-544"></span>
-<span class="source-line-no">545</span><span id="line-545">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user,</span>
-<span class="source-line-no">546</span><span id="line-546">      boolean bypassable) {</span>
-<span class="source-line-no">547</span><span id="line-547">      super(observerGetter, user, bypassable);</span>
-<span class="source-line-no">548</span><span id="line-548">    }</span>
-<span class="source-line-no">549</span><span id="line-549"></span>
-<span class="source-line-no">550</span><span id="line-550">    /**</span>
-<span class="source-line-no">551</span><span id="line-551">     * In case of coprocessors which have many kinds of observers (for eg, {@link RegionCoprocessor}</span>
-<span class="source-line-no">552</span><span id="line-552">     * has BulkLoadObserver, RegionObserver, etc), some implementations may not need all observers,</span>
-<span class="source-line-no">553</span><span id="line-553">     * in which case they will return null for that observer's getter. We simply ignore such cases.</span>
-<span class="source-line-no">554</span><span id="line-554">     */</span>
-<span class="source-line-no">555</span><span id="line-555">    @Override</span>
-<span class="source-line-no">556</span><span id="line-556">    void callObserver() throws IOException {</span>
-<span class="source-line-no">557</span><span id="line-557">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
-<span class="source-line-no">558</span><span id="line-558">      if (observer.isPresent()) {</span>
-<span class="source-line-no">559</span><span id="line-559">        call(observer.get());</span>
-<span class="source-line-no">560</span><span id="line-560">      }</span>
-<span class="source-line-no">561</span><span id="line-561">    }</span>
-<span class="source-line-no">562</span><span id="line-562">  }</span>
-<span class="source-line-no">563</span><span id="line-563"></span>
-<span class="source-line-no">564</span><span id="line-564">  public abstract class ObserverOperationWithResult&lt;O, R&gt; extends ObserverOperation&lt;O&gt; {</span>
-<span class="source-line-no">565</span><span id="line-565">    protected abstract R call(O observer) throws IOException;</span>
-<span class="source-line-no">566</span><span id="line-566"></span>
-<span class="source-line-no">567</span><span id="line-567">    private R result;</span>
+<span class="source-line-no">527</span><span id="line-527">    abstract void callObserver() throws IOException;</span>
+<span class="source-line-no">528</span><span id="line-528"></span>
+<span class="source-line-no">529</span><span id="line-529">    protected void postEnvCall() {</span>
+<span class="source-line-no">530</span><span id="line-530">    }</span>
+<span class="source-line-no">531</span><span id="line-531">  }</span>
+<span class="source-line-no">532</span><span id="line-532"></span>
+<span class="source-line-no">533</span><span id="line-533">  // Can't derive ObserverOperation from ObserverOperationWithResult (R = Void) because then all</span>
+<span class="source-line-no">534</span><span id="line-534">  // ObserverCaller implementations will have to have a return statement.</span>
+<span class="source-line-no">535</span><span id="line-535">  // O = observer, E = environment, C = coprocessor, R=result type</span>
+<span class="source-line-no">536</span><span id="line-536">  public abstract class ObserverOperationWithoutResult&lt;O&gt; extends ObserverOperation&lt;O&gt; {</span>
+<span class="source-line-no">537</span><span id="line-537">    protected abstract void call(O observer) throws IOException;</span>
+<span class="source-line-no">538</span><span id="line-538"></span>
+<span class="source-line-no">539</span><span id="line-539">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
+<span class="source-line-no">540</span><span id="line-540">      super(observerGetter);</span>
+<span class="source-line-no">541</span><span id="line-541">    }</span>
+<span class="source-line-no">542</span><span id="line-542"></span>
+<span class="source-line-no">543</span><span id="line-543">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
+<span class="source-line-no">544</span><span id="line-544">      super(observerGetter, user);</span>
+<span class="source-line-no">545</span><span id="line-545">    }</span>
+<span class="source-line-no">546</span><span id="line-546"></span>
+<span class="source-line-no">547</span><span id="line-547">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user,</span>
+<span class="source-line-no">548</span><span id="line-548">      boolean bypassable) {</span>
+<span class="source-line-no">549</span><span id="line-549">      super(observerGetter, user, bypassable);</span>
+<span class="source-line-no">550</span><span id="line-550">    }</span>
+<span class="source-line-no">551</span><span id="line-551"></span>
+<span class="source-line-no">552</span><span id="line-552">    /**</span>
+<span class="source-line-no">553</span><span id="line-553">     * In case of coprocessors which have many kinds of observers (for eg, {@link RegionCoprocessor}</span>
+<span class="source-line-no">554</span><span id="line-554">     * has BulkLoadObserver, RegionObserver, etc), some implementations may not need all observers,</span>
+<span class="source-line-no">555</span><span id="line-555">     * in which case they will return null for that observer's getter. We simply ignore such cases.</span>
+<span class="source-line-no">556</span><span id="line-556">     */</span>
+<span class="source-line-no">557</span><span id="line-557">    @Override</span>
+<span class="source-line-no">558</span><span id="line-558">    void callObserver() throws IOException {</span>
+<span class="source-line-no">559</span><span id="line-559">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
+<span class="source-line-no">560</span><span id="line-560">      if (observer.isPresent()) {</span>
+<span class="source-line-no">561</span><span id="line-561">        call(observer.get());</span>
+<span class="source-line-no">562</span><span id="line-562">      }</span>
+<span class="source-line-no">563</span><span id="line-563">    }</span>
+<span class="source-line-no">564</span><span id="line-564">  }</span>
+<span class="source-line-no">565</span><span id="line-565"></span>
+<span class="source-line-no">566</span><span id="line-566">  public abstract class ObserverOperationWithResult&lt;O, R&gt; extends ObserverOperation&lt;O&gt; {</span>
+<span class="source-line-no">567</span><span id="line-567">    protected abstract R call(O observer) throws IOException;</span>
 <span class="source-line-no">568</span><span id="line-568"></span>
-<span class="source-line-no">569</span><span id="line-569">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result) {</span>
-<span class="source-line-no">570</span><span id="line-570">      this(observerGetter, result, false);</span>
-<span class="source-line-no">571</span><span id="line-571">    }</span>
-<span class="source-line-no">572</span><span id="line-572"></span>
-<span class="source-line-no">573</span><span id="line-573">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result,</span>
-<span class="source-line-no">574</span><span id="line-574">      boolean bypassable) {</span>
-<span class="source-line-no">575</span><span id="line-575">      this(observerGetter, result, null, bypassable);</span>
-<span class="source-line-no">576</span><span id="line-576">    }</span>
-<span class="source-line-no">577</span><span id="line-577"></span>
-<span class="source-line-no">578</span><span id="line-578">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user) {</span>
-<span class="source-line-no">579</span><span id="line-579">      this(observerGetter, result, user, false);</span>
-<span class="source-line-no">580</span><span id="line-580">    }</span>
-<span class="source-line-no">581</span><span id="line-581"></span>
-<span class="source-line-no">582</span><span id="line-582">    private ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user,</span>
-<span class="source-line-no">583</span><span id="line-583">      boolean bypassable) {</span>
-<span class="source-line-no">584</span><span id="line-584">      super(observerGetter, user, bypassable);</span>
-<span class="source-line-no">585</span><span id="line-585">      this.result = result;</span>
-<span class="source-line-no">586</span><span id="line-586">    }</span>
-<span class="source-line-no">587</span><span id="line-587"></span>
-<span class="source-line-no">588</span><span id="line-588">    protected R getResult() {</span>
-<span class="source-line-no">589</span><span id="line-589">      return this.result;</span>
-<span class="source-line-no">590</span><span id="line-590">    }</span>
-<span class="source-line-no">591</span><span id="line-591"></span>
-<span class="source-line-no">592</span><span id="line-592">    @Override</span>
-<span class="source-line-no">593</span><span id="line-593">    void callObserver() throws IOException {</span>
-<span class="source-line-no">594</span><span id="line-594">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
-<span class="source-line-no">595</span><span id="line-595">      if (observer.isPresent()) {</span>
-<span class="source-line-no">596</span><span id="line-596">        result = call(observer.get());</span>
-<span class="source-line-no">597</span><span id="line-597">      }</span>
-<span class="source-line-no">598</span><span id="line-598">    }</span>
-<span class="source-line-no">599</span><span id="line-599">  }</span>
-<span class="source-line-no">600</span><span id="line-600"></span>
-<span class="source-line-no">601</span><span id="line-601">  //////////////////////////////////////////////////////////////////////////////////////////</span>
-<span class="source-line-no">602</span><span id="line-602">  // Functions to execute observer hooks and handle results (if any)</span>
+<span class="source-line-no">569</span><span id="line-569">    private R result;</span>
+<span class="source-line-no">570</span><span id="line-570"></span>
+<span class="source-line-no">571</span><span id="line-571">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result) {</span>
+<span class="source-line-no">572</span><span id="line-572">      this(observerGetter, result, false);</span>
+<span class="source-line-no">573</span><span id="line-573">    }</span>
+<span class="source-line-no">574</span><span id="line-574"></span>
+<span class="source-line-no">575</span><span id="line-575">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result,</span>
+<span class="source-line-no">576</span><span id="line-576">      boolean bypassable) {</span>
+<span class="source-line-no">577</span><span id="line-577">      this(observerGetter, result, null, bypassable);</span>
+<span class="source-line-no">578</span><span id="line-578">    }</span>
+<span class="source-line-no">579</span><span id="line-579"></span>
+<span class="source-line-no">580</span><span id="line-580">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user) {</span>
+<span class="source-line-no">581</span><span id="line-581">      this(observerGetter, result, user, false);</span>
+<span class="source-line-no">582</span><span id="line-582">    }</span>
+<span class="source-line-no">583</span><span id="line-583"></span>
+<span class="source-line-no">584</span><span id="line-584">    private ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user,</span>
+<span class="source-line-no">585</span><span id="line-585">      boolean bypassable) {</span>
+<span class="source-line-no">586</span><span id="line-586">      super(observerGetter, user, bypassable);</span>
+<span class="source-line-no">587</span><span id="line-587">      this.result = result;</span>
+<span class="source-line-no">588</span><span id="line-588">    }</span>
+<span class="source-line-no">589</span><span id="line-589"></span>
+<span class="source-line-no">590</span><span id="line-590">    protected R getResult() {</span>
+<span class="source-line-no">591</span><span id="line-591">      return this.result;</span>
+<span class="source-line-no">592</span><span id="line-592">    }</span>
+<span class="source-line-no">593</span><span id="line-593"></span>
+<span class="source-line-no">594</span><span id="line-594">    @Override</span>
+<span class="source-line-no">595</span><span id="line-595">    void callObserver() throws IOException {</span>
+<span class="source-line-no">596</span><span id="line-596">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
+<span class="source-line-no">597</span><span id="line-597">      if (observer.isPresent()) {</span>
+<span class="source-line-no">598</span><span id="line-598">        result = call(observer.get());</span>
+<span class="source-line-no">599</span><span id="line-599">      }</span>
+<span class="source-line-no">600</span><span id="line-600">    }</span>
+<span class="source-line-no">601</span><span id="line-601">  }</span>
+<span class="source-line-no">602</span><span id="line-602"></span>
 <span class="source-line-no">603</span><span id="line-603">  //////////////////////////////////////////////////////////////////////////////////////////</span>
-<span class="source-line-no">604</span><span id="line-604"></span>
-<span class="source-line-no">605</span><span id="line-605">  /**</span>
-<span class="source-line-no">606</span><span id="line-606">   * Do not call with an observerOperation that is null! Have the caller check.</span>
-<span class="source-line-no">607</span><span id="line-607">   */</span>
-<span class="source-line-no">608</span><span id="line-608">  protected &lt;O, R&gt; R execOperationWithResult(</span>
-<span class="source-line-no">609</span><span id="line-609">    final ObserverOperationWithResult&lt;O, R&gt; observerOperation) throws IOException {</span>
-<span class="source-line-no">610</span><span id="line-610">    boolean bypass = execOperation(observerOperation);</span>
-<span class="source-line-no">611</span><span id="line-611">    R result = observerOperation.getResult();</span>
-<span class="source-line-no">612</span><span id="line-612">    return bypass == observerOperation.isBypassable() ? result : null;</span>
-<span class="source-line-no">613</span><span id="line-613">  }</span>
-<span class="source-line-no">614</span><span id="line-614"></span>
-<span class="source-line-no">615</span><span id="line-615">  /**</span>
-<span class="source-line-no">616</span><span id="line-616">   * @return True if we are to bypass (Can only be &lt;code&gt;true&lt;/code&gt; if</span>
-<span class="source-line-no">617</span><span id="line-617">   *         ObserverOperation#isBypassable().</span>
-<span class="source-line-no">618</span><span id="line-618">   */</span>
-<span class="source-line-no">619</span><span id="line-619">  protected &lt;O&gt; boolean execOperation(final ObserverOperation&lt;O&gt; observerOperation)</span>
-<span class="source-line-no">620</span><span id="line-620">    throws IOException {</span>
-<span class="source-line-no">621</span><span id="line-621">    boolean bypass = false;</span>
-<span class="source-line-no">622</span><span id="line-622">    if (observerOperation == null) {</span>
-<span class="source-line-no">623</span><span id="line-623">      return bypass;</span>
-<span class="source-line-no">624</span><span id="line-624">    }</span>
-<span class="source-line-no">625</span><span id="line-625">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
-<span class="source-line-no">626</span><span id="line-626">    for (E env : envs) {</span>
-<span class="source-line-no">627</span><span id="line-627">      observerOperation.prepare(env);</span>
-<span class="source-line-no">628</span><span id="line-628">      Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">629</span><span id="line-629">      ClassLoader cl = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">630</span><span id="line-630">      try {</span>
-<span class="source-line-no">631</span><span id="line-631">        currentThread.setContextClassLoader(env.getClassLoader());</span>
-<span class="source-line-no">632</span><span id="line-632">        observerOperation.callObserver();</span>
-<span class="source-line-no">633</span><span id="line-633">      } catch (Throwable e) {</span>
-<span class="source-line-no">634</span><span id="line-634">        handleCoprocessorThrowable(env, e);</span>
-<span class="source-line-no">635</span><span id="line-635">      } finally {</span>
-<span class="source-line-no">636</span><span id="line-636">        currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">637</span><span id="line-637">      }</span>
-<span class="source-line-no">638</span><span id="line-638">      // Internal to shouldBypass, it checks if obeserverOperation#isBypassable().</span>
-<span class="source-line-no">639</span><span id="line-639">      bypass |= observerOperation.shouldBypass();</span>
-<span class="source-line-no">640</span><span id="line-640">      observerOperation.postEnvCall();</span>
-<span class="source-line-no">641</span><span id="line-641">      if (bypass) {</span>
-<span class="source-line-no">642</span><span id="line-642">        // If CP says bypass, skip out w/o calling any following CPs; they might ruin our response.</span>
-<span class="source-line-no">643</span><span id="line-643">        // In hbase1, this used to be called 'complete'. In hbase2, we unite bypass and 'complete'.</span>
-<span class="source-line-no">644</span><span id="line-644">        break;</span>
-<span class="source-line-no">645</span><span id="line-645">      }</span>
-<span class="source-line-no">646</span><span id="line-646">    }</span>
-<span class="source-line-no">647</span><span id="line-647">    return bypass;</span>
-<span class="source-line-no">648</span><span id="line-648">  }</span>
-<span class="source-line-no">649</span><span id="line-649"></span>
-<span class="source-line-no">650</span><span id="line-650">  /**</span>
-<span class="source-line-no">651</span><span id="line-651">   * Coprocessor classes can be configured in any order, based on that priority is set and chained</span>
-<span class="source-line-no">652</span><span id="line-652">   * in a sorted order. Should be used preStop*() hooks i.e. when master/regionserver is going down.</span>
-<span class="source-line-no">653</span><span id="line-653">   * This function first calls coprocessor methods (using ObserverOperation.call()) and then</span>
-<span class="source-line-no">654</span><span id="line-654">   * shutdowns the environment in postEnvCall(). &lt;br&gt;</span>
-<span class="source-line-no">655</span><span id="line-655">   * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors</span>
-<span class="source-line-no">656</span><span id="line-656">   * may remain shutdown if any exception occurs during next coprocessor execution which prevent</span>
-<span class="source-line-no">657</span><span id="line-657">   * master/regionserver stop or cluster shutdown. (Refer:</span>
-<span class="source-line-no">658</span><span id="line-658">   * &lt;a href="https://issues.apache.org/jira/browse/HBASE-16663"&gt;HBASE-16663&lt;/a&gt;</span>
-<span class="source-line-no">659</span><span id="line-659">   * @return true if bypaas coprocessor execution, false if not.</span>
-<span class="source-line-no">660</span><span id="line-660">   */</span>
-<span class="source-line-no">661</span><span id="line-661">  protected &lt;O&gt; boolean execShutdown(final ObserverOperation&lt;O&gt; observerOperation)</span>
-<span class="source-line-no">662</span><span id="line-662">    throws IOException {</span>
-<span class="source-line-no">663</span><span id="line-663">    if (observerOperation == null) return false;</span>
-<span class="source-line-no">664</span><span id="line-664">    boolean bypass = false;</span>
-<span class="source-line-no">665</span><span id="line-665">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
-<span class="source-line-no">666</span><span id="line-666">    // Iterate the coprocessors and execute ObserverOperation's call()</span>
-<span class="source-line-no">667</span><span id="line-667">    for (E env : envs) {</span>
-<span class="source-line-no">668</span><span id="line-668">      observerOperation.prepare(env);</span>
-<span class="source-line-no">669</span><span id="line-669">      Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">670</span><span id="line-670">      ClassLoader cl = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">671</span><span id="line-671">      try {</span>
-<span class="source-line-no">672</span><span id="line-672">        currentThread.setContextClassLoader(env.getClassLoader());</span>
-<span class="source-line-no">673</span><span id="line-673">        observerOperation.callObserver();</span>
-<span class="source-line-no">674</span><span id="line-674">      } catch (Throwable e) {</span>
-<span class="source-line-no">675</span><span id="line-675">        handleCoprocessorThrowable(env, e);</span>
-<span class="source-line-no">676</span><span id="line-676">      } finally {</span>
-<span class="source-line-no">677</span><span id="line-677">        currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">678</span><span id="line-678">      }</span>
-<span class="source-line-no">679</span><span id="line-679">      bypass |= observerOperation.shouldBypass();</span>
-<span class="source-line-no">680</span><span id="line-680">    }</span>
-<span class="source-line-no">681</span><span id="line-681"></span>
-<span class="source-line-no">682</span><span id="line-682">    // Iterate the coprocessors and execute ObserverOperation's postEnvCall()</span>
-<span class="source-line-no">683</span><span id="line-683">    for (E env : envs) {</span>
-<span class="source-line-no">684</span><span id="line-684">      observerOperation.prepare(env);</span>
-<span class="source-line-no">685</span><span id="line-685">      observerOperation.postEnvCall();</span>
-<span class="source-line-no">686</span><span id="line-686">    }</span>
-<span class="source-line-no">687</span><span id="line-687">    return bypass;</span>
-<span class="source-line-no">688</span><span id="line-688">  }</span>
-<span class="source-line-no">689</span><span id="line-689">}</span>
+<span class="source-line-no">604</span><span id="line-604">  // Functions to execute observer hooks and handle results (if any)</span>
+<span class="source-line-no">605</span><span id="line-605">  //////////////////////////////////////////////////////////////////////////////////////////</span>
+<span class="source-line-no">606</span><span id="line-606"></span>
+<span class="source-line-no">607</span><span id="line-607">  /**</span>
+<span class="source-line-no">608</span><span id="line-608">   * Do not call with an observerOperation that is null! Have the caller check.</span>
+<span class="source-line-no">609</span><span id="line-609">   */</span>
+<span class="source-line-no">610</span><span id="line-610">  protected &lt;O, R&gt; R execOperationWithResult(</span>
+<span class="source-line-no">611</span><span id="line-611">    final ObserverOperationWithResult&lt;O, R&gt; observerOperation) throws IOException {</span>
+<span class="source-line-no">612</span><span id="line-612">    boolean bypass = execOperation(observerOperation);</span>
+<span class="source-line-no">613</span><span id="line-613">    R result = observerOperation.getResult();</span>
+<span class="source-line-no">614</span><span id="line-614">    return bypass == observerOperation.isBypassable() ? result : null;</span>
+<span class="source-line-no">615</span><span id="line-615">  }</span>
+<span class="source-line-no">616</span><span id="line-616"></span>
+<span class="source-line-no">617</span><span id="line-617">  /**</span>
+<span class="source-line-no">618</span><span id="line-618">   * @return True if we are to bypass (Can only be &lt;code&gt;true&lt;/code&gt; if</span>
+<span class="source-line-no">619</span><span id="line-619">   *         ObserverOperation#isBypassable().</span>
+<span class="source-line-no">620</span><span id="line-620">   */</span>
+<span class="source-line-no">621</span><span id="line-621">  protected &lt;O&gt; boolean execOperation(final ObserverOperation&lt;O&gt; observerOperation)</span>
+<span class="source-line-no">622</span><span id="line-622">    throws IOException {</span>
+<span class="source-line-no">623</span><span id="line-623">    boolean bypass = false;</span>
+<span class="source-line-no">624</span><span id="line-624">    if (observerOperation == null) {</span>
+<span class="source-line-no">625</span><span id="line-625">      return bypass;</span>
+<span class="source-line-no">626</span><span id="line-626">    }</span>
+<span class="source-line-no">627</span><span id="line-627">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
+<span class="source-line-no">628</span><span id="line-628">    for (E env : envs) {</span>
+<span class="source-line-no">629</span><span id="line-629">      observerOperation.prepare(env);</span>
+<span class="source-line-no">630</span><span id="line-630">      Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">631</span><span id="line-631">      ClassLoader cl = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">632</span><span id="line-632">      try {</span>
+<span class="source-line-no">633</span><span id="line-633">        currentThread.setContextClassLoader(env.getClassLoader());</span>
+<span class="source-line-no">634</span><span id="line-634">        observerOperation.callObserver();</span>
+<span class="source-line-no">635</span><span id="line-635">      } catch (Throwable e) {</span>
+<span class="source-line-no">636</span><span id="line-636">        handleCoprocessorThrowable(env, e);</span>
+<span class="source-line-no">637</span><span id="line-637">      } finally {</span>
+<span class="source-line-no">638</span><span id="line-638">        currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">639</span><span id="line-639">      }</span>
+<span class="source-line-no">640</span><span id="line-640">      // Internal to shouldBypass, it checks if obeserverOperation#isBypassable().</span>
+<span class="source-line-no">641</span><span id="line-641">      bypass |= observerOperation.shouldBypass();</span>
+<span class="source-line-no">642</span><span id="line-642">      observerOperation.postEnvCall();</span>
+<span class="source-line-no">643</span><span id="line-643">      if (bypass) {</span>
+<span class="source-line-no">644</span><span id="line-644">        // If CP says bypass, skip out w/o calling any following CPs; they might ruin our response.</span>
+<span class="source-line-no">645</span><span id="line-645">        // In hbase1, this used to be called 'complete'. In hbase2, we unite bypass and 'complete'.</span>
+<span class="source-line-no">646</span><span id="line-646">        break;</span>
+<span class="source-line-no">647</span><span id="line-647">      }</span>
+<span class="source-line-no">648</span><span id="line-648">    }</span>
+<span class="source-line-no">649</span><span id="line-649">    return bypass;</span>
+<span class="source-line-no">650</span><span id="line-650">  }</span>
+<span class="source-line-no">651</span><span id="line-651"></span>
+<span class="source-line-no">652</span><span id="line-652">  /**</span>
+<span class="source-line-no">653</span><span id="line-653">   * Coprocessor classes can be configured in any order, based on that priority is set and chained</span>
+<span class="source-line-no">654</span><span id="line-654">   * in a sorted order. Should be used preStop*() hooks i.e. when master/regionserver is going down.</span>
+<span class="source-line-no">655</span><span id="line-655">   * This function first calls coprocessor methods (using ObserverOperation.call()) and then</span>
+<span class="source-line-no">656</span><span id="line-656">   * shutdowns the environment in postEnvCall(). &lt;br&gt;</span>
+<span class="source-line-no">657</span><span id="line-657">   * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors</span>
+<span class="source-line-no">658</span><span id="line-658">   * may remain shutdown if any exception occurs during next coprocessor execution which prevent</span>
+<span class="source-line-no">659</span><span id="line-659">   * master/regionserver stop or cluster shutdown. (Refer:</span>
+<span class="source-line-no">660</span><span id="line-660">   * &lt;a href="https://issues.apache.org/jira/browse/HBASE-16663"&gt;HBASE-16663&lt;/a&gt;</span>
+<span class="source-line-no">661</span><span id="line-661">   * @return true if bypaas coprocessor execution, false if not.</span>
+<span class="source-line-no">662</span><span id="line-662">   */</span>
+<span class="source-line-no">663</span><span id="line-663">  protected &lt;O&gt; boolean execShutdown(final ObserverOperation&lt;O&gt; observerOperation)</span>
+<span class="source-line-no">664</span><span id="line-664">    throws IOException {</span>
+<span class="source-line-no">665</span><span id="line-665">    if (observerOperation == null) return false;</span>
+<span class="source-line-no">666</span><span id="line-666">    boolean bypass = false;</span>
+<span class="source-line-no">667</span><span id="line-667">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
+<span class="source-line-no">668</span><span id="line-668">    // Iterate the coprocessors and execute ObserverOperation's call()</span>
+<span class="source-line-no">669</span><span id="line-669">    for (E env : envs) {</span>
+<span class="source-line-no">670</span><span id="line-670">      observerOperation.prepare(env);</span>
+<span class="source-line-no">671</span><span id="line-671">      Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">672</span><span id="line-672">      ClassLoader cl = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">673</span><span id="line-673">      try {</span>
+<span class="source-line-no">674</span><span id="line-674">        currentThread.setContextClassLoader(env.getClassLoader());</span>
+<span class="source-line-no">675</span><span id="line-675">        observerOperation.callObserver();</span>
+<span class="source-line-no">676</span><span id="line-676">      } catch (Throwable e) {</span>
+<span class="source-line-no">677</span><span id="line-677">        handleCoprocessorThrowable(env, e);</span>
+<span class="source-line-no">678</span><span id="line-678">      } finally {</span>
+<span class="source-line-no">679</span><span id="line-679">        currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">680</span><span id="line-680">      }</span>
+<span class="source-line-no">681</span><span id="line-681">      bypass |= observerOperation.shouldBypass();</span>
+<span class="source-line-no">682</span><span id="line-682">    }</span>
+<span class="source-line-no">683</span><span id="line-683"></span>
+<span class="source-line-no">684</span><span id="line-684">    // Iterate the coprocessors and execute ObserverOperation's postEnvCall()</span>
+<span class="source-line-no">685</span><span id="line-685">    for (E env : envs) {</span>
+<span class="source-line-no">686</span><span id="line-686">      observerOperation.prepare(env);</span>
+<span class="source-line-no">687</span><span id="line-687">      observerOperation.postEnvCall();</span>
+<span class="source-line-no">688</span><span id="line-688">    }</span>
+<span class="source-line-no">689</span><span id="line-689">    return bypass;</span>
+<span class="source-line-no">690</span><span id="line-690">  }</span>
+<span class="source-line-no">691</span><span id="line-691">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverOperationWithResult.html b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverOperationWithResult.html
index 041cbb1471e..27c23f86022 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverOperationWithResult.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverOperationWithResult.html
@@ -74,632 +74,634 @@
 <span class="source-line-no">061</span><span id="line-61">  public static final String USER_REGION_COPROCESSOR_CONF_KEY =</span>
 <span class="source-line-no">062</span><span id="line-62">    "hbase.coprocessor.user.region.classes";</span>
 <span class="source-line-no">063</span><span id="line-63">  public static final String MASTER_COPROCESSOR_CONF_KEY = "hbase.coprocessor.master.classes";</span>
-<span class="source-line-no">064</span><span id="line-64">  public static final String WAL_COPROCESSOR_CONF_KEY = "hbase.coprocessor.wal.classes";</span>
-<span class="source-line-no">065</span><span id="line-65">  public static final String RPC_COPROCESSOR_CONF_KEY = "hbase.coprocessor.rpc.classes";</span>
-<span class="source-line-no">066</span><span id="line-66">  public static final String ABORT_ON_ERROR_KEY = "hbase.coprocessor.abortonerror";</span>
-<span class="source-line-no">067</span><span id="line-67">  public static final boolean DEFAULT_ABORT_ON_ERROR = true;</span>
-<span class="source-line-no">068</span><span id="line-68">  public static final String COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.enabled";</span>
-<span class="source-line-no">069</span><span id="line-69">  public static final boolean DEFAULT_COPROCESSORS_ENABLED = true;</span>
-<span class="source-line-no">070</span><span id="line-70">  public static final String USER_COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.user.enabled";</span>
-<span class="source-line-no">071</span><span id="line-71">  public static final boolean DEFAULT_USER_COPROCESSORS_ENABLED = true;</span>
-<span class="source-line-no">072</span><span id="line-72">  public static final String SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR =</span>
-<span class="source-line-no">073</span><span id="line-73">    "hbase.skip.load.duplicate.table.coprocessor";</span>
-<span class="source-line-no">074</span><span id="line-74">  public static final boolean DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR = false;</span>
-<span class="source-line-no">075</span><span id="line-75"></span>
-<span class="source-line-no">076</span><span id="line-76">  private static final Logger LOG = LoggerFactory.getLogger(CoprocessorHost.class);</span>
-<span class="source-line-no">077</span><span id="line-77">  protected Abortable abortable;</span>
-<span class="source-line-no">078</span><span id="line-78">  /** Ordered set of loaded coprocessors with lock */</span>
-<span class="source-line-no">079</span><span id="line-79">  protected final SortedList&lt;E&gt; coprocEnvironments =</span>
-<span class="source-line-no">080</span><span id="line-80">    new SortedList&lt;&gt;(new EnvironmentPriorityComparator());</span>
-<span class="source-line-no">081</span><span id="line-81">  protected Configuration conf;</span>
-<span class="source-line-no">082</span><span id="line-82">  // unique file prefix to use for local copies of jars when classloading</span>
-<span class="source-line-no">083</span><span id="line-83">  protected String pathPrefix;</span>
-<span class="source-line-no">084</span><span id="line-84">  protected AtomicInteger loadSequence = new AtomicInteger();</span>
-<span class="source-line-no">085</span><span id="line-85"></span>
-<span class="source-line-no">086</span><span id="line-86">  public CoprocessorHost(Abortable abortable) {</span>
-<span class="source-line-no">087</span><span id="line-87">    this.abortable = abortable;</span>
-<span class="source-line-no">088</span><span id="line-88">    this.pathPrefix = UUID.randomUUID().toString();</span>
-<span class="source-line-no">089</span><span id="line-89">  }</span>
-<span class="source-line-no">090</span><span id="line-90"></span>
-<span class="source-line-no">091</span><span id="line-91">  /**</span>
-<span class="source-line-no">092</span><span id="line-92">   * Not to be confused with the per-object _coprocessors_ (above), coprocessorNames is static and</span>
-<span class="source-line-no">093</span><span id="line-93">   * stores the set of all coprocessors ever loaded by any thread in this JVM. It is strictly</span>
-<span class="source-line-no">094</span><span id="line-94">   * additive: coprocessors are added to coprocessorNames, by checkAndLoadInstance() but are never</span>
-<span class="source-line-no">095</span><span id="line-95">   * removed, since the intention is to preserve a history of all loaded coprocessors for diagnosis</span>
-<span class="source-line-no">096</span><span id="line-96">   * in case of server crash (HBASE-4014).</span>
-<span class="source-line-no">097</span><span id="line-97">   */</span>
-<span class="source-line-no">098</span><span id="line-98">  private static Set&lt;String&gt; coprocessorNames = Collections.synchronizedSet(new HashSet&lt;String&gt;());</span>
-<span class="source-line-no">099</span><span id="line-99"></span>
-<span class="source-line-no">100</span><span id="line-100">  public static Set&lt;String&gt; getLoadedCoprocessors() {</span>
-<span class="source-line-no">101</span><span id="line-101">    synchronized (coprocessorNames) {</span>
-<span class="source-line-no">102</span><span id="line-102">      return new HashSet(coprocessorNames);</span>
-<span class="source-line-no">103</span><span id="line-103">    }</span>
-<span class="source-line-no">104</span><span id="line-104">  }</span>
-<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106">  /**</span>
-<span class="source-line-no">107</span><span id="line-107">   * Used to create a parameter to the HServerLoad constructor so that HServerLoad can provide</span>
-<span class="source-line-no">108</span><span id="line-108">   * information about the coprocessors loaded by this regionserver. (HBASE-4070: Improve region</span>
-<span class="source-line-no">109</span><span id="line-109">   * server metrics to report loaded coprocessors to master).</span>
-<span class="source-line-no">110</span><span id="line-110">   */</span>
-<span class="source-line-no">111</span><span id="line-111">  public Set&lt;String&gt; getCoprocessors() {</span>
-<span class="source-line-no">112</span><span id="line-112">    Set&lt;String&gt; returnValue = new TreeSet&lt;&gt;();</span>
-<span class="source-line-no">113</span><span id="line-113">    for (E e : coprocEnvironments) {</span>
-<span class="source-line-no">114</span><span id="line-114">      returnValue.add(e.getInstance().getClass().getSimpleName());</span>
-<span class="source-line-no">115</span><span id="line-115">    }</span>
-<span class="source-line-no">116</span><span id="line-116">    return returnValue;</span>
-<span class="source-line-no">117</span><span id="line-117">  }</span>
-<span class="source-line-no">118</span><span id="line-118"></span>
-<span class="source-line-no">119</span><span id="line-119">  /**</span>
-<span class="source-line-no">120</span><span id="line-120">   * Load system coprocessors once only. Read the class names from configuration. Called by</span>
-<span class="source-line-no">121</span><span id="line-121">   * constructor.</span>
-<span class="source-line-no">122</span><span id="line-122">   */</span>
-<span class="source-line-no">123</span><span id="line-123">  protected void loadSystemCoprocessors(Configuration conf, String confKey) {</span>
-<span class="source-line-no">124</span><span id="line-124">    boolean coprocessorsEnabled =</span>
-<span class="source-line-no">125</span><span id="line-125">      conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, DEFAULT_COPROCESSORS_ENABLED);</span>
-<span class="source-line-no">126</span><span id="line-126">    if (!coprocessorsEnabled) {</span>
-<span class="source-line-no">127</span><span id="line-127">      return;</span>
-<span class="source-line-no">128</span><span id="line-128">    }</span>
-<span class="source-line-no">129</span><span id="line-129"></span>
-<span class="source-line-no">130</span><span id="line-130">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">064</span><span id="line-64">  public static final String CLIENT_META_COPROCESSOR_CONF_KEY =</span>
+<span class="source-line-no">065</span><span id="line-65">    "hbase.coprocessor.clientmeta.classes";</span>
+<span class="source-line-no">066</span><span id="line-66">  public static final String WAL_COPROCESSOR_CONF_KEY = "hbase.coprocessor.wal.classes";</span>
+<span class="source-line-no">067</span><span id="line-67">  public static final String RPC_COPROCESSOR_CONF_KEY = "hbase.coprocessor.rpc.classes";</span>
+<span class="source-line-no">068</span><span id="line-68">  public static final String ABORT_ON_ERROR_KEY = "hbase.coprocessor.abortonerror";</span>
+<span class="source-line-no">069</span><span id="line-69">  public static final boolean DEFAULT_ABORT_ON_ERROR = true;</span>
+<span class="source-line-no">070</span><span id="line-70">  public static final String COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.enabled";</span>
+<span class="source-line-no">071</span><span id="line-71">  public static final boolean DEFAULT_COPROCESSORS_ENABLED = true;</span>
+<span class="source-line-no">072</span><span id="line-72">  public static final String USER_COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.user.enabled";</span>
+<span class="source-line-no">073</span><span id="line-73">  public static final boolean DEFAULT_USER_COPROCESSORS_ENABLED = true;</span>
+<span class="source-line-no">074</span><span id="line-74">  public static final String SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR =</span>
+<span class="source-line-no">075</span><span id="line-75">    "hbase.skip.load.duplicate.table.coprocessor";</span>
+<span class="source-line-no">076</span><span id="line-76">  public static final boolean DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR = false;</span>
+<span class="source-line-no">077</span><span id="line-77"></span>
+<span class="source-line-no">078</span><span id="line-78">  private static final Logger LOG = LoggerFactory.getLogger(CoprocessorHost.class);</span>
+<span class="source-line-no">079</span><span id="line-79">  protected Abortable abortable;</span>
+<span class="source-line-no">080</span><span id="line-80">  /** Ordered set of loaded coprocessors with lock */</span>
+<span class="source-line-no">081</span><span id="line-81">  protected final SortedList&lt;E&gt; coprocEnvironments =</span>
+<span class="source-line-no">082</span><span id="line-82">    new SortedList&lt;&gt;(new EnvironmentPriorityComparator());</span>
+<span class="source-line-no">083</span><span id="line-83">  protected Configuration conf;</span>
+<span class="source-line-no">084</span><span id="line-84">  // unique file prefix to use for local copies of jars when classloading</span>
+<span class="source-line-no">085</span><span id="line-85">  protected String pathPrefix;</span>
+<span class="source-line-no">086</span><span id="line-86">  protected AtomicInteger loadSequence = new AtomicInteger();</span>
+<span class="source-line-no">087</span><span id="line-87"></span>
+<span class="source-line-no">088</span><span id="line-88">  public CoprocessorHost(Abortable abortable) {</span>
+<span class="source-line-no">089</span><span id="line-89">    this.abortable = abortable;</span>
+<span class="source-line-no">090</span><span id="line-90">    this.pathPrefix = UUID.randomUUID().toString();</span>
+<span class="source-line-no">091</span><span id="line-91">  }</span>
+<span class="source-line-no">092</span><span id="line-92"></span>
+<span class="source-line-no">093</span><span id="line-93">  /**</span>
+<span class="source-line-no">094</span><span id="line-94">   * Not to be confused with the per-object _coprocessors_ (above), coprocessorNames is static and</span>
+<span class="source-line-no">095</span><span id="line-95">   * stores the set of all coprocessors ever loaded by any thread in this JVM. It is strictly</span>
+<span class="source-line-no">096</span><span id="line-96">   * additive: coprocessors are added to coprocessorNames, by checkAndLoadInstance() but are never</span>
+<span class="source-line-no">097</span><span id="line-97">   * removed, since the intention is to preserve a history of all loaded coprocessors for diagnosis</span>
+<span class="source-line-no">098</span><span id="line-98">   * in case of server crash (HBASE-4014).</span>
+<span class="source-line-no">099</span><span id="line-99">   */</span>
+<span class="source-line-no">100</span><span id="line-100">  private static Set&lt;String&gt; coprocessorNames = Collections.synchronizedSet(new HashSet&lt;String&gt;());</span>
+<span class="source-line-no">101</span><span id="line-101"></span>
+<span class="source-line-no">102</span><span id="line-102">  public static Set&lt;String&gt; getLoadedCoprocessors() {</span>
+<span class="source-line-no">103</span><span id="line-103">    synchronized (coprocessorNames) {</span>
+<span class="source-line-no">104</span><span id="line-104">      return new HashSet(coprocessorNames);</span>
+<span class="source-line-no">105</span><span id="line-105">    }</span>
+<span class="source-line-no">106</span><span id="line-106">  }</span>
+<span class="source-line-no">107</span><span id="line-107"></span>
+<span class="source-line-no">108</span><span id="line-108">  /**</span>
+<span class="source-line-no">109</span><span id="line-109">   * Used to create a parameter to the HServerLoad constructor so that HServerLoad can provide</span>
+<span class="source-line-no">110</span><span id="line-110">   * information about the coprocessors loaded by this regionserver. (HBASE-4070: Improve region</span>
+<span class="source-line-no">111</span><span id="line-111">   * server metrics to report loaded coprocessors to master).</span>
+<span class="source-line-no">112</span><span id="line-112">   */</span>
+<span class="source-line-no">113</span><span id="line-113">  public Set&lt;String&gt; getCoprocessors() {</span>
+<span class="source-line-no">114</span><span id="line-114">    Set&lt;String&gt; returnValue = new TreeSet&lt;&gt;();</span>
+<span class="source-line-no">115</span><span id="line-115">    for (E e : coprocEnvironments) {</span>
+<span class="source-line-no">116</span><span id="line-116">      returnValue.add(e.getInstance().getClass().getSimpleName());</span>
+<span class="source-line-no">117</span><span id="line-117">    }</span>
+<span class="source-line-no">118</span><span id="line-118">    return returnValue;</span>
+<span class="source-line-no">119</span><span id="line-119">  }</span>
+<span class="source-line-no">120</span><span id="line-120"></span>
+<span class="source-line-no">121</span><span id="line-121">  /**</span>
+<span class="source-line-no">122</span><span id="line-122">   * Load system coprocessors once only. Read the class names from configuration. Called by</span>
+<span class="source-line-no">123</span><span id="line-123">   * constructor.</span>
+<span class="source-line-no">124</span><span id="line-124">   */</span>
+<span class="source-line-no">125</span><span id="line-125">  protected void loadSystemCoprocessors(Configuration conf, String confKey) {</span>
+<span class="source-line-no">126</span><span id="line-126">    boolean coprocessorsEnabled =</span>
+<span class="source-line-no">127</span><span id="line-127">      conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, DEFAULT_COPROCESSORS_ENABLED);</span>
+<span class="source-line-no">128</span><span id="line-128">    if (!coprocessorsEnabled) {</span>
+<span class="source-line-no">129</span><span id="line-129">      return;</span>
+<span class="source-line-no">130</span><span id="line-130">    }</span>
 <span class="source-line-no">131</span><span id="line-131"></span>
-<span class="source-line-no">132</span><span id="line-132">    // load default coprocessors from configure file</span>
-<span class="source-line-no">133</span><span id="line-133">    String[] defaultCPClasses = conf.getStrings(confKey);</span>
-<span class="source-line-no">134</span><span id="line-134">    if (defaultCPClasses == null || defaultCPClasses.length == 0) return;</span>
-<span class="source-line-no">135</span><span id="line-135"></span>
-<span class="source-line-no">136</span><span id="line-136">    int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;</span>
-<span class="source-line-no">137</span><span id="line-137">    for (String className : defaultCPClasses) {</span>
-<span class="source-line-no">138</span><span id="line-138">      // After HBASE-23710 and HBASE-26714 when configuring for system coprocessor, we accept</span>
-<span class="source-line-no">139</span><span id="line-139">      // an optional format of className|priority|path</span>
-<span class="source-line-no">140</span><span id="line-140">      String[] classNameToken = className.split("\\|");</span>
-<span class="source-line-no">141</span><span id="line-141">      boolean hasPriorityOverride = false;</span>
-<span class="source-line-no">142</span><span id="line-142">      boolean hasPath = false;</span>
-<span class="source-line-no">143</span><span id="line-143">      className = classNameToken[0];</span>
-<span class="source-line-no">144</span><span id="line-144">      int overridePriority = Coprocessor.PRIORITY_SYSTEM;</span>
-<span class="source-line-no">145</span><span id="line-145">      Path path = null;</span>
-<span class="source-line-no">146</span><span id="line-146">      if (classNameToken.length &gt; 1 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[1])) {</span>
-<span class="source-line-no">147</span><span id="line-147">        overridePriority = Integer.parseInt(classNameToken[1]);</span>
-<span class="source-line-no">148</span><span id="line-148">        hasPriorityOverride = true;</span>
-<span class="source-line-no">149</span><span id="line-149">      }</span>
-<span class="source-line-no">150</span><span id="line-150">      if (classNameToken.length &gt; 2 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[2])) {</span>
-<span class="source-line-no">151</span><span id="line-151">        path = new Path(classNameToken[2].trim());</span>
-<span class="source-line-no">152</span><span id="line-152">        hasPath = true;</span>
-<span class="source-line-no">153</span><span id="line-153">      }</span>
-<span class="source-line-no">154</span><span id="line-154">      className = className.trim();</span>
-<span class="source-line-no">155</span><span id="line-155">      if (findCoprocessor(className) != null) {</span>
-<span class="source-line-no">156</span><span id="line-156">        // If already loaded will just continue</span>
-<span class="source-line-no">157</span><span id="line-157">        LOG.warn("Attempted duplicate loading of " + className + "; skipped");</span>
-<span class="source-line-no">158</span><span id="line-158">        continue;</span>
-<span class="source-line-no">159</span><span id="line-159">      }</span>
-<span class="source-line-no">160</span><span id="line-160">      ClassLoader cl = this.getClass().getClassLoader();</span>
-<span class="source-line-no">161</span><span id="line-161">      try {</span>
-<span class="source-line-no">162</span><span id="line-162">        // override the class loader if a path for the system coprocessor is provided.</span>
-<span class="source-line-no">163</span><span id="line-163">        if (hasPath) {</span>
-<span class="source-line-no">164</span><span id="line-164">          cl = CoprocessorClassLoader.getClassLoader(path, this.getClass().getClassLoader(),</span>
-<span class="source-line-no">165</span><span id="line-165">            pathPrefix, conf);</span>
-<span class="source-line-no">166</span><span id="line-166">        }</span>
-<span class="source-line-no">167</span><span id="line-167">        Thread.currentThread().setContextClassLoader(cl);</span>
-<span class="source-line-no">168</span><span id="line-168">        implClass = cl.loadClass(className);</span>
-<span class="source-line-no">169</span><span id="line-169">        int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;</span>
-<span class="source-line-no">170</span><span id="line-170">        // Add coprocessors as we go to guard against case where a coprocessor is specified twice</span>
-<span class="source-line-no">171</span><span id="line-171">        // in the configuration</span>
-<span class="source-line-no">172</span><span id="line-172">        E env = checkAndLoadInstance(implClass, coprocPriority, conf);</span>
-<span class="source-line-no">173</span><span id="line-173">        if (env != null) {</span>
-<span class="source-line-no">174</span><span id="line-174">          this.coprocEnvironments.add(env);</span>
-<span class="source-line-no">175</span><span id="line-175">          LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);</span>
-<span class="source-line-no">176</span><span id="line-176">          if (!hasPriorityOverride) {</span>
-<span class="source-line-no">177</span><span id="line-177">            ++currentSystemPriority;</span>
-<span class="source-line-no">178</span><span id="line-178">          }</span>
-<span class="source-line-no">179</span><span id="line-179">        }</span>
-<span class="source-line-no">180</span><span id="line-180">      } catch (Throwable t) {</span>
-<span class="source-line-no">181</span><span id="line-181">        // We always abort if system coprocessors cannot be loaded</span>
-<span class="source-line-no">182</span><span id="line-182">        abortServer(className, t);</span>
-<span class="source-line-no">183</span><span id="line-183">      }</span>
-<span class="source-line-no">184</span><span id="line-184">    }</span>
-<span class="source-line-no">185</span><span id="line-185">  }</span>
-<span class="source-line-no">186</span><span id="line-186"></span>
-<span class="source-line-no">187</span><span id="line-187">  /**</span>
-<span class="source-line-no">188</span><span id="line-188">   * Load a coprocessor implementation into the host</span>
-<span class="source-line-no">189</span><span id="line-189">   * @param path      path to implementation jar</span>
-<span class="source-line-no">190</span><span id="line-190">   * @param className the main class name</span>
-<span class="source-line-no">191</span><span id="line-191">   * @param priority  chaining priority</span>
-<span class="source-line-no">192</span><span id="line-192">   * @param conf      configuration for coprocessor</span>
-<span class="source-line-no">193</span><span id="line-193">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">194</span><span id="line-194">   */</span>
-<span class="source-line-no">195</span><span id="line-195">  public E load(Path path, String className, int priority, Configuration conf) throws IOException {</span>
-<span class="source-line-no">196</span><span id="line-196">    String[] includedClassPrefixes = null;</span>
-<span class="source-line-no">197</span><span id="line-197">    if (conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY) != null) {</span>
-<span class="source-line-no">198</span><span id="line-198">      String prefixes = conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY);</span>
-<span class="source-line-no">199</span><span id="line-199">      includedClassPrefixes = prefixes.split(";");</span>
-<span class="source-line-no">200</span><span id="line-200">    }</span>
-<span class="source-line-no">201</span><span id="line-201">    return load(path, className, priority, conf, includedClassPrefixes);</span>
-<span class="source-line-no">202</span><span id="line-202">  }</span>
-<span class="source-line-no">203</span><span id="line-203"></span>
-<span class="source-line-no">204</span><span id="line-204">  /**</span>
-<span class="source-line-no">205</span><span id="line-205">   * Load a coprocessor implementation into the host</span>
-<span class="source-line-no">206</span><span id="line-206">   * @param path                  path to implementation jar</span>
-<span class="source-line-no">207</span><span id="line-207">   * @param className             the main class name</span>
-<span class="source-line-no">208</span><span id="line-208">   * @param priority              chaining priority</span>
-<span class="source-line-no">209</span><span id="line-209">   * @param conf                  configuration for coprocessor</span>
-<span class="source-line-no">210</span><span id="line-210">   * @param includedClassPrefixes class name prefixes to include</span>
-<span class="source-line-no">211</span><span id="line-211">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">212</span><span id="line-212">   */</span>
-<span class="source-line-no">213</span><span id="line-213">  public E load(Path path, String className, int priority, Configuration conf,</span>
-<span class="source-line-no">214</span><span id="line-214">    String[] includedClassPrefixes) throws IOException {</span>
-<span class="source-line-no">215</span><span id="line-215">    Class&lt;?&gt; implClass;</span>
-<span class="source-line-no">216</span><span id="line-216">    LOG.debug("Loading coprocessor class " + className + " with path " + path + " and priority "</span>
-<span class="source-line-no">217</span><span id="line-217">      + priority);</span>
-<span class="source-line-no">218</span><span id="line-218"></span>
-<span class="source-line-no">219</span><span id="line-219">    boolean skipLoadDuplicateCoprocessor = conf.getBoolean(SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR,</span>
-<span class="source-line-no">220</span><span id="line-220">      DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR);</span>
-<span class="source-line-no">221</span><span id="line-221">    if (skipLoadDuplicateCoprocessor &amp;&amp; findCoprocessor(className) != null) {</span>
-<span class="source-line-no">222</span><span id="line-222">      // If already loaded will just continue</span>
-<span class="source-line-no">223</span><span id="line-223">      LOG.warn("Attempted duplicate loading of {}; skipped", className);</span>
-<span class="source-line-no">224</span><span id="line-224">      return null;</span>
-<span class="source-line-no">225</span><span id="line-225">    }</span>
-<span class="source-line-no">226</span><span id="line-226"></span>
-<span class="source-line-no">227</span><span id="line-227">    ClassLoader cl = null;</span>
-<span class="source-line-no">228</span><span id="line-228">    if (path == null) {</span>
-<span class="source-line-no">229</span><span id="line-229">      try {</span>
-<span class="source-line-no">230</span><span id="line-230">        implClass = getClass().getClassLoader().loadClass(className);</span>
-<span class="source-line-no">231</span><span id="line-231">      } catch (ClassNotFoundException e) {</span>
-<span class="source-line-no">232</span><span id="line-232">        throw new IOException("No jar path specified for " + className);</span>
-<span class="source-line-no">233</span><span id="line-233">      }</span>
-<span class="source-line-no">234</span><span id="line-234">    } else {</span>
-<span class="source-line-no">235</span><span id="line-235">      cl =</span>
-<span class="source-line-no">236</span><span id="line-236">        CoprocessorClassLoader.getClassLoader(path, getClass().getClassLoader(), pathPrefix, conf);</span>
-<span class="source-line-no">237</span><span id="line-237">      try {</span>
-<span class="source-line-no">238</span><span id="line-238">        implClass = ((CoprocessorClassLoader) cl).loadClass(className, includedClassPrefixes);</span>
-<span class="source-line-no">239</span><span id="line-239">      } catch (ClassNotFoundException e) {</span>
-<span class="source-line-no">240</span><span id="line-240">        throw new IOException("Cannot load external coprocessor class " + className, e);</span>
-<span class="source-line-no">241</span><span id="line-241">      }</span>
-<span class="source-line-no">242</span><span id="line-242">    }</span>
-<span class="source-line-no">243</span><span id="line-243"></span>
-<span class="source-line-no">244</span><span id="line-244">    // load custom code for coprocessor</span>
-<span class="source-line-no">245</span><span id="line-245">    Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">246</span><span id="line-246">    ClassLoader hostClassLoader = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">247</span><span id="line-247">    try {</span>
-<span class="source-line-no">248</span><span id="line-248">      // switch temporarily to the thread classloader for custom CP</span>
-<span class="source-line-no">249</span><span id="line-249">      currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">250</span><span id="line-250">      E cpInstance = checkAndLoadInstance(implClass, priority, conf);</span>
-<span class="source-line-no">251</span><span id="line-251">      return cpInstance;</span>
-<span class="source-line-no">252</span><span id="line-252">    } finally {</span>
-<span class="source-line-no">253</span><span id="line-253">      // restore the fresh (host) classloader</span>
-<span class="source-line-no">254</span><span id="line-254">      currentThread.setContextClassLoader(hostClassLoader);</span>
-<span class="source-line-no">255</span><span id="line-255">    }</span>
-<span class="source-line-no">256</span><span id="line-256">  }</span>
-<span class="source-line-no">257</span><span id="line-257"></span>
-<span class="source-line-no">258</span><span id="line-258">  public void load(Class&lt;? extends C&gt; implClass, int priority, Configuration conf)</span>
-<span class="source-line-no">259</span><span id="line-259">    throws IOException {</span>
-<span class="source-line-no">260</span><span id="line-260">    E env = checkAndLoadInstance(implClass, priority, conf);</span>
-<span class="source-line-no">261</span><span id="line-261">    coprocEnvironments.add(env);</span>
-<span class="source-line-no">262</span><span id="line-262">  }</span>
-<span class="source-line-no">263</span><span id="line-263"></span>
-<span class="source-line-no">264</span><span id="line-264">  /**</span>
-<span class="source-line-no">265</span><span id="line-265">   * @param implClass Implementation class</span>
-<span class="source-line-no">266</span><span id="line-266">   * @param priority  priority</span>
-<span class="source-line-no">267</span><span id="line-267">   * @param conf      configuration</span>
-<span class="source-line-no">268</span><span id="line-268">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">269</span><span id="line-269">   */</span>
-<span class="source-line-no">270</span><span id="line-270">  public E checkAndLoadInstance(Class&lt;?&gt; implClass, int priority, Configuration conf)</span>
-<span class="source-line-no">271</span><span id="line-271">    throws IOException {</span>
-<span class="source-line-no">272</span><span id="line-272">    // create the instance</span>
-<span class="source-line-no">273</span><span id="line-273">    C impl;</span>
-<span class="source-line-no">274</span><span id="line-274">    try {</span>
-<span class="source-line-no">275</span><span id="line-275">      impl = checkAndGetInstance(implClass);</span>
-<span class="source-line-no">276</span><span id="line-276">      if (impl == null) {</span>
-<span class="source-line-no">277</span><span id="line-277">        LOG.error("Cannot load coprocessor " + implClass.getSimpleName());</span>
-<span class="source-line-no">278</span><span id="line-278">        return null;</span>
-<span class="source-line-no">279</span><span id="line-279">      }</span>
-<span class="source-line-no">280</span><span id="line-280">    } catch (InstantiationException | IllegalAccessException e) {</span>
-<span class="source-line-no">281</span><span id="line-281">      throw new IOException(e);</span>
-<span class="source-line-no">282</span><span id="line-282">    }</span>
-<span class="source-line-no">283</span><span id="line-283">    // create the environment</span>
-<span class="source-line-no">284</span><span id="line-284">    E env = createEnvironment(impl, priority, loadSequence.incrementAndGet(), conf);</span>
-<span class="source-line-no">285</span><span id="line-285">    assert env instanceof BaseEnvironment;</span>
-<span class="source-line-no">286</span><span id="line-286">    ((BaseEnvironment&lt;C&gt;) env).startup();</span>
-<span class="source-line-no">287</span><span id="line-287">    // HBASE-4014: maintain list of loaded coprocessors for later crash analysis</span>
-<span class="source-line-no">288</span><span id="line-288">    // if server (master or regionserver) aborts.</span>
-<span class="source-line-no">289</span><span id="line-289">    coprocessorNames.add(implClass.getName());</span>
-<span class="source-line-no">290</span><span id="line-290">    return env;</span>
-<span class="source-line-no">291</span><span id="line-291">  }</span>
-<span class="source-line-no">292</span><span id="line-292"></span>
-<span class="source-line-no">293</span><span id="line-293">  /**</span>
-<span class="source-line-no">294</span><span id="line-294">   * Called when a new Coprocessor class is loaded</span>
-<span class="source-line-no">295</span><span id="line-295">   */</span>
-<span class="source-line-no">296</span><span id="line-296">  public abstract E createEnvironment(C instance, int priority, int sequence, Configuration conf);</span>
-<span class="source-line-no">297</span><span id="line-297"></span>
-<span class="source-line-no">298</span><span id="line-298">  /**</span>
-<span class="source-line-no">299</span><span id="line-299">   * Called when a new Coprocessor class needs to be loaded. Checks if type of the given class is</span>
-<span class="source-line-no">300</span><span id="line-300">   * what the corresponding host implementation expects. If it is of correct type, returns an</span>
-<span class="source-line-no">301</span><span id="line-301">   * instance of the coprocessor to be loaded. If not, returns null. If an exception occurs when</span>
-<span class="source-line-no">302</span><span id="line-302">   * trying to create instance of a coprocessor, it's passed up and eventually results into server</span>
-<span class="source-line-no">303</span><span id="line-303">   * aborting.</span>
-<span class="source-line-no">304</span><span id="line-304">   */</span>
-<span class="source-line-no">305</span><span id="line-305">  public abstract C checkAndGetInstance(Class&lt;?&gt; implClass)</span>
-<span class="source-line-no">306</span><span id="line-306">    throws InstantiationException, IllegalAccessException;</span>
-<span class="source-line-no">307</span><span id="line-307"></span>
-<span class="source-line-no">308</span><span id="line-308">  public void shutdown(E e) {</span>
-<span class="source-line-no">309</span><span id="line-309">    assert e instanceof BaseEnvironment;</span>
-<span class="source-line-no">310</span><span id="line-310">    if (LOG.isDebugEnabled()) {</span>
-<span class="source-line-no">311</span><span id="line-311">      LOG.debug("Stop coprocessor " + e.getInstance().getClass().getName());</span>
-<span class="source-line-no">312</span><span id="line-312">    }</span>
-<span class="source-line-no">313</span><span id="line-313">    ((BaseEnvironment&lt;C&gt;) e).shutdown();</span>
-<span class="source-line-no">314</span><span id="line-314">  }</span>
-<span class="source-line-no">315</span><span id="line-315"></span>
-<span class="source-line-no">316</span><span id="line-316">  /**</span>
-<span class="source-line-no">317</span><span id="line-317">   * Find coprocessors by full class name or simple name.</span>
-<span class="source-line-no">318</span><span id="line-318">   */</span>
-<span class="source-line-no">319</span><span id="line-319">  public C findCoprocessor(String className) {</span>
-<span class="source-line-no">320</span><span id="line-320">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">321</span><span id="line-321">      if (</span>
-<span class="source-line-no">322</span><span id="line-322">        env.getInstance().getClass().getName().equals(className)</span>
-<span class="source-line-no">323</span><span id="line-323">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
-<span class="source-line-no">324</span><span id="line-324">      ) {</span>
-<span class="source-line-no">325</span><span id="line-325">        return env.getInstance();</span>
-<span class="source-line-no">326</span><span id="line-326">      }</span>
-<span class="source-line-no">327</span><span id="line-327">    }</span>
-<span class="source-line-no">328</span><span id="line-328">    return null;</span>
-<span class="source-line-no">329</span><span id="line-329">  }</span>
-<span class="source-line-no">330</span><span id="line-330"></span>
-<span class="source-line-no">331</span><span id="line-331">  public &lt;T extends C&gt; T findCoprocessor(Class&lt;T&gt; cls) {</span>
-<span class="source-line-no">332</span><span id="line-332">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">333</span><span id="line-333">      if (cls.isAssignableFrom(env.getInstance().getClass())) {</span>
-<span class="source-line-no">334</span><span id="line-334">        return (T) env.getInstance();</span>
-<span class="source-line-no">335</span><span id="line-335">      }</span>
-<span class="source-line-no">336</span><span id="line-336">    }</span>
-<span class="source-line-no">337</span><span id="line-337">    return null;</span>
-<span class="source-line-no">338</span><span id="line-338">  }</span>
-<span class="source-line-no">339</span><span id="line-339"></span>
-<span class="source-line-no">340</span><span id="line-340">  /**</span>
-<span class="source-line-no">341</span><span id="line-341">   * Find list of coprocessors that extend/implement the given class/interface</span>
-<span class="source-line-no">342</span><span id="line-342">   * @param cls the class/interface to look for</span>
-<span class="source-line-no">343</span><span id="line-343">   * @return the list of coprocessors, or null if not found</span>
-<span class="source-line-no">344</span><span id="line-344">   */</span>
-<span class="source-line-no">345</span><span id="line-345">  public &lt;T extends C&gt; List&lt;T&gt; findCoprocessors(Class&lt;T&gt; cls) {</span>
-<span class="source-line-no">346</span><span id="line-346">    ArrayList&lt;T&gt; ret = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">347</span><span id="line-347"></span>
-<span class="source-line-no">348</span><span id="line-348">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">349</span><span id="line-349">      C cp = env.getInstance();</span>
-<span class="source-line-no">350</span><span id="line-350"></span>
-<span class="source-line-no">351</span><span id="line-351">      if (cp != null) {</span>
-<span class="source-line-no">352</span><span id="line-352">        if (cls.isAssignableFrom(cp.getClass())) {</span>
-<span class="source-line-no">353</span><span id="line-353">          ret.add((T) cp);</span>
-<span class="source-line-no">354</span><span id="line-354">        }</span>
-<span class="source-line-no">355</span><span id="line-355">      }</span>
-<span class="source-line-no">356</span><span id="line-356">    }</span>
-<span class="source-line-no">357</span><span id="line-357">    return ret;</span>
-<span class="source-line-no">358</span><span id="line-358">  }</span>
-<span class="source-line-no">359</span><span id="line-359"></span>
-<span class="source-line-no">360</span><span id="line-360">  /**</span>
-<span class="source-line-no">361</span><span id="line-361">   * Find a coprocessor environment by class name</span>
-<span class="source-line-no">362</span><span id="line-362">   * @param className the class name</span>
-<span class="source-line-no">363</span><span id="line-363">   * @return the coprocessor, or null if not found</span>
-<span class="source-line-no">364</span><span id="line-364">   */</span>
-<span class="source-line-no">365</span><span id="line-365">  public E findCoprocessorEnvironment(String className) {</span>
-<span class="source-line-no">366</span><span id="line-366">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">367</span><span id="line-367">      if (</span>
-<span class="source-line-no">368</span><span id="line-368">        env.getInstance().getClass().getName().equals(className)</span>
-<span class="source-line-no">369</span><span id="line-369">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
-<span class="source-line-no">370</span><span id="line-370">      ) {</span>
-<span class="source-line-no">371</span><span id="line-371">        return env;</span>
-<span class="source-line-no">372</span><span id="line-372">      }</span>
-<span class="source-line-no">373</span><span id="line-373">    }</span>
-<span class="source-line-no">374</span><span id="line-374">    return null;</span>
-<span class="source-line-no">375</span><span id="line-375">  }</span>
-<span class="source-line-no">376</span><span id="line-376"></span>
-<span class="source-line-no">377</span><span id="line-377">  /**</span>
-<span class="source-line-no">378</span><span id="line-378">   * Retrieves the set of classloaders used to instantiate Coprocessor classes defined in external</span>
-<span class="source-line-no">379</span><span id="line-379">   * jar files.</span>
-<span class="source-line-no">380</span><span id="line-380">   * @return A set of ClassLoader instances</span>
-<span class="source-line-no">381</span><span id="line-381">   */</span>
-<span class="source-line-no">382</span><span id="line-382">  Set&lt;ClassLoader&gt; getExternalClassLoaders() {</span>
-<span class="source-line-no">383</span><span id="line-383">    Set&lt;ClassLoader&gt; externalClassLoaders = new HashSet&lt;&gt;();</span>
-<span class="source-line-no">384</span><span id="line-384">    final ClassLoader systemClassLoader = this.getClass().getClassLoader();</span>
-<span class="source-line-no">385</span><span id="line-385">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">386</span><span id="line-386">      ClassLoader cl = env.getInstance().getClass().getClassLoader();</span>
-<span class="source-line-no">387</span><span id="line-387">      if (cl != systemClassLoader) {</span>
-<span class="source-line-no">388</span><span id="line-388">        // do not include system classloader</span>
-<span class="source-line-no">389</span><span id="line-389">        externalClassLoaders.add(cl);</span>
-<span class="source-line-no">390</span><span id="line-390">      }</span>
-<span class="source-line-no">391</span><span id="line-391">    }</span>
-<span class="source-line-no">392</span><span id="line-392">    return externalClassLoaders;</span>
-<span class="source-line-no">393</span><span id="line-393">  }</span>
-<span class="source-line-no">394</span><span id="line-394"></span>
-<span class="source-line-no">395</span><span id="line-395">  /**</span>
-<span class="source-line-no">396</span><span id="line-396">   * Environment priority comparator. Coprocessors are chained in sorted order.</span>
-<span class="source-line-no">397</span><span id="line-397">   */</span>
-<span class="source-line-no">398</span><span id="line-398">  static class EnvironmentPriorityComparator implements Comparator&lt;CoprocessorEnvironment&gt; {</span>
-<span class="source-line-no">399</span><span id="line-399">    @Override</span>
-<span class="source-line-no">400</span><span id="line-400">    public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) {</span>
-<span class="source-line-no">401</span><span id="line-401">      if (env1.getPriority() &lt; env2.getPriority()) {</span>
-<span class="source-line-no">402</span><span id="line-402">        return -1;</span>
-<span class="source-line-no">403</span><span id="line-403">      } else if (env1.getPriority() &gt; env2.getPriority()) {</span>
-<span class="source-line-no">404</span><span id="line-404">        return 1;</span>
-<span class="source-line-no">405</span><span id="line-405">      }</span>
-<span class="source-line-no">406</span><span id="line-406">      if (env1.getLoadSequence() &lt; env2.getLoadSequence()) {</span>
-<span class="source-line-no">407</span><span id="line-407">        return -1;</span>
-<span class="source-line-no">408</span><span id="line-408">      } else if (env1.getLoadSequence() &gt; env2.getLoadSequence()) {</span>
-<span class="source-line-no">409</span><span id="line-409">        return 1;</span>
-<span class="source-line-no">410</span><span id="line-410">      }</span>
-<span class="source-line-no">411</span><span id="line-411">      return 0;</span>
-<span class="source-line-no">412</span><span id="line-412">    }</span>
-<span class="source-line-no">413</span><span id="line-413">  }</span>
-<span class="source-line-no">414</span><span id="line-414"></span>
-<span class="source-line-no">415</span><span id="line-415">  protected void abortServer(final E environment, final Throwable e) {</span>
-<span class="source-line-no">416</span><span id="line-416">    abortServer(environment.getInstance().getClass().getName(), e);</span>
-<span class="source-line-no">417</span><span id="line-417">  }</span>
-<span class="source-line-no">418</span><span id="line-418"></span>
-<span class="source-line-no">419</span><span id="line-419">  protected void abortServer(final String coprocessorName, final Throwable e) {</span>
-<span class="source-line-no">420</span><span id="line-420">    String message = "The coprocessor " + coprocessorName + " threw " + e.toString();</span>
-<span class="source-line-no">421</span><span id="line-421">    LOG.error(message, e);</span>
-<span class="source-line-no">422</span><span id="line-422">    if (abortable != null) {</span>
-<span class="source-line-no">423</span><span id="line-423">      abortable.abort(message, e);</span>
-<span class="source-line-no">424</span><span id="line-424">    } else {</span>
-<span class="source-line-no">425</span><span id="line-425">      LOG.warn("No available Abortable, process was not aborted");</span>
-<span class="source-line-no">426</span><span id="line-426">    }</span>
-<span class="source-line-no">427</span><span id="line-427">  }</span>
-<span class="source-line-no">428</span><span id="line-428"></span>
-<span class="source-line-no">429</span><span id="line-429">  /**</span>
-<span class="source-line-no">430</span><span id="line-430">   * This is used by coprocessor hooks which are declared to throw IOException (or its subtypes).</span>
-<span class="source-line-no">431</span><span id="line-431">   * For such hooks, we should handle throwable objects depending on the Throwable's type. Those</span>
-<span class="source-line-no">432</span><span id="line-432">   * which are instances of IOException should be passed on to the client. This is in conformance</span>
-<span class="source-line-no">433</span><span id="line-433">   * with the HBase idiom regarding IOException: that it represents a circumstance that should be</span>
-<span class="source-line-no">434</span><span id="line-434">   * passed along to the client for its own handling. For example, a coprocessor that implements</span>
-<span class="source-line-no">435</span><span id="line-435">   * access controls would throw a subclass of IOException, such as AccessDeniedException, in its</span>
-<span class="source-line-no">436</span><span id="line-436">   * preGet() method to prevent an unauthorized client's performing a Get on a particular table.</span>
-<span class="source-line-no">437</span><span id="line-437">   * @param env Coprocessor Environment</span>
-<span class="source-line-no">438</span><span id="line-438">   * @param e   Throwable object thrown by coprocessor.</span>
-<span class="source-line-no">439</span><span id="line-439">   * @exception IOException Exception</span>
-<span class="source-line-no">440</span><span id="line-440">   */</span>
-<span class="source-line-no">441</span><span id="line-441">  // Note to devs: Class comments of all observers ({@link MasterObserver}, {@link WALObserver},</span>
-<span class="source-line-no">442</span><span id="line-442">  // etc) mention this nuance of our exception handling so that coprocessor can throw appropriate</span>
-<span class="source-line-no">443</span><span id="line-443">  // exceptions depending on situation. If any changes are made to this logic, make sure to</span>
-<span class="source-line-no">444</span><span id="line-444">  // update all classes' comments.</span>
-<span class="source-line-no">445</span><span id="line-445">  protected void handleCoprocessorThrowable(final E env, final Throwable e) throws IOException {</span>
-<span class="source-line-no">446</span><span id="line-446">    if (e instanceof IOException) {</span>
-<span class="source-line-no">447</span><span id="line-447">      throw (IOException) e;</span>
-<span class="source-line-no">448</span><span id="line-448">    }</span>
-<span class="source-line-no">449</span><span id="line-449">    // If we got here, e is not an IOException. A loaded coprocessor has a</span>
-<span class="source-line-no">450</span><span id="line-450">    // fatal bug, and the server (master or regionserver) should remove the</span>
-<span class="source-line-no">451</span><span id="line-451">    // faulty coprocessor from its set of active coprocessors. Setting</span>
-<span class="source-line-no">452</span><span id="line-452">    // 'hbase.coprocessor.abortonerror' to true will cause abortServer(),</span>
-<span class="source-line-no">453</span><span id="line-453">    // which may be useful in development and testing environments where</span>
-<span class="source-line-no">454</span><span id="line-454">    // 'failing fast' for error analysis is desired.</span>
-<span class="source-line-no">455</span><span id="line-455">    if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) {</span>
-<span class="source-line-no">456</span><span id="line-456">      // server is configured to abort.</span>
-<span class="source-line-no">457</span><span id="line-457">      abortServer(env, e);</span>
-<span class="source-line-no">458</span><span id="line-458">    } else {</span>
-<span class="source-line-no">459</span><span id="line-459">      // If available, pull a table name out of the environment</span>
-<span class="source-line-no">460</span><span id="line-460">      if (env instanceof RegionCoprocessorEnvironment) {</span>
-<span class="source-line-no">461</span><span id="line-461">        String tableName =</span>
-<span class="source-line-no">462</span><span id="line-462">          ((RegionCoprocessorEnvironment) env).getRegionInfo().getTable().getNameAsString();</span>
-<span class="source-line-no">463</span><span id="line-463">        LOG.error("Removing coprocessor '" + env.toString() + "' from table '" + tableName + "'",</span>
-<span class="source-line-no">464</span><span id="line-464">          e);</span>
-<span class="source-line-no">465</span><span id="line-465">      } else {</span>
-<span class="source-line-no">466</span><span id="line-466">        LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment", e);</span>
-<span class="source-line-no">467</span><span id="line-467">      }</span>
-<span class="source-line-no">468</span><span id="line-468"></span>
-<span class="source-line-no">469</span><span id="line-469">      coprocEnvironments.remove(env);</span>
-<span class="source-line-no">470</span><span id="line-470">      try {</span>
-<span class="source-line-no">471</span><span id="line-471">        shutdown(env);</span>
-<span class="source-line-no">472</span><span id="line-472">      } catch (Exception x) {</span>
-<span class="source-line-no">473</span><span id="line-473">        LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x);</span>
-<span class="source-line-no">474</span><span id="line-474">      }</span>
-<span class="source-line-no">475</span><span id="line-475">      throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e</span>
-<span class="source-line-no">476</span><span id="line-476">        + "' and has been removed from the active " + "coprocessor set.", e);</span>
-<span class="source-line-no">477</span><span id="line-477">    }</span>
-<span class="source-line-no">478</span><span id="line-478">  }</span>
-<span class="source-line-no">479</span><span id="line-479"></span>
-<span class="source-line-no">480</span><span id="line-480">  /**</span>
-<span class="source-line-no">481</span><span id="line-481">   * Used to limit legacy handling to once per Coprocessor class per classloader.</span>
-<span class="source-line-no">482</span><span id="line-482">   */</span>
-<span class="source-line-no">483</span><span id="line-483">  private static final Set&lt;Class&lt;? extends Coprocessor&gt;&gt; legacyWarning =</span>
-<span class="source-line-no">484</span><span id="line-484">    new ConcurrentSkipListSet&lt;&gt;(new Comparator&lt;Class&lt;? extends Coprocessor&gt;&gt;() {</span>
-<span class="source-line-no">485</span><span id="line-485">      @Override</span>
-<span class="source-line-no">486</span><span id="line-486">      public int compare(Class&lt;? extends Coprocessor&gt; c1, Class&lt;? extends Coprocessor&gt; c2) {</span>
-<span class="source-line-no">487</span><span id="line-487">        if (c1.equals(c2)) {</span>
-<span class="source-line-no">488</span><span id="line-488">          return 0;</span>
-<span class="source-line-no">489</span><span id="line-489">        }</span>
-<span class="source-line-no">490</span><span id="line-490">        return c1.getName().compareTo(c2.getName());</span>
-<span class="source-line-no">491</span><span id="line-491">      }</span>
-<span class="source-line-no">492</span><span id="line-492">    });</span>
-<span class="source-line-no">493</span><span id="line-493"></span>
-<span class="source-line-no">494</span><span id="line-494">  /**</span>
-<span class="source-line-no">495</span><span id="line-495">   * Implementations defined function to get an observer of type {@code O} from a coprocessor of</span>
-<span class="source-line-no">496</span><span id="line-496">   * type {@code C}. Concrete implementations of CoprocessorHost define one getter for each observer</span>
-<span class="source-line-no">497</span><span id="line-497">   * they can handle. For e.g. RegionCoprocessorHost will use 3 getters, one for each of</span>
-<span class="source-line-no">498</span><span id="line-498">   * RegionObserver, EndpointObserver and BulkLoadObserver. These getters are used by</span>
-<span class="source-line-no">499</span><span id="line-499">   * {@code ObserverOperation} to get appropriate observer from the coprocessor.</span>
-<span class="source-line-no">500</span><span id="line-500">   */</span>
-<span class="source-line-no">501</span><span id="line-501">  @FunctionalInterface</span>
-<span class="source-line-no">502</span><span id="line-502">  public interface ObserverGetter&lt;C, O&gt; extends Function&lt;C, Optional&lt;O&gt;&gt; {</span>
-<span class="source-line-no">503</span><span id="line-503">  }</span>
-<span class="source-line-no">504</span><span id="line-504"></span>
-<span class="source-line-no">505</span><span id="line-505">  private abstract class ObserverOperation&lt;O&gt; extends ObserverContextImpl&lt;E&gt; {</span>
-<span class="source-line-no">506</span><span id="line-506">    ObserverGetter&lt;C, O&gt; observerGetter;</span>
-<span class="source-line-no">507</span><span id="line-507"></span>
-<span class="source-line-no">508</span><span id="line-508">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
-<span class="source-line-no">509</span><span id="line-509">      this(observerGetter, null);</span>
-<span class="source-line-no">510</span><span id="line-510">    }</span>
-<span class="source-line-no">511</span><span id="line-511"></span>
-<span class="source-line-no">512</span><span id="line-512">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
-<span class="source-line-no">513</span><span id="line-513">      this(observerGetter, user, false);</span>
-<span class="source-line-no">514</span><span id="line-514">    }</span>
-<span class="source-line-no">515</span><span id="line-515"></span>
-<span class="source-line-no">516</span><span id="line-516">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, boolean bypassable) {</span>
-<span class="source-line-no">517</span><span id="line-517">      this(observerGetter, null, bypassable);</span>
-<span class="source-line-no">518</span><span id="line-518">    }</span>
-<span class="source-line-no">519</span><span id="line-519"></span>
-<span class="source-line-no">520</span><span id="line-520">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user, boolean bypassable) {</span>
-<span class="source-line-no">521</span><span id="line-521">      super(user != null ? user : RpcServer.getRequestUser().orElse(null), bypassable);</span>
-<span class="source-line-no">522</span><span id="line-522">      this.observerGetter = observerGetter;</span>
-<span class="source-line-no">523</span><span id="line-523">    }</span>
-<span class="source-line-no">524</span><span id="line-524"></span>
-<span class="source-line-no">525</span><span id="line-525">    abstract void callObserver() throws IOException;</span>
+<span class="source-line-no">132</span><span id="line-132">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">133</span><span id="line-133"></span>
+<span class="source-line-no">134</span><span id="line-134">    // load default coprocessors from configure file</span>
+<span class="source-line-no">135</span><span id="line-135">    String[] defaultCPClasses = conf.getStrings(confKey);</span>
+<span class="source-line-no">136</span><span id="line-136">    if (defaultCPClasses == null || defaultCPClasses.length == 0) return;</span>
+<span class="source-line-no">137</span><span id="line-137"></span>
+<span class="source-line-no">138</span><span id="line-138">    int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;</span>
+<span class="source-line-no">139</span><span id="line-139">    for (String className : defaultCPClasses) {</span>
+<span class="source-line-no">140</span><span id="line-140">      // After HBASE-23710 and HBASE-26714 when configuring for system coprocessor, we accept</span>
+<span class="source-line-no">141</span><span id="line-141">      // an optional format of className|priority|path</span>
+<span class="source-line-no">142</span><span id="line-142">      String[] classNameToken = className.split("\\|");</span>
+<span class="source-line-no">143</span><span id="line-143">      boolean hasPriorityOverride = false;</span>
+<span class="source-line-no">144</span><span id="line-144">      boolean hasPath = false;</span>
+<span class="source-line-no">145</span><span id="line-145">      className = classNameToken[0];</span>
+<span class="source-line-no">146</span><span id="line-146">      int overridePriority = Coprocessor.PRIORITY_SYSTEM;</span>
+<span class="source-line-no">147</span><span id="line-147">      Path path = null;</span>
+<span class="source-line-no">148</span><span id="line-148">      if (classNameToken.length &gt; 1 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[1])) {</span>
+<span class="source-line-no">149</span><span id="line-149">        overridePriority = Integer.parseInt(classNameToken[1]);</span>
+<span class="source-line-no">150</span><span id="line-150">        hasPriorityOverride = true;</span>
+<span class="source-line-no">151</span><span id="line-151">      }</span>
+<span class="source-line-no">152</span><span id="line-152">      if (classNameToken.length &gt; 2 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[2])) {</span>
+<span class="source-line-no">153</span><span id="line-153">        path = new Path(classNameToken[2].trim());</span>
+<span class="source-line-no">154</span><span id="line-154">        hasPath = true;</span>
+<span class="source-line-no">155</span><span id="line-155">      }</span>
+<span class="source-line-no">156</span><span id="line-156">      className = className.trim();</span>
+<span class="source-line-no">157</span><span id="line-157">      if (findCoprocessor(className) != null) {</span>
+<span class="source-line-no">158</span><span id="line-158">        // If already loaded will just continue</span>
+<span class="source-line-no">159</span><span id="line-159">        LOG.warn("Attempted duplicate loading of " + className + "; skipped");</span>
+<span class="source-line-no">160</span><span id="line-160">        continue;</span>
+<span class="source-line-no">161</span><span id="line-161">      }</span>
+<span class="source-line-no">162</span><span id="line-162">      ClassLoader cl = this.getClass().getClassLoader();</span>
+<span class="source-line-no">163</span><span id="line-163">      try {</span>
+<span class="source-line-no">164</span><span id="line-164">        // override the class loader if a path for the system coprocessor is provided.</span>
+<span class="source-line-no">165</span><span id="line-165">        if (hasPath) {</span>
+<span class="source-line-no">166</span><span id="line-166">          cl = CoprocessorClassLoader.getClassLoader(path, this.getClass().getClassLoader(),</span>
+<span class="source-line-no">167</span><span id="line-167">            pathPrefix, conf);</span>
+<span class="source-line-no">168</span><span id="line-168">        }</span>
+<span class="source-line-no">169</span><span id="line-169">        Thread.currentThread().setContextClassLoader(cl);</span>
+<span class="source-line-no">170</span><span id="line-170">        implClass = cl.loadClass(className);</span>
+<span class="source-line-no">171</span><span id="line-171">        int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;</span>
+<span class="source-line-no">172</span><span id="line-172">        // Add coprocessors as we go to guard against case where a coprocessor is specified twice</span>
+<span class="source-line-no">173</span><span id="line-173">        // in the configuration</span>
+<span class="source-line-no">174</span><span id="line-174">        E env = checkAndLoadInstance(implClass, coprocPriority, conf);</span>
+<span class="source-line-no">175</span><span id="line-175">        if (env != null) {</span>
+<span class="source-line-no">176</span><span id="line-176">          this.coprocEnvironments.add(env);</span>
+<span class="source-line-no">177</span><span id="line-177">          LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);</span>
+<span class="source-line-no">178</span><span id="line-178">          if (!hasPriorityOverride) {</span>
+<span class="source-line-no">179</span><span id="line-179">            ++currentSystemPriority;</span>
+<span class="source-line-no">180</span><span id="line-180">          }</span>
+<span class="source-line-no">181</span><span id="line-181">        }</span>
+<span class="source-line-no">182</span><span id="line-182">      } catch (Throwable t) {</span>
+<span class="source-line-no">183</span><span id="line-183">        // We always abort if system coprocessors cannot be loaded</span>
+<span class="source-line-no">184</span><span id="line-184">        abortServer(className, t);</span>
+<span class="source-line-no">185</span><span id="line-185">      }</span>
+<span class="source-line-no">186</span><span id="line-186">    }</span>
+<span class="source-line-no">187</span><span id="line-187">  }</span>
+<span class="source-line-no">188</span><span id="line-188"></span>
+<span class="source-line-no">189</span><span id="line-189">  /**</span>
+<span class="source-line-no">190</span><span id="line-190">   * Load a coprocessor implementation into the host</span>
+<span class="source-line-no">191</span><span id="line-191">   * @param path      path to implementation jar</span>
+<span class="source-line-no">192</span><span id="line-192">   * @param className the main class name</span>
+<span class="source-line-no">193</span><span id="line-193">   * @param priority  chaining priority</span>
+<span class="source-line-no">194</span><span id="line-194">   * @param conf      configuration for coprocessor</span>
+<span class="source-line-no">195</span><span id="line-195">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">196</span><span id="line-196">   */</span>
+<span class="source-line-no">197</span><span id="line-197">  public E load(Path path, String className, int priority, Configuration conf) throws IOException {</span>
+<span class="source-line-no">198</span><span id="line-198">    String[] includedClassPrefixes = null;</span>
+<span class="source-line-no">199</span><span id="line-199">    if (conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY) != null) {</span>
+<span class="source-line-no">200</span><span id="line-200">      String prefixes = conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY);</span>
+<span class="source-line-no">201</span><span id="line-201">      includedClassPrefixes = prefixes.split(";");</span>
+<span class="source-line-no">202</span><span id="line-202">    }</span>
+<span class="source-line-no">203</span><span id="line-203">    return load(path, className, priority, conf, includedClassPrefixes);</span>
+<span class="source-line-no">204</span><span id="line-204">  }</span>
+<span class="source-line-no">205</span><span id="line-205"></span>
+<span class="source-line-no">206</span><span id="line-206">  /**</span>
+<span class="source-line-no">207</span><span id="line-207">   * Load a coprocessor implementation into the host</span>
+<span class="source-line-no">208</span><span id="line-208">   * @param path                  path to implementation jar</span>
+<span class="source-line-no">209</span><span id="line-209">   * @param className             the main class name</span>
+<span class="source-line-no">210</span><span id="line-210">   * @param priority              chaining priority</span>
+<span class="source-line-no">211</span><span id="line-211">   * @param conf                  configuration for coprocessor</span>
+<span class="source-line-no">212</span><span id="line-212">   * @param includedClassPrefixes class name prefixes to include</span>
+<span class="source-line-no">213</span><span id="line-213">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">214</span><span id="line-214">   */</span>
+<span class="source-line-no">215</span><span id="line-215">  public E load(Path path, String className, int priority, Configuration conf,</span>
+<span class="source-line-no">216</span><span id="line-216">    String[] includedClassPrefixes) throws IOException {</span>
+<span class="source-line-no">217</span><span id="line-217">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">218</span><span id="line-218">    LOG.debug("Loading coprocessor class " + className + " with path " + path + " and priority "</span>
+<span class="source-line-no">219</span><span id="line-219">      + priority);</span>
+<span class="source-line-no">220</span><span id="line-220"></span>
+<span class="source-line-no">221</span><span id="line-221">    boolean skipLoadDuplicateCoprocessor = conf.getBoolean(SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR,</span>
+<span class="source-line-no">222</span><span id="line-222">      DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR);</span>
+<span class="source-line-no">223</span><span id="line-223">    if (skipLoadDuplicateCoprocessor &amp;&amp; findCoprocessor(className) != null) {</span>
+<span class="source-line-no">224</span><span id="line-224">      // If already loaded will just continue</span>
+<span class="source-line-no">225</span><span id="line-225">      LOG.warn("Attempted duplicate loading of {}; skipped", className);</span>
+<span class="source-line-no">226</span><span id="line-226">      return null;</span>
+<span class="source-line-no">227</span><span id="line-227">    }</span>
+<span class="source-line-no">228</span><span id="line-228"></span>
+<span class="source-line-no">229</span><span id="line-229">    ClassLoader cl = null;</span>
+<span class="source-line-no">230</span><span id="line-230">    if (path == null) {</span>
+<span class="source-line-no">231</span><span id="line-231">      try {</span>
+<span class="source-line-no">232</span><span id="line-232">        implClass = getClass().getClassLoader().loadClass(className);</span>
+<span class="source-line-no">233</span><span id="line-233">      } catch (ClassNotFoundException e) {</span>
+<span class="source-line-no">234</span><span id="line-234">        throw new IOException("No jar path specified for " + className);</span>
+<span class="source-line-no">235</span><span id="line-235">      }</span>
+<span class="source-line-no">236</span><span id="line-236">    } else {</span>
+<span class="source-line-no">237</span><span id="line-237">      cl =</span>
+<span class="source-line-no">238</span><span id="line-238">        CoprocessorClassLoader.getClassLoader(path, getClass().getClassLoader(), pathPrefix, conf);</span>
+<span class="source-line-no">239</span><span id="line-239">      try {</span>
+<span class="source-line-no">240</span><span id="line-240">        implClass = ((CoprocessorClassLoader) cl).loadClass(className, includedClassPrefixes);</span>
+<span class="source-line-no">241</span><span id="line-241">      } catch (ClassNotFoundException e) {</span>
+<span class="source-line-no">242</span><span id="line-242">        throw new IOException("Cannot load external coprocessor class " + className, e);</span>
+<span class="source-line-no">243</span><span id="line-243">      }</span>
+<span class="source-line-no">244</span><span id="line-244">    }</span>
+<span class="source-line-no">245</span><span id="line-245"></span>
+<span class="source-line-no">246</span><span id="line-246">    // load custom code for coprocessor</span>
+<span class="source-line-no">247</span><span id="line-247">    Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">248</span><span id="line-248">    ClassLoader hostClassLoader = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">249</span><span id="line-249">    try {</span>
+<span class="source-line-no">250</span><span id="line-250">      // switch temporarily to the thread classloader for custom CP</span>
+<span class="source-line-no">251</span><span id="line-251">      currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">252</span><span id="line-252">      E cpInstance = checkAndLoadInstance(implClass, priority, conf);</span>
+<span class="source-line-no">253</span><span id="line-253">      return cpInstance;</span>
+<span class="source-line-no">254</span><span id="line-254">    } finally {</span>
+<span class="source-line-no">255</span><span id="line-255">      // restore the fresh (host) classloader</span>
+<span class="source-line-no">256</span><span id="line-256">      currentThread.setContextClassLoader(hostClassLoader);</span>
+<span class="source-line-no">257</span><span id="line-257">    }</span>
+<span class="source-line-no">258</span><span id="line-258">  }</span>
+<span class="source-line-no">259</span><span id="line-259"></span>
+<span class="source-line-no">260</span><span id="line-260">  public void load(Class&lt;? extends C&gt; implClass, int priority, Configuration conf)</span>
+<span class="source-line-no">261</span><span id="line-261">    throws IOException {</span>
+<span class="source-line-no">262</span><span id="line-262">    E env = checkAndLoadInstance(implClass, priority, conf);</span>
+<span class="source-line-no">263</span><span id="line-263">    coprocEnvironments.add(env);</span>
+<span class="source-line-no">264</span><span id="line-264">  }</span>
+<span class="source-line-no">265</span><span id="line-265"></span>
+<span class="source-line-no">266</span><span id="line-266">  /**</span>
+<span class="source-line-no">267</span><span id="line-267">   * @param implClass Implementation class</span>
+<span class="source-line-no">268</span><span id="line-268">   * @param priority  priority</span>
+<span class="source-line-no">269</span><span id="line-269">   * @param conf      configuration</span>
+<span class="source-line-no">270</span><span id="line-270">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">271</span><span id="line-271">   */</span>
+<span class="source-line-no">272</span><span id="line-272">  public E checkAndLoadInstance(Class&lt;?&gt; implClass, int priority, Configuration conf)</span>
+<span class="source-line-no">273</span><span id="line-273">    throws IOException {</span>
+<span class="source-line-no">274</span><span id="line-274">    // create the instance</span>
+<span class="source-line-no">275</span><span id="line-275">    C impl;</span>
+<span class="source-line-no">276</span><span id="line-276">    try {</span>
+<span class="source-line-no">277</span><span id="line-277">      impl = checkAndGetInstance(implClass);</span>
+<span class="source-line-no">278</span><span id="line-278">      if (impl == null) {</span>
+<span class="source-line-no">279</span><span id="line-279">        LOG.error("Cannot load coprocessor " + implClass.getSimpleName());</span>
+<span class="source-line-no">280</span><span id="line-280">        return null;</span>
+<span class="source-line-no">281</span><span id="line-281">      }</span>
+<span class="source-line-no">282</span><span id="line-282">    } catch (InstantiationException | IllegalAccessException e) {</span>
+<span class="source-line-no">283</span><span id="line-283">      throw new IOException(e);</span>
+<span class="source-line-no">284</span><span id="line-284">    }</span>
+<span class="source-line-no">285</span><span id="line-285">    // create the environment</span>
+<span class="source-line-no">286</span><span id="line-286">    E env = createEnvironment(impl, priority, loadSequence.incrementAndGet(), conf);</span>
+<span class="source-line-no">287</span><span id="line-287">    assert env instanceof BaseEnvironment;</span>
+<span class="source-line-no">288</span><span id="line-288">    ((BaseEnvironment&lt;C&gt;) env).startup();</span>
+<span class="source-line-no">289</span><span id="line-289">    // HBASE-4014: maintain list of loaded coprocessors for later crash analysis</span>
+<span class="source-line-no">290</span><span id="line-290">    // if server (master or regionserver) aborts.</span>
+<span class="source-line-no">291</span><span id="line-291">    coprocessorNames.add(implClass.getName());</span>
+<span class="source-line-no">292</span><span id="line-292">    return env;</span>
+<span class="source-line-no">293</span><span id="line-293">  }</span>
+<span class="source-line-no">294</span><span id="line-294"></span>
+<span class="source-line-no">295</span><span id="line-295">  /**</span>
+<span class="source-line-no">296</span><span id="line-296">   * Called when a new Coprocessor class is loaded</span>
+<span class="source-line-no">297</span><span id="line-297">   */</span>
+<span class="source-line-no">298</span><span id="line-298">  public abstract E createEnvironment(C instance, int priority, int sequence, Configuration conf);</span>
+<span class="source-line-no">299</span><span id="line-299"></span>
+<span class="source-line-no">300</span><span id="line-300">  /**</span>
+<span class="source-line-no">301</span><span id="line-301">   * Called when a new Coprocessor class needs to be loaded. Checks if type of the given class is</span>
+<span class="source-line-no">302</span><span id="line-302">   * what the corresponding host implementation expects. If it is of correct type, returns an</span>
+<span class="source-line-no">303</span><span id="line-303">   * instance of the coprocessor to be loaded. If not, returns null. If an exception occurs when</span>
+<span class="source-line-no">304</span><span id="line-304">   * trying to create instance of a coprocessor, it's passed up and eventually results into server</span>
+<span class="source-line-no">305</span><span id="line-305">   * aborting.</span>
+<span class="source-line-no">306</span><span id="line-306">   */</span>
+<span class="source-line-no">307</span><span id="line-307">  public abstract C checkAndGetInstance(Class&lt;?&gt; implClass)</span>
+<span class="source-line-no">308</span><span id="line-308">    throws InstantiationException, IllegalAccessException;</span>
+<span class="source-line-no">309</span><span id="line-309"></span>
+<span class="source-line-no">310</span><span id="line-310">  public void shutdown(E e) {</span>
+<span class="source-line-no">311</span><span id="line-311">    assert e instanceof BaseEnvironment;</span>
+<span class="source-line-no">312</span><span id="line-312">    if (LOG.isDebugEnabled()) {</span>
+<span class="source-line-no">313</span><span id="line-313">      LOG.debug("Stop coprocessor " + e.getInstance().getClass().getName());</span>
+<span class="source-line-no">314</span><span id="line-314">    }</span>
+<span class="source-line-no">315</span><span id="line-315">    ((BaseEnvironment&lt;C&gt;) e).shutdown();</span>
+<span class="source-line-no">316</span><span id="line-316">  }</span>
+<span class="source-line-no">317</span><span id="line-317"></span>
+<span class="source-line-no">318</span><span id="line-318">  /**</span>
+<span class="source-line-no">319</span><span id="line-319">   * Find coprocessors by full class name or simple name.</span>
+<span class="source-line-no">320</span><span id="line-320">   */</span>
+<span class="source-line-no">321</span><span id="line-321">  public C findCoprocessor(String className) {</span>
+<span class="source-line-no">322</span><span id="line-322">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">323</span><span id="line-323">      if (</span>
+<span class="source-line-no">324</span><span id="line-324">        env.getInstance().getClass().getName().equals(className)</span>
+<span class="source-line-no">325</span><span id="line-325">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
+<span class="source-line-no">326</span><span id="line-326">      ) {</span>
+<span class="source-line-no">327</span><span id="line-327">        return env.getInstance();</span>
+<span class="source-line-no">328</span><span id="line-328">      }</span>
+<span class="source-line-no">329</span><span id="line-329">    }</span>
+<span class="source-line-no">330</span><span id="line-330">    return null;</span>
+<span class="source-line-no">331</span><span id="line-331">  }</span>
+<span class="source-line-no">332</span><span id="line-332"></span>
+<span class="source-line-no">333</span><span id="line-333">  public &lt;T extends C&gt; T findCoprocessor(Class&lt;T&gt; cls) {</span>
+<span class="source-line-no">334</span><span id="line-334">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">335</span><span id="line-335">      if (cls.isAssignableFrom(env.getInstance().getClass())) {</span>
+<span class="source-line-no">336</span><span id="line-336">        return (T) env.getInstance();</span>
+<span class="source-line-no">337</span><span id="line-337">      }</span>
+<span class="source-line-no">338</span><span id="line-338">    }</span>
+<span class="source-line-no">339</span><span id="line-339">    return null;</span>
+<span class="source-line-no">340</span><span id="line-340">  }</span>
+<span class="source-line-no">341</span><span id="line-341"></span>
+<span class="source-line-no">342</span><span id="line-342">  /**</span>
+<span class="source-line-no">343</span><span id="line-343">   * Find list of coprocessors that extend/implement the given class/interface</span>
+<span class="source-line-no">344</span><span id="line-344">   * @param cls the class/interface to look for</span>
+<span class="source-line-no">345</span><span id="line-345">   * @return the list of coprocessors, or null if not found</span>
+<span class="source-line-no">346</span><span id="line-346">   */</span>
+<span class="source-line-no">347</span><span id="line-347">  public &lt;T extends C&gt; List&lt;T&gt; findCoprocessors(Class&lt;T&gt; cls) {</span>
+<span class="source-line-no">348</span><span id="line-348">    ArrayList&lt;T&gt; ret = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">349</span><span id="line-349"></span>
+<span class="source-line-no">350</span><span id="line-350">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">351</span><span id="line-351">      C cp = env.getInstance();</span>
+<span class="source-line-no">352</span><span id="line-352"></span>
+<span class="source-line-no">353</span><span id="line-353">      if (cp != null) {</span>
+<span class="source-line-no">354</span><span id="line-354">        if (cls.isAssignableFrom(cp.getClass())) {</span>
+<span class="source-line-no">355</span><span id="line-355">          ret.add((T) cp);</span>
+<span class="source-line-no">356</span><span id="line-356">        }</span>
+<span class="source-line-no">357</span><span id="line-357">      }</span>
+<span class="source-line-no">358</span><span id="line-358">    }</span>
+<span class="source-line-no">359</span><span id="line-359">    return ret;</span>
+<span class="source-line-no">360</span><span id="line-360">  }</span>
+<span class="source-line-no">361</span><span id="line-361"></span>
+<span class="source-line-no">362</span><span id="line-362">  /**</span>
+<span class="source-line-no">363</span><span id="line-363">   * Find a coprocessor environment by class name</span>
+<span class="source-line-no">364</span><span id="line-364">   * @param className the class name</span>
+<span class="source-line-no">365</span><span id="line-365">   * @return the coprocessor, or null if not found</span>
+<span class="source-line-no">366</span><span id="line-366">   */</span>
+<span class="source-line-no">367</span><span id="line-367">  public E findCoprocessorEnvironment(String className) {</span>
+<span class="source-line-no">368</span><span id="line-368">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">369</span><span id="line-369">      if (</span>
+<span class="source-line-no">370</span><span id="line-370">        env.getInstance().getClass().getName().equals(className)</span>
+<span class="source-line-no">371</span><span id="line-371">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
+<span class="source-line-no">372</span><span id="line-372">      ) {</span>
+<span class="source-line-no">373</span><span id="line-373">        return env;</span>
+<span class="source-line-no">374</span><span id="line-374">      }</span>
+<span class="source-line-no">375</span><span id="line-375">    }</span>
+<span class="source-line-no">376</span><span id="line-376">    return null;</span>
+<span class="source-line-no">377</span><span id="line-377">  }</span>
+<span class="source-line-no">378</span><span id="line-378"></span>
+<span class="source-line-no">379</span><span id="line-379">  /**</span>
+<span class="source-line-no">380</span><span id="line-380">   * Retrieves the set of classloaders used to instantiate Coprocessor classes defined in external</span>
+<span class="source-line-no">381</span><span id="line-381">   * jar files.</span>
+<span class="source-line-no">382</span><span id="line-382">   * @return A set of ClassLoader instances</span>
+<span class="source-line-no">383</span><span id="line-383">   */</span>
+<span class="source-line-no">384</span><span id="line-384">  Set&lt;ClassLoader&gt; getExternalClassLoaders() {</span>
+<span class="source-line-no">385</span><span id="line-385">    Set&lt;ClassLoader&gt; externalClassLoaders = new HashSet&lt;&gt;();</span>
+<span class="source-line-no">386</span><span id="line-386">    final ClassLoader systemClassLoader = this.getClass().getClassLoader();</span>
+<span class="source-line-no">387</span><span id="line-387">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">388</span><span id="line-388">      ClassLoader cl = env.getInstance().getClass().getClassLoader();</span>
+<span class="source-line-no">389</span><span id="line-389">      if (cl != systemClassLoader) {</span>
+<span class="source-line-no">390</span><span id="line-390">        // do not include system classloader</span>
+<span class="source-line-no">391</span><span id="line-391">        externalClassLoaders.add(cl);</span>
+<span class="source-line-no">392</span><span id="line-392">      }</span>
+<span class="source-line-no">393</span><span id="line-393">    }</span>
+<span class="source-line-no">394</span><span id="line-394">    return externalClassLoaders;</span>
+<span class="source-line-no">395</span><span id="line-395">  }</span>
+<span class="source-line-no">396</span><span id="line-396"></span>
+<span class="source-line-no">397</span><span id="line-397">  /**</span>
+<span class="source-line-no">398</span><span id="line-398">   * Environment priority comparator. Coprocessors are chained in sorted order.</span>
+<span class="source-line-no">399</span><span id="line-399">   */</span>
+<span class="source-line-no">400</span><span id="line-400">  static class EnvironmentPriorityComparator implements Comparator&lt;CoprocessorEnvironment&gt; {</span>
+<span class="source-line-no">401</span><span id="line-401">    @Override</span>
+<span class="source-line-no">402</span><span id="line-402">    public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) {</span>
+<span class="source-line-no">403</span><span id="line-403">      if (env1.getPriority() &lt; env2.getPriority()) {</span>
+<span class="source-line-no">404</span><span id="line-404">        return -1;</span>
+<span class="source-line-no">405</span><span id="line-405">      } else if (env1.getPriority() &gt; env2.getPriority()) {</span>
+<span class="source-line-no">406</span><span id="line-406">        return 1;</span>
+<span class="source-line-no">407</span><span id="line-407">      }</span>
+<span class="source-line-no">408</span><span id="line-408">      if (env1.getLoadSequence() &lt; env2.getLoadSequence()) {</span>
+<span class="source-line-no">409</span><span id="line-409">        return -1;</span>
+<span class="source-line-no">410</span><span id="line-410">      } else if (env1.getLoadSequence() &gt; env2.getLoadSequence()) {</span>
+<span class="source-line-no">411</span><span id="line-411">        return 1;</span>
+<span class="source-line-no">412</span><span id="line-412">      }</span>
+<span class="source-line-no">413</span><span id="line-413">      return 0;</span>
+<span class="source-line-no">414</span><span id="line-414">    }</span>
+<span class="source-line-no">415</span><span id="line-415">  }</span>
+<span class="source-line-no">416</span><span id="line-416"></span>
+<span class="source-line-no">417</span><span id="line-417">  protected void abortServer(final E environment, final Throwable e) {</span>
+<span class="source-line-no">418</span><span id="line-418">    abortServer(environment.getInstance().getClass().getName(), e);</span>
+<span class="source-line-no">419</span><span id="line-419">  }</span>
+<span class="source-line-no">420</span><span id="line-420"></span>
+<span class="source-line-no">421</span><span id="line-421">  protected void abortServer(final String coprocessorName, final Throwable e) {</span>
+<span class="source-line-no">422</span><span id="line-422">    String message = "The coprocessor " + coprocessorName + " threw " + e.toString();</span>
+<span class="source-line-no">423</span><span id="line-423">    LOG.error(message, e);</span>
+<span class="source-line-no">424</span><span id="line-424">    if (abortable != null) {</span>
+<span class="source-line-no">425</span><span id="line-425">      abortable.abort(message, e);</span>
+<span class="source-line-no">426</span><span id="line-426">    } else {</span>
+<span class="source-line-no">427</span><span id="line-427">      LOG.warn("No available Abortable, process was not aborted");</span>
+<span class="source-line-no">428</span><span id="line-428">    }</span>
+<span class="source-line-no">429</span><span id="line-429">  }</span>
+<span class="source-line-no">430</span><span id="line-430"></span>
+<span class="source-line-no">431</span><span id="line-431">  /**</span>
+<span class="source-line-no">432</span><span id="line-432">   * This is used by coprocessor hooks which are declared to throw IOException (or its subtypes).</span>
+<span class="source-line-no">433</span><span id="line-433">   * For such hooks, we should handle throwable objects depending on the Throwable's type. Those</span>
+<span class="source-line-no">434</span><span id="line-434">   * which are instances of IOException should be passed on to the client. This is in conformance</span>
+<span class="source-line-no">435</span><span id="line-435">   * with the HBase idiom regarding IOException: that it represents a circumstance that should be</span>
+<span class="source-line-no">436</span><span id="line-436">   * passed along to the client for its own handling. For example, a coprocessor that implements</span>
+<span class="source-line-no">437</span><span id="line-437">   * access controls would throw a subclass of IOException, such as AccessDeniedException, in its</span>
+<span class="source-line-no">438</span><span id="line-438">   * preGet() method to prevent an unauthorized client's performing a Get on a particular table.</span>
+<span class="source-line-no">439</span><span id="line-439">   * @param env Coprocessor Environment</span>
+<span class="source-line-no">440</span><span id="line-440">   * @param e   Throwable object thrown by coprocessor.</span>
+<span class="source-line-no">441</span><span id="line-441">   * @exception IOException Exception</span>
+<span class="source-line-no">442</span><span id="line-442">   */</span>
+<span class="source-line-no">443</span><span id="line-443">  // Note to devs: Class comments of all observers ({@link MasterObserver}, {@link WALObserver},</span>
+<span class="source-line-no">444</span><span id="line-444">  // etc) mention this nuance of our exception handling so that coprocessor can throw appropriate</span>
+<span class="source-line-no">445</span><span id="line-445">  // exceptions depending on situation. If any changes are made to this logic, make sure to</span>
+<span class="source-line-no">446</span><span id="line-446">  // update all classes' comments.</span>
+<span class="source-line-no">447</span><span id="line-447">  protected void handleCoprocessorThrowable(final E env, final Throwable e) throws IOException {</span>
+<span class="source-line-no">448</span><span id="line-448">    if (e instanceof IOException) {</span>
+<span class="source-line-no">449</span><span id="line-449">      throw (IOException) e;</span>
+<span class="source-line-no">450</span><span id="line-450">    }</span>
+<span class="source-line-no">451</span><span id="line-451">    // If we got here, e is not an IOException. A loaded coprocessor has a</span>
+<span class="source-line-no">452</span><span id="line-452">    // fatal bug, and the server (master or regionserver) should remove the</span>
+<span class="source-line-no">453</span><span id="line-453">    // faulty coprocessor from its set of active coprocessors. Setting</span>
+<span class="source-line-no">454</span><span id="line-454">    // 'hbase.coprocessor.abortonerror' to true will cause abortServer(),</span>
+<span class="source-line-no">455</span><span id="line-455">    // which may be useful in development and testing environments where</span>
+<span class="source-line-no">456</span><span id="line-456">    // 'failing fast' for error analysis is desired.</span>
+<span class="source-line-no">457</span><span id="line-457">    if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) {</span>
+<span class="source-line-no">458</span><span id="line-458">      // server is configured to abort.</span>
+<span class="source-line-no">459</span><span id="line-459">      abortServer(env, e);</span>
+<span class="source-line-no">460</span><span id="line-460">    } else {</span>
+<span class="source-line-no">461</span><span id="line-461">      // If available, pull a table name out of the environment</span>
+<span class="source-line-no">462</span><span id="line-462">      if (env instanceof RegionCoprocessorEnvironment) {</span>
+<span class="source-line-no">463</span><span id="line-463">        String tableName =</span>
+<span class="source-line-no">464</span><span id="line-464">          ((RegionCoprocessorEnvironment) env).getRegionInfo().getTable().getNameAsString();</span>
+<span class="source-line-no">465</span><span id="line-465">        LOG.error("Removing coprocessor '" + env.toString() + "' from table '" + tableName + "'",</span>
+<span class="source-line-no">466</span><span id="line-466">          e);</span>
+<span class="source-line-no">467</span><span id="line-467">      } else {</span>
+<span class="source-line-no">468</span><span id="line-468">        LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment", e);</span>
+<span class="source-line-no">469</span><span id="line-469">      }</span>
+<span class="source-line-no">470</span><span id="line-470"></span>
+<span class="source-line-no">471</span><span id="line-471">      coprocEnvironments.remove(env);</span>
+<span class="source-line-no">472</span><span id="line-472">      try {</span>
+<span class="source-line-no">473</span><span id="line-473">        shutdown(env);</span>
+<span class="source-line-no">474</span><span id="line-474">      } catch (Exception x) {</span>
+<span class="source-line-no">475</span><span id="line-475">        LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x);</span>
+<span class="source-line-no">476</span><span id="line-476">      }</span>
+<span class="source-line-no">477</span><span id="line-477">      throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e</span>
+<span class="source-line-no">478</span><span id="line-478">        + "' and has been removed from the active " + "coprocessor set.", e);</span>
+<span class="source-line-no">479</span><span id="line-479">    }</span>
+<span class="source-line-no">480</span><span id="line-480">  }</span>
+<span class="source-line-no">481</span><span id="line-481"></span>
+<span class="source-line-no">482</span><span id="line-482">  /**</span>
+<span class="source-line-no">483</span><span id="line-483">   * Used to limit legacy handling to once per Coprocessor class per classloader.</span>
+<span class="source-line-no">484</span><span id="line-484">   */</span>
+<span class="source-line-no">485</span><span id="line-485">  private static final Set&lt;Class&lt;? extends Coprocessor&gt;&gt; legacyWarning =</span>
+<span class="source-line-no">486</span><span id="line-486">    new ConcurrentSkipListSet&lt;&gt;(new Comparator&lt;Class&lt;? extends Coprocessor&gt;&gt;() {</span>
+<span class="source-line-no">487</span><span id="line-487">      @Override</span>
+<span class="source-line-no">488</span><span id="line-488">      public int compare(Class&lt;? extends Coprocessor&gt; c1, Class&lt;? extends Coprocessor&gt; c2) {</span>
+<span class="source-line-no">489</span><span id="line-489">        if (c1.equals(c2)) {</span>
+<span class="source-line-no">490</span><span id="line-490">          return 0;</span>
+<span class="source-line-no">491</span><span id="line-491">        }</span>
+<span class="source-line-no">492</span><span id="line-492">        return c1.getName().compareTo(c2.getName());</span>
+<span class="source-line-no">493</span><span id="line-493">      }</span>
+<span class="source-line-no">494</span><span id="line-494">    });</span>
+<span class="source-line-no">495</span><span id="line-495"></span>
+<span class="source-line-no">496</span><span id="line-496">  /**</span>
+<span class="source-line-no">497</span><span id="line-497">   * Implementations defined function to get an observer of type {@code O} from a coprocessor of</span>
+<span class="source-line-no">498</span><span id="line-498">   * type {@code C}. Concrete implementations of CoprocessorHost define one getter for each observer</span>
+<span class="source-line-no">499</span><span id="line-499">   * they can handle. For e.g. RegionCoprocessorHost will use 3 getters, one for each of</span>
+<span class="source-line-no">500</span><span id="line-500">   * RegionObserver, EndpointObserver and BulkLoadObserver. These getters are used by</span>
+<span class="source-line-no">501</span><span id="line-501">   * {@code ObserverOperation} to get appropriate observer from the coprocessor.</span>
+<span class="source-line-no">502</span><span id="line-502">   */</span>
+<span class="source-line-no">503</span><span id="line-503">  @FunctionalInterface</span>
+<span class="source-line-no">504</span><span id="line-504">  public interface ObserverGetter&lt;C, O&gt; extends Function&lt;C, Optional&lt;O&gt;&gt; {</span>
+<span class="source-line-no">505</span><span id="line-505">  }</span>
+<span class="source-line-no">506</span><span id="line-506"></span>
+<span class="source-line-no">507</span><span id="line-507">  private abstract class ObserverOperation&lt;O&gt; extends ObserverContextImpl&lt;E&gt; {</span>
+<span class="source-line-no">508</span><span id="line-508">    ObserverGetter&lt;C, O&gt; observerGetter;</span>
+<span class="source-line-no">509</span><span id="line-509"></span>
+<span class="source-line-no">510</span><span id="line-510">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
+<span class="source-line-no">511</span><span id="line-511">      this(observerGetter, null);</span>
+<span class="source-line-no">512</span><span id="line-512">    }</span>
+<span class="source-line-no">513</span><span id="line-513"></span>
+<span class="source-line-no">514</span><span id="line-514">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
+<span class="source-line-no">515</span><span id="line-515">      this(observerGetter, user, false);</span>
+<span class="source-line-no">516</span><span id="line-516">    }</span>
+<span class="source-line-no">517</span><span id="line-517"></span>
+<span class="source-line-no">518</span><span id="line-518">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, boolean bypassable) {</span>
+<span class="source-line-no">519</span><span id="line-519">      this(observerGetter, null, bypassable);</span>
+<span class="source-line-no">520</span><span id="line-520">    }</span>
+<span class="source-line-no">521</span><span id="line-521"></span>
+<span class="source-line-no">522</span><span id="line-522">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user, boolean bypassable) {</span>
+<span class="source-line-no">523</span><span id="line-523">      super(user != null ? user : RpcServer.getRequestUser().orElse(null), bypassable);</span>
+<span class="source-line-no">524</span><span id="line-524">      this.observerGetter = observerGetter;</span>
+<span class="source-line-no">525</span><span id="line-525">    }</span>
 <span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527">    protected void postEnvCall() {</span>
-<span class="source-line-no">528</span><span id="line-528">    }</span>
-<span class="source-line-no">529</span><span id="line-529">  }</span>
-<span class="source-line-no">530</span><span id="line-530"></span>
-<span class="source-line-no">531</span><span id="line-531">  // Can't derive ObserverOperation from ObserverOperationWithResult (R = Void) because then all</span>
-<span class="source-line-no">532</span><span id="line-532">  // ObserverCaller implementations will have to have a return statement.</span>
-<span class="source-line-no">533</span><span id="line-533">  // O = observer, E = environment, C = coprocessor, R=result type</span>
-<span class="source-line-no">534</span><span id="line-534">  public abstract class ObserverOperationWithoutResult&lt;O&gt; extends ObserverOperation&lt;O&gt; {</span>
-<span class="source-line-no">535</span><span id="line-535">    protected abstract void call(O observer) throws IOException;</span>
-<span class="source-line-no">536</span><span id="line-536"></span>
-<span class="source-line-no">537</span><span id="line-537">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
-<span class="source-line-no">538</span><span id="line-538">      super(observerGetter);</span>
-<span class="source-line-no">539</span><span id="line-539">    }</span>
-<span class="source-line-no">540</span><span id="line-540"></span>
-<span class="source-line-no">541</span><span id="line-541">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
-<span class="source-line-no">542</span><span id="line-542">      super(observerGetter, user);</span>
-<span class="source-line-no">543</span><span id="line-543">    }</span>
-<span class="source-line-no">544</span><span id="line-544"></span>
-<span class="source-line-no">545</span><span id="line-545">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user,</span>
-<span class="source-line-no">546</span><span id="line-546">      boolean bypassable) {</span>
-<span class="source-line-no">547</span><span id="line-547">      super(observerGetter, user, bypassable);</span>
-<span class="source-line-no">548</span><span id="line-548">    }</span>
-<span class="source-line-no">549</span><span id="line-549"></span>
-<span class="source-line-no">550</span><span id="line-550">    /**</span>
-<span class="source-line-no">551</span><span id="line-551">     * In case of coprocessors which have many kinds of observers (for eg, {@link RegionCoprocessor}</span>
-<span class="source-line-no">552</span><span id="line-552">     * has BulkLoadObserver, RegionObserver, etc), some implementations may not need all observers,</span>
-<span class="source-line-no">553</span><span id="line-553">     * in which case they will return null for that observer's getter. We simply ignore such cases.</span>
-<span class="source-line-no">554</span><span id="line-554">     */</span>
-<span class="source-line-no">555</span><span id="line-555">    @Override</span>
-<span class="source-line-no">556</span><span id="line-556">    void callObserver() throws IOException {</span>
-<span class="source-line-no">557</span><span id="line-557">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
-<span class="source-line-no">558</span><span id="line-558">      if (observer.isPresent()) {</span>
-<span class="source-line-no">559</span><span id="line-559">        call(observer.get());</span>
-<span class="source-line-no">560</span><span id="line-560">      }</span>
-<span class="source-line-no">561</span><span id="line-561">    }</span>
-<span class="source-line-no">562</span><span id="line-562">  }</span>
-<span class="source-line-no">563</span><span id="line-563"></span>
-<span class="source-line-no">564</span><span id="line-564">  public abstract class ObserverOperationWithResult&lt;O, R&gt; extends ObserverOperation&lt;O&gt; {</span>
-<span class="source-line-no">565</span><span id="line-565">    protected abstract R call(O observer) throws IOException;</span>
-<span class="source-line-no">566</span><span id="line-566"></span>
-<span class="source-line-no">567</span><span id="line-567">    private R result;</span>
+<span class="source-line-no">527</span><span id="line-527">    abstract void callObserver() throws IOException;</span>
+<span class="source-line-no">528</span><span id="line-528"></span>
+<span class="source-line-no">529</span><span id="line-529">    protected void postEnvCall() {</span>
+<span class="source-line-no">530</span><span id="line-530">    }</span>
+<span class="source-line-no">531</span><span id="line-531">  }</span>
+<span class="source-line-no">532</span><span id="line-532"></span>
+<span class="source-line-no">533</span><span id="line-533">  // Can't derive ObserverOperation from ObserverOperationWithResult (R = Void) because then all</span>
+<span class="source-line-no">534</span><span id="line-534">  // ObserverCaller implementations will have to have a return statement.</span>
+<span class="source-line-no">535</span><span id="line-535">  // O = observer, E = environment, C = coprocessor, R=result type</span>
+<span class="source-line-no">536</span><span id="line-536">  public abstract class ObserverOperationWithoutResult&lt;O&gt; extends ObserverOperation&lt;O&gt; {</span>
+<span class="source-line-no">537</span><span id="line-537">    protected abstract void call(O observer) throws IOException;</span>
+<span class="source-line-no">538</span><span id="line-538"></span>
+<span class="source-line-no">539</span><span id="line-539">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
+<span class="source-line-no">540</span><span id="line-540">      super(observerGetter);</span>
+<span class="source-line-no">541</span><span id="line-541">    }</span>
+<span class="source-line-no">542</span><span id="line-542"></span>
+<span class="source-line-no">543</span><span id="line-543">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
+<span class="source-line-no">544</span><span id="line-544">      super(observerGetter, user);</span>
+<span class="source-line-no">545</span><span id="line-545">    }</span>
+<span class="source-line-no">546</span><span id="line-546"></span>
+<span class="source-line-no">547</span><span id="line-547">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user,</span>
+<span class="source-line-no">548</span><span id="line-548">      boolean bypassable) {</span>
+<span class="source-line-no">549</span><span id="line-549">      super(observerGetter, user, bypassable);</span>
+<span class="source-line-no">550</span><span id="line-550">    }</span>
+<span class="source-line-no">551</span><span id="line-551"></span>
+<span class="source-line-no">552</span><span id="line-552">    /**</span>
+<span class="source-line-no">553</span><span id="line-553">     * In case of coprocessors which have many kinds of observers (for eg, {@link RegionCoprocessor}</span>
+<span class="source-line-no">554</span><span id="line-554">     * has BulkLoadObserver, RegionObserver, etc), some implementations may not need all observers,</span>
+<span class="source-line-no">555</span><span id="line-555">     * in which case they will return null for that observer's getter. We simply ignore such cases.</span>
+<span class="source-line-no">556</span><span id="line-556">     */</span>
+<span class="source-line-no">557</span><span id="line-557">    @Override</span>
+<span class="source-line-no">558</span><span id="line-558">    void callObserver() throws IOException {</span>
+<span class="source-line-no">559</span><span id="line-559">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
+<span class="source-line-no">560</span><span id="line-560">      if (observer.isPresent()) {</span>
+<span class="source-line-no">561</span><span id="line-561">        call(observer.get());</span>
+<span class="source-line-no">562</span><span id="line-562">      }</span>
+<span class="source-line-no">563</span><span id="line-563">    }</span>
+<span class="source-line-no">564</span><span id="line-564">  }</span>
+<span class="source-line-no">565</span><span id="line-565"></span>
+<span class="source-line-no">566</span><span id="line-566">  public abstract class ObserverOperationWithResult&lt;O, R&gt; extends ObserverOperation&lt;O&gt; {</span>
+<span class="source-line-no">567</span><span id="line-567">    protected abstract R call(O observer) throws IOException;</span>
 <span class="source-line-no">568</span><span id="line-568"></span>
-<span class="source-line-no">569</span><span id="line-569">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result) {</span>
-<span class="source-line-no">570</span><span id="line-570">      this(observerGetter, result, false);</span>
-<span class="source-line-no">571</span><span id="line-571">    }</span>
-<span class="source-line-no">572</span><span id="line-572"></span>
-<span class="source-line-no">573</span><span id="line-573">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result,</span>
-<span class="source-line-no">574</span><span id="line-574">      boolean bypassable) {</span>
-<span class="source-line-no">575</span><span id="line-575">      this(observerGetter, result, null, bypassable);</span>
-<span class="source-line-no">576</span><span id="line-576">    }</span>
-<span class="source-line-no">577</span><span id="line-577"></span>
-<span class="source-line-no">578</span><span id="line-578">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user) {</span>
-<span class="source-line-no">579</span><span id="line-579">      this(observerGetter, result, user, false);</span>
-<span class="source-line-no">580</span><span id="line-580">    }</span>
-<span class="source-line-no">581</span><span id="line-581"></span>
-<span class="source-line-no">582</span><span id="line-582">    private ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user,</span>
-<span class="source-line-no">583</span><span id="line-583">      boolean bypassable) {</span>
-<span class="source-line-no">584</span><span id="line-584">      super(observerGetter, user, bypassable);</span>
-<span class="source-line-no">585</span><span id="line-585">      this.result = result;</span>
-<span class="source-line-no">586</span><span id="line-586">    }</span>
-<span class="source-line-no">587</span><span id="line-587"></span>
-<span class="source-line-no">588</span><span id="line-588">    protected R getResult() {</span>
-<span class="source-line-no">589</span><span id="line-589">      return this.result;</span>
-<span class="source-line-no">590</span><span id="line-590">    }</span>
-<span class="source-line-no">591</span><span id="line-591"></span>
-<span class="source-line-no">592</span><span id="line-592">    @Override</span>
-<span class="source-line-no">593</span><span id="line-593">    void callObserver() throws IOException {</span>
-<span class="source-line-no">594</span><span id="line-594">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
-<span class="source-line-no">595</span><span id="line-595">      if (observer.isPresent()) {</span>
-<span class="source-line-no">596</span><span id="line-596">        result = call(observer.get());</span>
-<span class="source-line-no">597</span><span id="line-597">      }</span>
-<span class="source-line-no">598</span><span id="line-598">    }</span>
-<span class="source-line-no">599</span><span id="line-599">  }</span>
-<span class="source-line-no">600</span><span id="line-600"></span>
-<span class="source-line-no">601</span><span id="line-601">  //////////////////////////////////////////////////////////////////////////////////////////</span>
-<span class="source-line-no">602</span><span id="line-602">  // Functions to execute observer hooks and handle results (if any)</span>
+<span class="source-line-no">569</span><span id="line-569">    private R result;</span>
+<span class="source-line-no">570</span><span id="line-570"></span>
+<span class="source-line-no">571</span><span id="line-571">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result) {</span>
+<span class="source-line-no">572</span><span id="line-572">      this(observerGetter, result, false);</span>
+<span class="source-line-no">573</span><span id="line-573">    }</span>
+<span class="source-line-no">574</span><span id="line-574"></span>
+<span class="source-line-no">575</span><span id="line-575">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result,</span>
+<span class="source-line-no">576</span><span id="line-576">      boolean bypassable) {</span>
+<span class="source-line-no">577</span><span id="line-577">      this(observerGetter, result, null, bypassable);</span>
+<span class="source-line-no">578</span><span id="line-578">    }</span>
+<span class="source-line-no">579</span><span id="line-579"></span>
+<span class="source-line-no">580</span><span id="line-580">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user) {</span>
+<span class="source-line-no">581</span><span id="line-581">      this(observerGetter, result, user, false);</span>
+<span class="source-line-no">582</span><span id="line-582">    }</span>
+<span class="source-line-no">583</span><span id="line-583"></span>
+<span class="source-line-no">584</span><span id="line-584">    private ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user,</span>
+<span class="source-line-no">585</span><span id="line-585">      boolean bypassable) {</span>
+<span class="source-line-no">586</span><span id="line-586">      super(observerGetter, user, bypassable);</span>
+<span class="source-line-no">587</span><span id="line-587">      this.result = result;</span>
+<span class="source-line-no">588</span><span id="line-588">    }</span>
+<span class="source-line-no">589</span><span id="line-589"></span>
+<span class="source-line-no">590</span><span id="line-590">    protected R getResult() {</span>
+<span class="source-line-no">591</span><span id="line-591">      return this.result;</span>
+<span class="source-line-no">592</span><span id="line-592">    }</span>
+<span class="source-line-no">593</span><span id="line-593"></span>
+<span class="source-line-no">594</span><span id="line-594">    @Override</span>
+<span class="source-line-no">595</span><span id="line-595">    void callObserver() throws IOException {</span>
+<span class="source-line-no">596</span><span id="line-596">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
+<span class="source-line-no">597</span><span id="line-597">      if (observer.isPresent()) {</span>
+<span class="source-line-no">598</span><span id="line-598">        result = call(observer.get());</span>
+<span class="source-line-no">599</span><span id="line-599">      }</span>
+<span class="source-line-no">600</span><span id="line-600">    }</span>
+<span class="source-line-no">601</span><span id="line-601">  }</span>
+<span class="source-line-no">602</span><span id="line-602"></span>
 <span class="source-line-no">603</span><span id="line-603">  //////////////////////////////////////////////////////////////////////////////////////////</span>
-<span class="source-line-no">604</span><span id="line-604"></span>
-<span class="source-line-no">605</span><span id="line-605">  /**</span>
-<span class="source-line-no">606</span><span id="line-606">   * Do not call with an observerOperation that is null! Have the caller check.</span>
-<span class="source-line-no">607</span><span id="line-607">   */</span>
-<span class="source-line-no">608</span><span id="line-608">  protected &lt;O, R&gt; R execOperationWithResult(</span>
-<span class="source-line-no">609</span><span id="line-609">    final ObserverOperationWithResult&lt;O, R&gt; observerOperation) throws IOException {</span>
-<span class="source-line-no">610</span><span id="line-610">    boolean bypass = execOperation(observerOperation);</span>
-<span class="source-line-no">611</span><span id="line-611">    R result = observerOperation.getResult();</span>
-<span class="source-line-no">612</span><span id="line-612">    return bypass == observerOperation.isBypassable() ? result : null;</span>
-<span class="source-line-no">613</span><span id="line-613">  }</span>
-<span class="source-line-no">614</span><span id="line-614"></span>
-<span class="source-line-no">615</span><span id="line-615">  /**</span>
-<span class="source-line-no">616</span><span id="line-616">   * @return True if we are to bypass (Can only be &lt;code&gt;true&lt;/code&gt; if</span>
-<span class="source-line-no">617</span><span id="line-617">   *         ObserverOperation#isBypassable().</span>
-<span class="source-line-no">618</span><span id="line-618">   */</span>
-<span class="source-line-no">619</span><span id="line-619">  protected &lt;O&gt; boolean execOperation(final ObserverOperation&lt;O&gt; observerOperation)</span>
-<span class="source-line-no">620</span><span id="line-620">    throws IOException {</span>
-<span class="source-line-no">621</span><span id="line-621">    boolean bypass = false;</span>
-<span class="source-line-no">622</span><span id="line-622">    if (observerOperation == null) {</span>
-<span class="source-line-no">623</span><span id="line-623">      return bypass;</span>
-<span class="source-line-no">624</span><span id="line-624">    }</span>
-<span class="source-line-no">625</span><span id="line-625">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
-<span class="source-line-no">626</span><span id="line-626">    for (E env : envs) {</span>
-<span class="source-line-no">627</span><span id="line-627">      observerOperation.prepare(env);</span>
-<span class="source-line-no">628</span><span id="line-628">      Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">629</span><span id="line-629">      ClassLoader cl = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">630</span><span id="line-630">      try {</span>
-<span class="source-line-no">631</span><span id="line-631">        currentThread.setContextClassLoader(env.getClassLoader());</span>
-<span class="source-line-no">632</span><span id="line-632">        observerOperation.callObserver();</span>
-<span class="source-line-no">633</span><span id="line-633">      } catch (Throwable e) {</span>
-<span class="source-line-no">634</span><span id="line-634">        handleCoprocessorThrowable(env, e);</span>
-<span class="source-line-no">635</span><span id="line-635">      } finally {</span>
-<span class="source-line-no">636</span><span id="line-636">        currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">637</span><span id="line-637">      }</span>
-<span class="source-line-no">638</span><span id="line-638">      // Internal to shouldBypass, it checks if obeserverOperation#isBypassable().</span>
-<span class="source-line-no">639</span><span id="line-639">      bypass |= observerOperation.shouldBypass();</span>
-<span class="source-line-no">640</span><span id="line-640">      observerOperation.postEnvCall();</span>
-<span class="source-line-no">641</span><span id="line-641">      if (bypass) {</span>
-<span class="source-line-no">642</span><span id="line-642">        // If CP says bypass, skip out w/o calling any following CPs; they might ruin our response.</span>
-<span class="source-line-no">643</span><span id="line-643">        // In hbase1, this used to be called 'complete'. In hbase2, we unite bypass and 'complete'.</span>
-<span class="source-line-no">644</span><span id="line-644">        break;</span>
-<span class="source-line-no">645</span><span id="line-645">      }</span>
-<span class="source-line-no">646</span><span id="line-646">    }</span>
-<span class="source-line-no">647</span><span id="line-647">    return bypass;</span>
-<span class="source-line-no">648</span><span id="line-648">  }</span>
-<span class="source-line-no">649</span><span id="line-649"></span>
-<span class="source-line-no">650</span><span id="line-650">  /**</span>
-<span class="source-line-no">651</span><span id="line-651">   * Coprocessor classes can be configured in any order, based on that priority is set and chained</span>
-<span class="source-line-no">652</span><span id="line-652">   * in a sorted order. Should be used preStop*() hooks i.e. when master/regionserver is going down.</span>
-<span class="source-line-no">653</span><span id="line-653">   * This function first calls coprocessor methods (using ObserverOperation.call()) and then</span>
-<span class="source-line-no">654</span><span id="line-654">   * shutdowns the environment in postEnvCall(). &lt;br&gt;</span>
-<span class="source-line-no">655</span><span id="line-655">   * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors</span>
-<span class="source-line-no">656</span><span id="line-656">   * may remain shutdown if any exception occurs during next coprocessor execution which prevent</span>
-<span class="source-line-no">657</span><span id="line-657">   * master/regionserver stop or cluster shutdown. (Refer:</span>
-<span class="source-line-no">658</span><span id="line-658">   * &lt;a href="https://issues.apache.org/jira/browse/HBASE-16663"&gt;HBASE-16663&lt;/a&gt;</span>
-<span class="source-line-no">659</span><span id="line-659">   * @return true if bypaas coprocessor execution, false if not.</span>
-<span class="source-line-no">660</span><span id="line-660">   */</span>
-<span class="source-line-no">661</span><span id="line-661">  protected &lt;O&gt; boolean execShutdown(final ObserverOperation&lt;O&gt; observerOperation)</span>
-<span class="source-line-no">662</span><span id="line-662">    throws IOException {</span>
-<span class="source-line-no">663</span><span id="line-663">    if (observerOperation == null) return false;</span>
-<span class="source-line-no">664</span><span id="line-664">    boolean bypass = false;</span>
-<span class="source-line-no">665</span><span id="line-665">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
-<span class="source-line-no">666</span><span id="line-666">    // Iterate the coprocessors and execute ObserverOperation's call()</span>
-<span class="source-line-no">667</span><span id="line-667">    for (E env : envs) {</span>
-<span class="source-line-no">668</span><span id="line-668">      observerOperation.prepare(env);</span>
-<span class="source-line-no">669</span><span id="line-669">      Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">670</span><span id="line-670">      ClassLoader cl = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">671</span><span id="line-671">      try {</span>
-<span class="source-line-no">672</span><span id="line-672">        currentThread.setContextClassLoader(env.getClassLoader());</span>
-<span class="source-line-no">673</span><span id="line-673">        observerOperation.callObserver();</span>
-<span class="source-line-no">674</span><span id="line-674">      } catch (Throwable e) {</span>
-<span class="source-line-no">675</span><span id="line-675">        handleCoprocessorThrowable(env, e);</span>
-<span class="source-line-no">676</span><span id="line-676">      } finally {</span>
-<span class="source-line-no">677</span><span id="line-677">        currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">678</span><span id="line-678">      }</span>
-<span class="source-line-no">679</span><span id="line-679">      bypass |= observerOperation.shouldBypass();</span>
-<span class="source-line-no">680</span><span id="line-680">    }</span>
-<span class="source-line-no">681</span><span id="line-681"></span>
-<span class="source-line-no">682</span><span id="line-682">    // Iterate the coprocessors and execute ObserverOperation's postEnvCall()</span>
-<span class="source-line-no">683</span><span id="line-683">    for (E env : envs) {</span>
-<span class="source-line-no">684</span><span id="line-684">      observerOperation.prepare(env);</span>
-<span class="source-line-no">685</span><span id="line-685">      observerOperation.postEnvCall();</span>
-<span class="source-line-no">686</span><span id="line-686">    }</span>
-<span class="source-line-no">687</span><span id="line-687">    return bypass;</span>
-<span class="source-line-no">688</span><span id="line-688">  }</span>
-<span class="source-line-no">689</span><span id="line-689">}</span>
+<span class="source-line-no">604</span><span id="line-604">  // Functions to execute observer hooks and handle results (if any)</span>
+<span class="source-line-no">605</span><span id="line-605">  //////////////////////////////////////////////////////////////////////////////////////////</span>
+<span class="source-line-no">606</span><span id="line-606"></span>
+<span class="source-line-no">607</span><span id="line-607">  /**</span>
+<span class="source-line-no">608</span><span id="line-608">   * Do not call with an observerOperation that is null! Have the caller check.</span>
+<span class="source-line-no">609</span><span id="line-609">   */</span>
+<span class="source-line-no">610</span><span id="line-610">  protected &lt;O, R&gt; R execOperationWithResult(</span>
+<span class="source-line-no">611</span><span id="line-611">    final ObserverOperationWithResult&lt;O, R&gt; observerOperation) throws IOException {</span>
+<span class="source-line-no">612</span><span id="line-612">    boolean bypass = execOperation(observerOperation);</span>
+<span class="source-line-no">613</span><span id="line-613">    R result = observerOperation.getResult();</span>
+<span class="source-line-no">614</span><span id="line-614">    return bypass == observerOperation.isBypassable() ? result : null;</span>
+<span class="source-line-no">615</span><span id="line-615">  }</span>
+<span class="source-line-no">616</span><span id="line-616"></span>
+<span class="source-line-no">617</span><span id="line-617">  /**</span>
+<span class="source-line-no">618</span><span id="line-618">   * @return True if we are to bypass (Can only be &lt;code&gt;true&lt;/code&gt; if</span>
+<span class="source-line-no">619</span><span id="line-619">   *         ObserverOperation#isBypassable().</span>
+<span class="source-line-no">620</span><span id="line-620">   */</span>
+<span class="source-line-no">621</span><span id="line-621">  protected &lt;O&gt; boolean execOperation(final ObserverOperation&lt;O&gt; observerOperation)</span>
+<span class="source-line-no">622</span><span id="line-622">    throws IOException {</span>
+<span class="source-line-no">623</span><span id="line-623">    boolean bypass = false;</span>
+<span class="source-line-no">624</span><span id="line-624">    if (observerOperation == null) {</span>
+<span class="source-line-no">625</span><span id="line-625">      return bypass;</span>
+<span class="source-line-no">626</span><span id="line-626">    }</span>
+<span class="source-line-no">627</span><span id="line-627">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
+<span class="source-line-no">628</span><span id="line-628">    for (E env : envs) {</span>
+<span class="source-line-no">629</span><span id="line-629">      observerOperation.prepare(env);</span>
+<span class="source-line-no">630</span><span id="line-630">      Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">631</span><span id="line-631">      ClassLoader cl = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">632</span><span id="line-632">      try {</span>
+<span class="source-line-no">633</span><span id="line-633">        currentThread.setContextClassLoader(env.getClassLoader());</span>
+<span class="source-line-no">634</span><span id="line-634">        observerOperation.callObserver();</span>
+<span class="source-line-no">635</span><span id="line-635">      } catch (Throwable e) {</span>
+<span class="source-line-no">636</span><span id="line-636">        handleCoprocessorThrowable(env, e);</span>
+<span class="source-line-no">637</span><span id="line-637">      } finally {</span>
+<span class="source-line-no">638</span><span id="line-638">        currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">639</span><span id="line-639">      }</span>
+<span class="source-line-no">640</span><span id="line-640">      // Internal to shouldBypass, it checks if obeserverOperation#isBypassable().</span>
+<span class="source-line-no">641</span><span id="line-641">      bypass |= observerOperation.shouldBypass();</span>
+<span class="source-line-no">642</span><span id="line-642">      observerOperation.postEnvCall();</span>
+<span class="source-line-no">643</span><span id="line-643">      if (bypass) {</span>
+<span class="source-line-no">644</span><span id="line-644">        // If CP says bypass, skip out w/o calling any following CPs; they might ruin our response.</span>
+<span class="source-line-no">645</span><span id="line-645">        // In hbase1, this used to be called 'complete'. In hbase2, we unite bypass and 'complete'.</span>
+<span class="source-line-no">646</span><span id="line-646">        break;</span>
+<span class="source-line-no">647</span><span id="line-647">      }</span>
+<span class="source-line-no">648</span><span id="line-648">    }</span>
+<span class="source-line-no">649</span><span id="line-649">    return bypass;</span>
+<span class="source-line-no">650</span><span id="line-650">  }</span>
+<span class="source-line-no">651</span><span id="line-651"></span>
+<span class="source-line-no">652</span><span id="line-652">  /**</span>
+<span class="source-line-no">653</span><span id="line-653">   * Coprocessor classes can be configured in any order, based on that priority is set and chained</span>
+<span class="source-line-no">654</span><span id="line-654">   * in a sorted order. Should be used preStop*() hooks i.e. when master/regionserver is going down.</span>
+<span class="source-line-no">655</span><span id="line-655">   * This function first calls coprocessor methods (using ObserverOperation.call()) and then</span>
+<span class="source-line-no">656</span><span id="line-656">   * shutdowns the environment in postEnvCall(). &lt;br&gt;</span>
+<span class="source-line-no">657</span><span id="line-657">   * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors</span>
+<span class="source-line-no">658</span><span id="line-658">   * may remain shutdown if any exception occurs during next coprocessor execution which prevent</span>
+<span class="source-line-no">659</span><span id="line-659">   * master/regionserver stop or cluster shutdown. (Refer:</span>
+<span class="source-line-no">660</span><span id="line-660">   * &lt;a href="https://issues.apache.org/jira/browse/HBASE-16663"&gt;HBASE-16663&lt;/a&gt;</span>
+<span class="source-line-no">661</span><span id="line-661">   * @return true if bypaas coprocessor execution, false if not.</span>
+<span class="source-line-no">662</span><span id="line-662">   */</span>
+<span class="source-line-no">663</span><span id="line-663">  protected &lt;O&gt; boolean execShutdown(final ObserverOperation&lt;O&gt; observerOperation)</span>
+<span class="source-line-no">664</span><span id="line-664">    throws IOException {</span>
+<span class="source-line-no">665</span><span id="line-665">    if (observerOperation == null) return false;</span>
+<span class="source-line-no">666</span><span id="line-666">    boolean bypass = false;</span>
+<span class="source-line-no">667</span><span id="line-667">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
+<span class="source-line-no">668</span><span id="line-668">    // Iterate the coprocessors and execute ObserverOperation's call()</span>
+<span class="source-line-no">669</span><span id="line-669">    for (E env : envs) {</span>
+<span class="source-line-no">670</span><span id="line-670">      observerOperation.prepare(env);</span>
+<span class="source-line-no">671</span><span id="line-671">      Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">672</span><span id="line-672">      ClassLoader cl = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">673</span><span id="line-673">      try {</span>
+<span class="source-line-no">674</span><span id="line-674">        currentThread.setContextClassLoader(env.getClassLoader());</span>
+<span class="source-line-no">675</span><span id="line-675">        observerOperation.callObserver();</span>
+<span class="source-line-no">676</span><span id="line-676">      } catch (Throwable e) {</span>
+<span class="source-line-no">677</span><span id="line-677">        handleCoprocessorThrowable(env, e);</span>
+<span class="source-line-no">678</span><span id="line-678">      } finally {</span>
+<span class="source-line-no">679</span><span id="line-679">        currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">680</span><span id="line-680">      }</span>
+<span class="source-line-no">681</span><span id="line-681">      bypass |= observerOperation.shouldBypass();</span>
+<span class="source-line-no">682</span><span id="line-682">    }</span>
+<span class="source-line-no">683</span><span id="line-683"></span>
+<span class="source-line-no">684</span><span id="line-684">    // Iterate the coprocessors and execute ObserverOperation's postEnvCall()</span>
+<span class="source-line-no">685</span><span id="line-685">    for (E env : envs) {</span>
+<span class="source-line-no">686</span><span id="line-686">      observerOperation.prepare(env);</span>
+<span class="source-line-no">687</span><span id="line-687">      observerOperation.postEnvCall();</span>
+<span class="source-line-no">688</span><span id="line-688">    }</span>
+<span class="source-line-no">689</span><span id="line-689">    return bypass;</span>
+<span class="source-line-no">690</span><span id="line-690">  }</span>
+<span class="source-line-no">691</span><span id="line-691">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverOperationWithoutResult.html b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverOperationWithoutResult.html
index a9b533f8652..395542b4b25 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverOperationWithoutResult.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.ObserverOperationWithoutResult.html
@@ -74,632 +74,634 @@
 <span class="source-line-no">061</span><span id="line-61">  public static final String USER_REGION_COPROCESSOR_CONF_KEY =</span>
 <span class="source-line-no">062</span><span id="line-62">    "hbase.coprocessor.user.region.classes";</span>
 <span class="source-line-no">063</span><span id="line-63">  public static final String MASTER_COPROCESSOR_CONF_KEY = "hbase.coprocessor.master.classes";</span>
-<span class="source-line-no">064</span><span id="line-64">  public static final String WAL_COPROCESSOR_CONF_KEY = "hbase.coprocessor.wal.classes";</span>
-<span class="source-line-no">065</span><span id="line-65">  public static final String RPC_COPROCESSOR_CONF_KEY = "hbase.coprocessor.rpc.classes";</span>
-<span class="source-line-no">066</span><span id="line-66">  public static final String ABORT_ON_ERROR_KEY = "hbase.coprocessor.abortonerror";</span>
-<span class="source-line-no">067</span><span id="line-67">  public static final boolean DEFAULT_ABORT_ON_ERROR = true;</span>
-<span class="source-line-no">068</span><span id="line-68">  public static final String COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.enabled";</span>
-<span class="source-line-no">069</span><span id="line-69">  public static final boolean DEFAULT_COPROCESSORS_ENABLED = true;</span>
-<span class="source-line-no">070</span><span id="line-70">  public static final String USER_COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.user.enabled";</span>
-<span class="source-line-no">071</span><span id="line-71">  public static final boolean DEFAULT_USER_COPROCESSORS_ENABLED = true;</span>
-<span class="source-line-no">072</span><span id="line-72">  public static final String SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR =</span>
-<span class="source-line-no">073</span><span id="line-73">    "hbase.skip.load.duplicate.table.coprocessor";</span>
-<span class="source-line-no">074</span><span id="line-74">  public static final boolean DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR = false;</span>
-<span class="source-line-no">075</span><span id="line-75"></span>
-<span class="source-line-no">076</span><span id="line-76">  private static final Logger LOG = LoggerFactory.getLogger(CoprocessorHost.class);</span>
-<span class="source-line-no">077</span><span id="line-77">  protected Abortable abortable;</span>
-<span class="source-line-no">078</span><span id="line-78">  /** Ordered set of loaded coprocessors with lock */</span>
-<span class="source-line-no">079</span><span id="line-79">  protected final SortedList&lt;E&gt; coprocEnvironments =</span>
-<span class="source-line-no">080</span><span id="line-80">    new SortedList&lt;&gt;(new EnvironmentPriorityComparator());</span>
-<span class="source-line-no">081</span><span id="line-81">  protected Configuration conf;</span>
-<span class="source-line-no">082</span><span id="line-82">  // unique file prefix to use for local copies of jars when classloading</span>
-<span class="source-line-no">083</span><span id="line-83">  protected String pathPrefix;</span>
-<span class="source-line-no">084</span><span id="line-84">  protected AtomicInteger loadSequence = new AtomicInteger();</span>
-<span class="source-line-no">085</span><span id="line-85"></span>
-<span class="source-line-no">086</span><span id="line-86">  public CoprocessorHost(Abortable abortable) {</span>
-<span class="source-line-no">087</span><span id="line-87">    this.abortable = abortable;</span>
-<span class="source-line-no">088</span><span id="line-88">    this.pathPrefix = UUID.randomUUID().toString();</span>
-<span class="source-line-no">089</span><span id="line-89">  }</span>
-<span class="source-line-no">090</span><span id="line-90"></span>
-<span class="source-line-no">091</span><span id="line-91">  /**</span>
-<span class="source-line-no">092</span><span id="line-92">   * Not to be confused with the per-object _coprocessors_ (above), coprocessorNames is static and</span>
-<span class="source-line-no">093</span><span id="line-93">   * stores the set of all coprocessors ever loaded by any thread in this JVM. It is strictly</span>
-<span class="source-line-no">094</span><span id="line-94">   * additive: coprocessors are added to coprocessorNames, by checkAndLoadInstance() but are never</span>
-<span class="source-line-no">095</span><span id="line-95">   * removed, since the intention is to preserve a history of all loaded coprocessors for diagnosis</span>
-<span class="source-line-no">096</span><span id="line-96">   * in case of server crash (HBASE-4014).</span>
-<span class="source-line-no">097</span><span id="line-97">   */</span>
-<span class="source-line-no">098</span><span id="line-98">  private static Set&lt;String&gt; coprocessorNames = Collections.synchronizedSet(new HashSet&lt;String&gt;());</span>
-<span class="source-line-no">099</span><span id="line-99"></span>
-<span class="source-line-no">100</span><span id="line-100">  public static Set&lt;String&gt; getLoadedCoprocessors() {</span>
-<span class="source-line-no">101</span><span id="line-101">    synchronized (coprocessorNames) {</span>
-<span class="source-line-no">102</span><span id="line-102">      return new HashSet(coprocessorNames);</span>
-<span class="source-line-no">103</span><span id="line-103">    }</span>
-<span class="source-line-no">104</span><span id="line-104">  }</span>
-<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106">  /**</span>
-<span class="source-line-no">107</span><span id="line-107">   * Used to create a parameter to the HServerLoad constructor so that HServerLoad can provide</span>
-<span class="source-line-no">108</span><span id="line-108">   * information about the coprocessors loaded by this regionserver. (HBASE-4070: Improve region</span>
-<span class="source-line-no">109</span><span id="line-109">   * server metrics to report loaded coprocessors to master).</span>
-<span class="source-line-no">110</span><span id="line-110">   */</span>
-<span class="source-line-no">111</span><span id="line-111">  public Set&lt;String&gt; getCoprocessors() {</span>
-<span class="source-line-no">112</span><span id="line-112">    Set&lt;String&gt; returnValue = new TreeSet&lt;&gt;();</span>
-<span class="source-line-no">113</span><span id="line-113">    for (E e : coprocEnvironments) {</span>
-<span class="source-line-no">114</span><span id="line-114">      returnValue.add(e.getInstance().getClass().getSimpleName());</span>
-<span class="source-line-no">115</span><span id="line-115">    }</span>
-<span class="source-line-no">116</span><span id="line-116">    return returnValue;</span>
-<span class="source-line-no">117</span><span id="line-117">  }</span>
-<span class="source-line-no">118</span><span id="line-118"></span>
-<span class="source-line-no">119</span><span id="line-119">  /**</span>
-<span class="source-line-no">120</span><span id="line-120">   * Load system coprocessors once only. Read the class names from configuration. Called by</span>
-<span class="source-line-no">121</span><span id="line-121">   * constructor.</span>
-<span class="source-line-no">122</span><span id="line-122">   */</span>
-<span class="source-line-no">123</span><span id="line-123">  protected void loadSystemCoprocessors(Configuration conf, String confKey) {</span>
-<span class="source-line-no">124</span><span id="line-124">    boolean coprocessorsEnabled =</span>
-<span class="source-line-no">125</span><span id="line-125">      conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, DEFAULT_COPROCESSORS_ENABLED);</span>
-<span class="source-line-no">126</span><span id="line-126">    if (!coprocessorsEnabled) {</span>
-<span class="source-line-no">127</span><span id="line-127">      return;</span>
-<span class="source-line-no">128</span><span id="line-128">    }</span>
-<span class="source-line-no">129</span><span id="line-129"></span>
-<span class="source-line-no">130</span><span id="line-130">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">064</span><span id="line-64">  public static final String CLIENT_META_COPROCESSOR_CONF_KEY =</span>
+<span class="source-line-no">065</span><span id="line-65">    "hbase.coprocessor.clientmeta.classes";</span>
+<span class="source-line-no">066</span><span id="line-66">  public static final String WAL_COPROCESSOR_CONF_KEY = "hbase.coprocessor.wal.classes";</span>
+<span class="source-line-no">067</span><span id="line-67">  public static final String RPC_COPROCESSOR_CONF_KEY = "hbase.coprocessor.rpc.classes";</span>
+<span class="source-line-no">068</span><span id="line-68">  public static final String ABORT_ON_ERROR_KEY = "hbase.coprocessor.abortonerror";</span>
+<span class="source-line-no">069</span><span id="line-69">  public static final boolean DEFAULT_ABORT_ON_ERROR = true;</span>
+<span class="source-line-no">070</span><span id="line-70">  public static final String COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.enabled";</span>
+<span class="source-line-no">071</span><span id="line-71">  public static final boolean DEFAULT_COPROCESSORS_ENABLED = true;</span>
+<span class="source-line-no">072</span><span id="line-72">  public static final String USER_COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.user.enabled";</span>
+<span class="source-line-no">073</span><span id="line-73">  public static final boolean DEFAULT_USER_COPROCESSORS_ENABLED = true;</span>
+<span class="source-line-no">074</span><span id="line-74">  public static final String SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR =</span>
+<span class="source-line-no">075</span><span id="line-75">    "hbase.skip.load.duplicate.table.coprocessor";</span>
+<span class="source-line-no">076</span><span id="line-76">  public static final boolean DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR = false;</span>
+<span class="source-line-no">077</span><span id="line-77"></span>
+<span class="source-line-no">078</span><span id="line-78">  private static final Logger LOG = LoggerFactory.getLogger(CoprocessorHost.class);</span>
+<span class="source-line-no">079</span><span id="line-79">  protected Abortable abortable;</span>
+<span class="source-line-no">080</span><span id="line-80">  /** Ordered set of loaded coprocessors with lock */</span>
+<span class="source-line-no">081</span><span id="line-81">  protected final SortedList&lt;E&gt; coprocEnvironments =</span>
+<span class="source-line-no">082</span><span id="line-82">    new SortedList&lt;&gt;(new EnvironmentPriorityComparator());</span>
+<span class="source-line-no">083</span><span id="line-83">  protected Configuration conf;</span>
+<span class="source-line-no">084</span><span id="line-84">  // unique file prefix to use for local copies of jars when classloading</span>
+<span class="source-line-no">085</span><span id="line-85">  protected String pathPrefix;</span>
+<span class="source-line-no">086</span><span id="line-86">  protected AtomicInteger loadSequence = new AtomicInteger();</span>
+<span class="source-line-no">087</span><span id="line-87"></span>
+<span class="source-line-no">088</span><span id="line-88">  public CoprocessorHost(Abortable abortable) {</span>
+<span class="source-line-no">089</span><span id="line-89">    this.abortable = abortable;</span>
+<span class="source-line-no">090</span><span id="line-90">    this.pathPrefix = UUID.randomUUID().toString();</span>
+<span class="source-line-no">091</span><span id="line-91">  }</span>
+<span class="source-line-no">092</span><span id="line-92"></span>
+<span class="source-line-no">093</span><span id="line-93">  /**</span>
+<span class="source-line-no">094</span><span id="line-94">   * Not to be confused with the per-object _coprocessors_ (above), coprocessorNames is static and</span>
+<span class="source-line-no">095</span><span id="line-95">   * stores the set of all coprocessors ever loaded by any thread in this JVM. It is strictly</span>
+<span class="source-line-no">096</span><span id="line-96">   * additive: coprocessors are added to coprocessorNames, by checkAndLoadInstance() but are never</span>
+<span class="source-line-no">097</span><span id="line-97">   * removed, since the intention is to preserve a history of all loaded coprocessors for diagnosis</span>
+<span class="source-line-no">098</span><span id="line-98">   * in case of server crash (HBASE-4014).</span>
+<span class="source-line-no">099</span><span id="line-99">   */</span>
+<span class="source-line-no">100</span><span id="line-100">  private static Set&lt;String&gt; coprocessorNames = Collections.synchronizedSet(new HashSet&lt;String&gt;());</span>
+<span class="source-line-no">101</span><span id="line-101"></span>
+<span class="source-line-no">102</span><span id="line-102">  public static Set&lt;String&gt; getLoadedCoprocessors() {</span>
+<span class="source-line-no">103</span><span id="line-103">    synchronized (coprocessorNames) {</span>
+<span class="source-line-no">104</span><span id="line-104">      return new HashSet(coprocessorNames);</span>
+<span class="source-line-no">105</span><span id="line-105">    }</span>
+<span class="source-line-no">106</span><span id="line-106">  }</span>
+<span class="source-line-no">107</span><span id="line-107"></span>
+<span class="source-line-no">108</span><span id="line-108">  /**</span>
+<span class="source-line-no">109</span><span id="line-109">   * Used to create a parameter to the HServerLoad constructor so that HServerLoad can provide</span>
+<span class="source-line-no">110</span><span id="line-110">   * information about the coprocessors loaded by this regionserver. (HBASE-4070: Improve region</span>
+<span class="source-line-no">111</span><span id="line-111">   * server metrics to report loaded coprocessors to master).</span>
+<span class="source-line-no">112</span><span id="line-112">   */</span>
+<span class="source-line-no">113</span><span id="line-113">  public Set&lt;String&gt; getCoprocessors() {</span>
+<span class="source-line-no">114</span><span id="line-114">    Set&lt;String&gt; returnValue = new TreeSet&lt;&gt;();</span>
+<span class="source-line-no">115</span><span id="line-115">    for (E e : coprocEnvironments) {</span>
+<span class="source-line-no">116</span><span id="line-116">      returnValue.add(e.getInstance().getClass().getSimpleName());</span>
+<span class="source-line-no">117</span><span id="line-117">    }</span>
+<span class="source-line-no">118</span><span id="line-118">    return returnValue;</span>
+<span class="source-line-no">119</span><span id="line-119">  }</span>
+<span class="source-line-no">120</span><span id="line-120"></span>
+<span class="source-line-no">121</span><span id="line-121">  /**</span>
+<span class="source-line-no">122</span><span id="line-122">   * Load system coprocessors once only. Read the class names from configuration. Called by</span>
+<span class="source-line-no">123</span><span id="line-123">   * constructor.</span>
+<span class="source-line-no">124</span><span id="line-124">   */</span>
+<span class="source-line-no">125</span><span id="line-125">  protected void loadSystemCoprocessors(Configuration conf, String confKey) {</span>
+<span class="source-line-no">126</span><span id="line-126">    boolean coprocessorsEnabled =</span>
+<span class="source-line-no">127</span><span id="line-127">      conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, DEFAULT_COPROCESSORS_ENABLED);</span>
+<span class="source-line-no">128</span><span id="line-128">    if (!coprocessorsEnabled) {</span>
+<span class="source-line-no">129</span><span id="line-129">      return;</span>
+<span class="source-line-no">130</span><span id="line-130">    }</span>
 <span class="source-line-no">131</span><span id="line-131"></span>
-<span class="source-line-no">132</span><span id="line-132">    // load default coprocessors from configure file</span>
-<span class="source-line-no">133</span><span id="line-133">    String[] defaultCPClasses = conf.getStrings(confKey);</span>
-<span class="source-line-no">134</span><span id="line-134">    if (defaultCPClasses == null || defaultCPClasses.length == 0) return;</span>
-<span class="source-line-no">135</span><span id="line-135"></span>
-<span class="source-line-no">136</span><span id="line-136">    int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;</span>
-<span class="source-line-no">137</span><span id="line-137">    for (String className : defaultCPClasses) {</span>
-<span class="source-line-no">138</span><span id="line-138">      // After HBASE-23710 and HBASE-26714 when configuring for system coprocessor, we accept</span>
-<span class="source-line-no">139</span><span id="line-139">      // an optional format of className|priority|path</span>
-<span class="source-line-no">140</span><span id="line-140">      String[] classNameToken = className.split("\\|");</span>
-<span class="source-line-no">141</span><span id="line-141">      boolean hasPriorityOverride = false;</span>
-<span class="source-line-no">142</span><span id="line-142">      boolean hasPath = false;</span>
-<span class="source-line-no">143</span><span id="line-143">      className = classNameToken[0];</span>
-<span class="source-line-no">144</span><span id="line-144">      int overridePriority = Coprocessor.PRIORITY_SYSTEM;</span>
-<span class="source-line-no">145</span><span id="line-145">      Path path = null;</span>
-<span class="source-line-no">146</span><span id="line-146">      if (classNameToken.length &gt; 1 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[1])) {</span>
-<span class="source-line-no">147</span><span id="line-147">        overridePriority = Integer.parseInt(classNameToken[1]);</span>
-<span class="source-line-no">148</span><span id="line-148">        hasPriorityOverride = true;</span>
-<span class="source-line-no">149</span><span id="line-149">      }</span>
-<span class="source-line-no">150</span><span id="line-150">      if (classNameToken.length &gt; 2 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[2])) {</span>
-<span class="source-line-no">151</span><span id="line-151">        path = new Path(classNameToken[2].trim());</span>
-<span class="source-line-no">152</span><span id="line-152">        hasPath = true;</span>
-<span class="source-line-no">153</span><span id="line-153">      }</span>
-<span class="source-line-no">154</span><span id="line-154">      className = className.trim();</span>
-<span class="source-line-no">155</span><span id="line-155">      if (findCoprocessor(className) != null) {</span>
-<span class="source-line-no">156</span><span id="line-156">        // If already loaded will just continue</span>
-<span class="source-line-no">157</span><span id="line-157">        LOG.warn("Attempted duplicate loading of " + className + "; skipped");</span>
-<span class="source-line-no">158</span><span id="line-158">        continue;</span>
-<span class="source-line-no">159</span><span id="line-159">      }</span>
-<span class="source-line-no">160</span><span id="line-160">      ClassLoader cl = this.getClass().getClassLoader();</span>
-<span class="source-line-no">161</span><span id="line-161">      try {</span>
-<span class="source-line-no">162</span><span id="line-162">        // override the class loader if a path for the system coprocessor is provided.</span>
-<span class="source-line-no">163</span><span id="line-163">        if (hasPath) {</span>
-<span class="source-line-no">164</span><span id="line-164">          cl = CoprocessorClassLoader.getClassLoader(path, this.getClass().getClassLoader(),</span>
-<span class="source-line-no">165</span><span id="line-165">            pathPrefix, conf);</span>
-<span class="source-line-no">166</span><span id="line-166">        }</span>
-<span class="source-line-no">167</span><span id="line-167">        Thread.currentThread().setContextClassLoader(cl);</span>
-<span class="source-line-no">168</span><span id="line-168">        implClass = cl.loadClass(className);</span>
-<span class="source-line-no">169</span><span id="line-169">        int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;</span>
-<span class="source-line-no">170</span><span id="line-170">        // Add coprocessors as we go to guard against case where a coprocessor is specified twice</span>
-<span class="source-line-no">171</span><span id="line-171">        // in the configuration</span>
-<span class="source-line-no">172</span><span id="line-172">        E env = checkAndLoadInstance(implClass, coprocPriority, conf);</span>
-<span class="source-line-no">173</span><span id="line-173">        if (env != null) {</span>
-<span class="source-line-no">174</span><span id="line-174">          this.coprocEnvironments.add(env);</span>
-<span class="source-line-no">175</span><span id="line-175">          LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);</span>
-<span class="source-line-no">176</span><span id="line-176">          if (!hasPriorityOverride) {</span>
-<span class="source-line-no">177</span><span id="line-177">            ++currentSystemPriority;</span>
-<span class="source-line-no">178</span><span id="line-178">          }</span>
-<span class="source-line-no">179</span><span id="line-179">        }</span>
-<span class="source-line-no">180</span><span id="line-180">      } catch (Throwable t) {</span>
-<span class="source-line-no">181</span><span id="line-181">        // We always abort if system coprocessors cannot be loaded</span>
-<span class="source-line-no">182</span><span id="line-182">        abortServer(className, t);</span>
-<span class="source-line-no">183</span><span id="line-183">      }</span>
-<span class="source-line-no">184</span><span id="line-184">    }</span>
-<span class="source-line-no">185</span><span id="line-185">  }</span>
-<span class="source-line-no">186</span><span id="line-186"></span>
-<span class="source-line-no">187</span><span id="line-187">  /**</span>
-<span class="source-line-no">188</span><span id="line-188">   * Load a coprocessor implementation into the host</span>
-<span class="source-line-no">189</span><span id="line-189">   * @param path      path to implementation jar</span>
-<span class="source-line-no">190</span><span id="line-190">   * @param className the main class name</span>
-<span class="source-line-no">191</span><span id="line-191">   * @param priority  chaining priority</span>
-<span class="source-line-no">192</span><span id="line-192">   * @param conf      configuration for coprocessor</span>
-<span class="source-line-no">193</span><span id="line-193">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">194</span><span id="line-194">   */</span>
-<span class="source-line-no">195</span><span id="line-195">  public E load(Path path, String className, int priority, Configuration conf) throws IOException {</span>
-<span class="source-line-no">196</span><span id="line-196">    String[] includedClassPrefixes = null;</span>
-<span class="source-line-no">197</span><span id="line-197">    if (conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY) != null) {</span>
-<span class="source-line-no">198</span><span id="line-198">      String prefixes = conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY);</span>
-<span class="source-line-no">199</span><span id="line-199">      includedClassPrefixes = prefixes.split(";");</span>
-<span class="source-line-no">200</span><span id="line-200">    }</span>
-<span class="source-line-no">201</span><span id="line-201">    return load(path, className, priority, conf, includedClassPrefixes);</span>
-<span class="source-line-no">202</span><span id="line-202">  }</span>
-<span class="source-line-no">203</span><span id="line-203"></span>
-<span class="source-line-no">204</span><span id="line-204">  /**</span>
-<span class="source-line-no">205</span><span id="line-205">   * Load a coprocessor implementation into the host</span>
-<span class="source-line-no">206</span><span id="line-206">   * @param path                  path to implementation jar</span>
-<span class="source-line-no">207</span><span id="line-207">   * @param className             the main class name</span>
-<span class="source-line-no">208</span><span id="line-208">   * @param priority              chaining priority</span>
-<span class="source-line-no">209</span><span id="line-209">   * @param conf                  configuration for coprocessor</span>
-<span class="source-line-no">210</span><span id="line-210">   * @param includedClassPrefixes class name prefixes to include</span>
-<span class="source-line-no">211</span><span id="line-211">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">212</span><span id="line-212">   */</span>
-<span class="source-line-no">213</span><span id="line-213">  public E load(Path path, String className, int priority, Configuration conf,</span>
-<span class="source-line-no">214</span><span id="line-214">    String[] includedClassPrefixes) throws IOException {</span>
-<span class="source-line-no">215</span><span id="line-215">    Class&lt;?&gt; implClass;</span>
-<span class="source-line-no">216</span><span id="line-216">    LOG.debug("Loading coprocessor class " + className + " with path " + path + " and priority "</span>
-<span class="source-line-no">217</span><span id="line-217">      + priority);</span>
-<span class="source-line-no">218</span><span id="line-218"></span>
-<span class="source-line-no">219</span><span id="line-219">    boolean skipLoadDuplicateCoprocessor = conf.getBoolean(SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR,</span>
-<span class="source-line-no">220</span><span id="line-220">      DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR);</span>
-<span class="source-line-no">221</span><span id="line-221">    if (skipLoadDuplicateCoprocessor &amp;&amp; findCoprocessor(className) != null) {</span>
-<span class="source-line-no">222</span><span id="line-222">      // If already loaded will just continue</span>
-<span class="source-line-no">223</span><span id="line-223">      LOG.warn("Attempted duplicate loading of {}; skipped", className);</span>
-<span class="source-line-no">224</span><span id="line-224">      return null;</span>
-<span class="source-line-no">225</span><span id="line-225">    }</span>
-<span class="source-line-no">226</span><span id="line-226"></span>
-<span class="source-line-no">227</span><span id="line-227">    ClassLoader cl = null;</span>
-<span class="source-line-no">228</span><span id="line-228">    if (path == null) {</span>
-<span class="source-line-no">229</span><span id="line-229">      try {</span>
-<span class="source-line-no">230</span><span id="line-230">        implClass = getClass().getClassLoader().loadClass(className);</span>
-<span class="source-line-no">231</span><span id="line-231">      } catch (ClassNotFoundException e) {</span>
-<span class="source-line-no">232</span><span id="line-232">        throw new IOException("No jar path specified for " + className);</span>
-<span class="source-line-no">233</span><span id="line-233">      }</span>
-<span class="source-line-no">234</span><span id="line-234">    } else {</span>
-<span class="source-line-no">235</span><span id="line-235">      cl =</span>
-<span class="source-line-no">236</span><span id="line-236">        CoprocessorClassLoader.getClassLoader(path, getClass().getClassLoader(), pathPrefix, conf);</span>
-<span class="source-line-no">237</span><span id="line-237">      try {</span>
-<span class="source-line-no">238</span><span id="line-238">        implClass = ((CoprocessorClassLoader) cl).loadClass(className, includedClassPrefixes);</span>
-<span class="source-line-no">239</span><span id="line-239">      } catch (ClassNotFoundException e) {</span>
-<span class="source-line-no">240</span><span id="line-240">        throw new IOException("Cannot load external coprocessor class " + className, e);</span>
-<span class="source-line-no">241</span><span id="line-241">      }</span>
-<span class="source-line-no">242</span><span id="line-242">    }</span>
-<span class="source-line-no">243</span><span id="line-243"></span>
-<span class="source-line-no">244</span><span id="line-244">    // load custom code for coprocessor</span>
-<span class="source-line-no">245</span><span id="line-245">    Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">246</span><span id="line-246">    ClassLoader hostClassLoader = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">247</span><span id="line-247">    try {</span>
-<span class="source-line-no">248</span><span id="line-248">      // switch temporarily to the thread classloader for custom CP</span>
-<span class="source-line-no">249</span><span id="line-249">      currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">250</span><span id="line-250">      E cpInstance = checkAndLoadInstance(implClass, priority, conf);</span>
-<span class="source-line-no">251</span><span id="line-251">      return cpInstance;</span>
-<span class="source-line-no">252</span><span id="line-252">    } finally {</span>
-<span class="source-line-no">253</span><span id="line-253">      // restore the fresh (host) classloader</span>
-<span class="source-line-no">254</span><span id="line-254">      currentThread.setContextClassLoader(hostClassLoader);</span>
-<span class="source-line-no">255</span><span id="line-255">    }</span>
-<span class="source-line-no">256</span><span id="line-256">  }</span>
-<span class="source-line-no">257</span><span id="line-257"></span>
-<span class="source-line-no">258</span><span id="line-258">  public void load(Class&lt;? extends C&gt; implClass, int priority, Configuration conf)</span>
-<span class="source-line-no">259</span><span id="line-259">    throws IOException {</span>
-<span class="source-line-no">260</span><span id="line-260">    E env = checkAndLoadInstance(implClass, priority, conf);</span>
-<span class="source-line-no">261</span><span id="line-261">    coprocEnvironments.add(env);</span>
-<span class="source-line-no">262</span><span id="line-262">  }</span>
-<span class="source-line-no">263</span><span id="line-263"></span>
-<span class="source-line-no">264</span><span id="line-264">  /**</span>
-<span class="source-line-no">265</span><span id="line-265">   * @param implClass Implementation class</span>
-<span class="source-line-no">266</span><span id="line-266">   * @param priority  priority</span>
-<span class="source-line-no">267</span><span id="line-267">   * @param conf      configuration</span>
-<span class="source-line-no">268</span><span id="line-268">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">269</span><span id="line-269">   */</span>
-<span class="source-line-no">270</span><span id="line-270">  public E checkAndLoadInstance(Class&lt;?&gt; implClass, int priority, Configuration conf)</span>
-<span class="source-line-no">271</span><span id="line-271">    throws IOException {</span>
-<span class="source-line-no">272</span><span id="line-272">    // create the instance</span>
-<span class="source-line-no">273</span><span id="line-273">    C impl;</span>
-<span class="source-line-no">274</span><span id="line-274">    try {</span>
-<span class="source-line-no">275</span><span id="line-275">      impl = checkAndGetInstance(implClass);</span>
-<span class="source-line-no">276</span><span id="line-276">      if (impl == null) {</span>
-<span class="source-line-no">277</span><span id="line-277">        LOG.error("Cannot load coprocessor " + implClass.getSimpleName());</span>
-<span class="source-line-no">278</span><span id="line-278">        return null;</span>
-<span class="source-line-no">279</span><span id="line-279">      }</span>
-<span class="source-line-no">280</span><span id="line-280">    } catch (InstantiationException | IllegalAccessException e) {</span>
-<span class="source-line-no">281</span><span id="line-281">      throw new IOException(e);</span>
-<span class="source-line-no">282</span><span id="line-282">    }</span>
-<span class="source-line-no">283</span><span id="line-283">    // create the environment</span>
-<span class="source-line-no">284</span><span id="line-284">    E env = createEnvironment(impl, priority, loadSequence.incrementAndGet(), conf);</span>
-<span class="source-line-no">285</span><span id="line-285">    assert env instanceof BaseEnvironment;</span>
-<span class="source-line-no">286</span><span id="line-286">    ((BaseEnvironment&lt;C&gt;) env).startup();</span>
-<span class="source-line-no">287</span><span id="line-287">    // HBASE-4014: maintain list of loaded coprocessors for later crash analysis</span>
-<span class="source-line-no">288</span><span id="line-288">    // if server (master or regionserver) aborts.</span>
-<span class="source-line-no">289</span><span id="line-289">    coprocessorNames.add(implClass.getName());</span>
-<span class="source-line-no">290</span><span id="line-290">    return env;</span>
-<span class="source-line-no">291</span><span id="line-291">  }</span>
-<span class="source-line-no">292</span><span id="line-292"></span>
-<span class="source-line-no">293</span><span id="line-293">  /**</span>
-<span class="source-line-no">294</span><span id="line-294">   * Called when a new Coprocessor class is loaded</span>
-<span class="source-line-no">295</span><span id="line-295">   */</span>
-<span class="source-line-no">296</span><span id="line-296">  public abstract E createEnvironment(C instance, int priority, int sequence, Configuration conf);</span>
-<span class="source-line-no">297</span><span id="line-297"></span>
-<span class="source-line-no">298</span><span id="line-298">  /**</span>
-<span class="source-line-no">299</span><span id="line-299">   * Called when a new Coprocessor class needs to be loaded. Checks if type of the given class is</span>
-<span class="source-line-no">300</span><span id="line-300">   * what the corresponding host implementation expects. If it is of correct type, returns an</span>
-<span class="source-line-no">301</span><span id="line-301">   * instance of the coprocessor to be loaded. If not, returns null. If an exception occurs when</span>
-<span class="source-line-no">302</span><span id="line-302">   * trying to create instance of a coprocessor, it's passed up and eventually results into server</span>
-<span class="source-line-no">303</span><span id="line-303">   * aborting.</span>
-<span class="source-line-no">304</span><span id="line-304">   */</span>
-<span class="source-line-no">305</span><span id="line-305">  public abstract C checkAndGetInstance(Class&lt;?&gt; implClass)</span>
-<span class="source-line-no">306</span><span id="line-306">    throws InstantiationException, IllegalAccessException;</span>
-<span class="source-line-no">307</span><span id="line-307"></span>
-<span class="source-line-no">308</span><span id="line-308">  public void shutdown(E e) {</span>
-<span class="source-line-no">309</span><span id="line-309">    assert e instanceof BaseEnvironment;</span>
-<span class="source-line-no">310</span><span id="line-310">    if (LOG.isDebugEnabled()) {</span>
-<span class="source-line-no">311</span><span id="line-311">      LOG.debug("Stop coprocessor " + e.getInstance().getClass().getName());</span>
-<span class="source-line-no">312</span><span id="line-312">    }</span>
-<span class="source-line-no">313</span><span id="line-313">    ((BaseEnvironment&lt;C&gt;) e).shutdown();</span>
-<span class="source-line-no">314</span><span id="line-314">  }</span>
-<span class="source-line-no">315</span><span id="line-315"></span>
-<span class="source-line-no">316</span><span id="line-316">  /**</span>
-<span class="source-line-no">317</span><span id="line-317">   * Find coprocessors by full class name or simple name.</span>
-<span class="source-line-no">318</span><span id="line-318">   */</span>
-<span class="source-line-no">319</span><span id="line-319">  public C findCoprocessor(String className) {</span>
-<span class="source-line-no">320</span><span id="line-320">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">321</span><span id="line-321">      if (</span>
-<span class="source-line-no">322</span><span id="line-322">        env.getInstance().getClass().getName().equals(className)</span>
-<span class="source-line-no">323</span><span id="line-323">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
-<span class="source-line-no">324</span><span id="line-324">      ) {</span>
-<span class="source-line-no">325</span><span id="line-325">        return env.getInstance();</span>
-<span class="source-line-no">326</span><span id="line-326">      }</span>
-<span class="source-line-no">327</span><span id="line-327">    }</span>
-<span class="source-line-no">328</span><span id="line-328">    return null;</span>
-<span class="source-line-no">329</span><span id="line-329">  }</span>
-<span class="source-line-no">330</span><span id="line-330"></span>
-<span class="source-line-no">331</span><span id="line-331">  public &lt;T extends C&gt; T findCoprocessor(Class&lt;T&gt; cls) {</span>
-<span class="source-line-no">332</span><span id="line-332">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">333</span><span id="line-333">      if (cls.isAssignableFrom(env.getInstance().getClass())) {</span>
-<span class="source-line-no">334</span><span id="line-334">        return (T) env.getInstance();</span>
-<span class="source-line-no">335</span><span id="line-335">      }</span>
-<span class="source-line-no">336</span><span id="line-336">    }</span>
-<span class="source-line-no">337</span><span id="line-337">    return null;</span>
-<span class="source-line-no">338</span><span id="line-338">  }</span>
-<span class="source-line-no">339</span><span id="line-339"></span>
-<span class="source-line-no">340</span><span id="line-340">  /**</span>
-<span class="source-line-no">341</span><span id="line-341">   * Find list of coprocessors that extend/implement the given class/interface</span>
-<span class="source-line-no">342</span><span id="line-342">   * @param cls the class/interface to look for</span>
-<span class="source-line-no">343</span><span id="line-343">   * @return the list of coprocessors, or null if not found</span>
-<span class="source-line-no">344</span><span id="line-344">   */</span>
-<span class="source-line-no">345</span><span id="line-345">  public &lt;T extends C&gt; List&lt;T&gt; findCoprocessors(Class&lt;T&gt; cls) {</span>
-<span class="source-line-no">346</span><span id="line-346">    ArrayList&lt;T&gt; ret = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">347</span><span id="line-347"></span>
-<span class="source-line-no">348</span><span id="line-348">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">349</span><span id="line-349">      C cp = env.getInstance();</span>
-<span class="source-line-no">350</span><span id="line-350"></span>
-<span class="source-line-no">351</span><span id="line-351">      if (cp != null) {</span>
-<span class="source-line-no">352</span><span id="line-352">        if (cls.isAssignableFrom(cp.getClass())) {</span>
-<span class="source-line-no">353</span><span id="line-353">          ret.add((T) cp);</span>
-<span class="source-line-no">354</span><span id="line-354">        }</span>
-<span class="source-line-no">355</span><span id="line-355">      }</span>
-<span class="source-line-no">356</span><span id="line-356">    }</span>
-<span class="source-line-no">357</span><span id="line-357">    return ret;</span>
-<span class="source-line-no">358</span><span id="line-358">  }</span>
-<span class="source-line-no">359</span><span id="line-359"></span>
-<span class="source-line-no">360</span><span id="line-360">  /**</span>
-<span class="source-line-no">361</span><span id="line-361">   * Find a coprocessor environment by class name</span>
-<span class="source-line-no">362</span><span id="line-362">   * @param className the class name</span>
-<span class="source-line-no">363</span><span id="line-363">   * @return the coprocessor, or null if not found</span>
-<span class="source-line-no">364</span><span id="line-364">   */</span>
-<span class="source-line-no">365</span><span id="line-365">  public E findCoprocessorEnvironment(String className) {</span>
-<span class="source-line-no">366</span><span id="line-366">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">367</span><span id="line-367">      if (</span>
-<span class="source-line-no">368</span><span id="line-368">        env.getInstance().getClass().getName().equals(className)</span>
-<span class="source-line-no">369</span><span id="line-369">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
-<span class="source-line-no">370</span><span id="line-370">      ) {</span>
-<span class="source-line-no">371</span><span id="line-371">        return env;</span>
-<span class="source-line-no">372</span><span id="line-372">      }</span>
-<span class="source-line-no">373</span><span id="line-373">    }</span>
-<span class="source-line-no">374</span><span id="line-374">    return null;</span>
-<span class="source-line-no">375</span><span id="line-375">  }</span>
-<span class="source-line-no">376</span><span id="line-376"></span>
-<span class="source-line-no">377</span><span id="line-377">  /**</span>
-<span class="source-line-no">378</span><span id="line-378">   * Retrieves the set of classloaders used to instantiate Coprocessor classes defined in external</span>
-<span class="source-line-no">379</span><span id="line-379">   * jar files.</span>
-<span class="source-line-no">380</span><span id="line-380">   * @return A set of ClassLoader instances</span>
-<span class="source-line-no">381</span><span id="line-381">   */</span>
-<span class="source-line-no">382</span><span id="line-382">  Set&lt;ClassLoader&gt; getExternalClassLoaders() {</span>
-<span class="source-line-no">383</span><span id="line-383">    Set&lt;ClassLoader&gt; externalClassLoaders = new HashSet&lt;&gt;();</span>
-<span class="source-line-no">384</span><span id="line-384">    final ClassLoader systemClassLoader = this.getClass().getClassLoader();</span>
-<span class="source-line-no">385</span><span id="line-385">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">386</span><span id="line-386">      ClassLoader cl = env.getInstance().getClass().getClassLoader();</span>
-<span class="source-line-no">387</span><span id="line-387">      if (cl != systemClassLoader) {</span>
-<span class="source-line-no">388</span><span id="line-388">        // do not include system classloader</span>
-<span class="source-line-no">389</span><span id="line-389">        externalClassLoaders.add(cl);</span>
-<span class="source-line-no">390</span><span id="line-390">      }</span>
-<span class="source-line-no">391</span><span id="line-391">    }</span>
-<span class="source-line-no">392</span><span id="line-392">    return externalClassLoaders;</span>
-<span class="source-line-no">393</span><span id="line-393">  }</span>
-<span class="source-line-no">394</span><span id="line-394"></span>
-<span class="source-line-no">395</span><span id="line-395">  /**</span>
-<span class="source-line-no">396</span><span id="line-396">   * Environment priority comparator. Coprocessors are chained in sorted order.</span>
-<span class="source-line-no">397</span><span id="line-397">   */</span>
-<span class="source-line-no">398</span><span id="line-398">  static class EnvironmentPriorityComparator implements Comparator&lt;CoprocessorEnvironment&gt; {</span>
-<span class="source-line-no">399</span><span id="line-399">    @Override</span>
-<span class="source-line-no">400</span><span id="line-400">    public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) {</span>
-<span class="source-line-no">401</span><span id="line-401">      if (env1.getPriority() &lt; env2.getPriority()) {</span>
-<span class="source-line-no">402</span><span id="line-402">        return -1;</span>
-<span class="source-line-no">403</span><span id="line-403">      } else if (env1.getPriority() &gt; env2.getPriority()) {</span>
-<span class="source-line-no">404</span><span id="line-404">        return 1;</span>
-<span class="source-line-no">405</span><span id="line-405">      }</span>
-<span class="source-line-no">406</span><span id="line-406">      if (env1.getLoadSequence() &lt; env2.getLoadSequence()) {</span>
-<span class="source-line-no">407</span><span id="line-407">        return -1;</span>
-<span class="source-line-no">408</span><span id="line-408">      } else if (env1.getLoadSequence() &gt; env2.getLoadSequence()) {</span>
-<span class="source-line-no">409</span><span id="line-409">        return 1;</span>
-<span class="source-line-no">410</span><span id="line-410">      }</span>
-<span class="source-line-no">411</span><span id="line-411">      return 0;</span>
-<span class="source-line-no">412</span><span id="line-412">    }</span>
-<span class="source-line-no">413</span><span id="line-413">  }</span>
-<span class="source-line-no">414</span><span id="line-414"></span>
-<span class="source-line-no">415</span><span id="line-415">  protected void abortServer(final E environment, final Throwable e) {</span>
-<span class="source-line-no">416</span><span id="line-416">    abortServer(environment.getInstance().getClass().getName(), e);</span>
-<span class="source-line-no">417</span><span id="line-417">  }</span>
-<span class="source-line-no">418</span><span id="line-418"></span>
-<span class="source-line-no">419</span><span id="line-419">  protected void abortServer(final String coprocessorName, final Throwable e) {</span>
-<span class="source-line-no">420</span><span id="line-420">    String message = "The coprocessor " + coprocessorName + " threw " + e.toString();</span>
-<span class="source-line-no">421</span><span id="line-421">    LOG.error(message, e);</span>
-<span class="source-line-no">422</span><span id="line-422">    if (abortable != null) {</span>
-<span class="source-line-no">423</span><span id="line-423">      abortable.abort(message, e);</span>
-<span class="source-line-no">424</span><span id="line-424">    } else {</span>
-<span class="source-line-no">425</span><span id="line-425">      LOG.warn("No available Abortable, process was not aborted");</span>
-<span class="source-line-no">426</span><span id="line-426">    }</span>
-<span class="source-line-no">427</span><span id="line-427">  }</span>
-<span class="source-line-no">428</span><span id="line-428"></span>
-<span class="source-line-no">429</span><span id="line-429">  /**</span>
-<span class="source-line-no">430</span><span id="line-430">   * This is used by coprocessor hooks which are declared to throw IOException (or its subtypes).</span>
-<span class="source-line-no">431</span><span id="line-431">   * For such hooks, we should handle throwable objects depending on the Throwable's type. Those</span>
-<span class="source-line-no">432</span><span id="line-432">   * which are instances of IOException should be passed on to the client. This is in conformance</span>
-<span class="source-line-no">433</span><span id="line-433">   * with the HBase idiom regarding IOException: that it represents a circumstance that should be</span>
-<span class="source-line-no">434</span><span id="line-434">   * passed along to the client for its own handling. For example, a coprocessor that implements</span>
-<span class="source-line-no">435</span><span id="line-435">   * access controls would throw a subclass of IOException, such as AccessDeniedException, in its</span>
-<span class="source-line-no">436</span><span id="line-436">   * preGet() method to prevent an unauthorized client's performing a Get on a particular table.</span>
-<span class="source-line-no">437</span><span id="line-437">   * @param env Coprocessor Environment</span>
-<span class="source-line-no">438</span><span id="line-438">   * @param e   Throwable object thrown by coprocessor.</span>
-<span class="source-line-no">439</span><span id="line-439">   * @exception IOException Exception</span>
-<span class="source-line-no">440</span><span id="line-440">   */</span>
-<span class="source-line-no">441</span><span id="line-441">  // Note to devs: Class comments of all observers ({@link MasterObserver}, {@link WALObserver},</span>
-<span class="source-line-no">442</span><span id="line-442">  // etc) mention this nuance of our exception handling so that coprocessor can throw appropriate</span>
-<span class="source-line-no">443</span><span id="line-443">  // exceptions depending on situation. If any changes are made to this logic, make sure to</span>
-<span class="source-line-no">444</span><span id="line-444">  // update all classes' comments.</span>
-<span class="source-line-no">445</span><span id="line-445">  protected void handleCoprocessorThrowable(final E env, final Throwable e) throws IOException {</span>
-<span class="source-line-no">446</span><span id="line-446">    if (e instanceof IOException) {</span>
-<span class="source-line-no">447</span><span id="line-447">      throw (IOException) e;</span>
-<span class="source-line-no">448</span><span id="line-448">    }</span>
-<span class="source-line-no">449</span><span id="line-449">    // If we got here, e is not an IOException. A loaded coprocessor has a</span>
-<span class="source-line-no">450</span><span id="line-450">    // fatal bug, and the server (master or regionserver) should remove the</span>
-<span class="source-line-no">451</span><span id="line-451">    // faulty coprocessor from its set of active coprocessors. Setting</span>
-<span class="source-line-no">452</span><span id="line-452">    // 'hbase.coprocessor.abortonerror' to true will cause abortServer(),</span>
-<span class="source-line-no">453</span><span id="line-453">    // which may be useful in development and testing environments where</span>
-<span class="source-line-no">454</span><span id="line-454">    // 'failing fast' for error analysis is desired.</span>
-<span class="source-line-no">455</span><span id="line-455">    if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) {</span>
-<span class="source-line-no">456</span><span id="line-456">      // server is configured to abort.</span>
-<span class="source-line-no">457</span><span id="line-457">      abortServer(env, e);</span>
-<span class="source-line-no">458</span><span id="line-458">    } else {</span>
-<span class="source-line-no">459</span><span id="line-459">      // If available, pull a table name out of the environment</span>
-<span class="source-line-no">460</span><span id="line-460">      if (env instanceof RegionCoprocessorEnvironment) {</span>
-<span class="source-line-no">461</span><span id="line-461">        String tableName =</span>
-<span class="source-line-no">462</span><span id="line-462">          ((RegionCoprocessorEnvironment) env).getRegionInfo().getTable().getNameAsString();</span>
-<span class="source-line-no">463</span><span id="line-463">        LOG.error("Removing coprocessor '" + env.toString() + "' from table '" + tableName + "'",</span>
-<span class="source-line-no">464</span><span id="line-464">          e);</span>
-<span class="source-line-no">465</span><span id="line-465">      } else {</span>
-<span class="source-line-no">466</span><span id="line-466">        LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment", e);</span>
-<span class="source-line-no">467</span><span id="line-467">      }</span>
-<span class="source-line-no">468</span><span id="line-468"></span>
-<span class="source-line-no">469</span><span id="line-469">      coprocEnvironments.remove(env);</span>
-<span class="source-line-no">470</span><span id="line-470">      try {</span>
-<span class="source-line-no">471</span><span id="line-471">        shutdown(env);</span>
-<span class="source-line-no">472</span><span id="line-472">      } catch (Exception x) {</span>
-<span class="source-line-no">473</span><span id="line-473">        LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x);</span>
-<span class="source-line-no">474</span><span id="line-474">      }</span>
-<span class="source-line-no">475</span><span id="line-475">      throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e</span>
-<span class="source-line-no">476</span><span id="line-476">        + "' and has been removed from the active " + "coprocessor set.", e);</span>
-<span class="source-line-no">477</span><span id="line-477">    }</span>
-<span class="source-line-no">478</span><span id="line-478">  }</span>
-<span class="source-line-no">479</span><span id="line-479"></span>
-<span class="source-line-no">480</span><span id="line-480">  /**</span>
-<span class="source-line-no">481</span><span id="line-481">   * Used to limit legacy handling to once per Coprocessor class per classloader.</span>
-<span class="source-line-no">482</span><span id="line-482">   */</span>
-<span class="source-line-no">483</span><span id="line-483">  private static final Set&lt;Class&lt;? extends Coprocessor&gt;&gt; legacyWarning =</span>
-<span class="source-line-no">484</span><span id="line-484">    new ConcurrentSkipListSet&lt;&gt;(new Comparator&lt;Class&lt;? extends Coprocessor&gt;&gt;() {</span>
-<span class="source-line-no">485</span><span id="line-485">      @Override</span>
-<span class="source-line-no">486</span><span id="line-486">      public int compare(Class&lt;? extends Coprocessor&gt; c1, Class&lt;? extends Coprocessor&gt; c2) {</span>
-<span class="source-line-no">487</span><span id="line-487">        if (c1.equals(c2)) {</span>
-<span class="source-line-no">488</span><span id="line-488">          return 0;</span>
-<span class="source-line-no">489</span><span id="line-489">        }</span>
-<span class="source-line-no">490</span><span id="line-490">        return c1.getName().compareTo(c2.getName());</span>
-<span class="source-line-no">491</span><span id="line-491">      }</span>
-<span class="source-line-no">492</span><span id="line-492">    });</span>
-<span class="source-line-no">493</span><span id="line-493"></span>
-<span class="source-line-no">494</span><span id="line-494">  /**</span>
-<span class="source-line-no">495</span><span id="line-495">   * Implementations defined function to get an observer of type {@code O} from a coprocessor of</span>
-<span class="source-line-no">496</span><span id="line-496">   * type {@code C}. Concrete implementations of CoprocessorHost define one getter for each observer</span>
-<span class="source-line-no">497</span><span id="line-497">   * they can handle. For e.g. RegionCoprocessorHost will use 3 getters, one for each of</span>
-<span class="source-line-no">498</span><span id="line-498">   * RegionObserver, EndpointObserver and BulkLoadObserver. These getters are used by</span>
-<span class="source-line-no">499</span><span id="line-499">   * {@code ObserverOperation} to get appropriate observer from the coprocessor.</span>
-<span class="source-line-no">500</span><span id="line-500">   */</span>
-<span class="source-line-no">501</span><span id="line-501">  @FunctionalInterface</span>
-<span class="source-line-no">502</span><span id="line-502">  public interface ObserverGetter&lt;C, O&gt; extends Function&lt;C, Optional&lt;O&gt;&gt; {</span>
-<span class="source-line-no">503</span><span id="line-503">  }</span>
-<span class="source-line-no">504</span><span id="line-504"></span>
-<span class="source-line-no">505</span><span id="line-505">  private abstract class ObserverOperation&lt;O&gt; extends ObserverContextImpl&lt;E&gt; {</span>
-<span class="source-line-no">506</span><span id="line-506">    ObserverGetter&lt;C, O&gt; observerGetter;</span>
-<span class="source-line-no">507</span><span id="line-507"></span>
-<span class="source-line-no">508</span><span id="line-508">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
-<span class="source-line-no">509</span><span id="line-509">      this(observerGetter, null);</span>
-<span class="source-line-no">510</span><span id="line-510">    }</span>
-<span class="source-line-no">511</span><span id="line-511"></span>
-<span class="source-line-no">512</span><span id="line-512">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
-<span class="source-line-no">513</span><span id="line-513">      this(observerGetter, user, false);</span>
-<span class="source-line-no">514</span><span id="line-514">    }</span>
-<span class="source-line-no">515</span><span id="line-515"></span>
-<span class="source-line-no">516</span><span id="line-516">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, boolean bypassable) {</span>
-<span class="source-line-no">517</span><span id="line-517">      this(observerGetter, null, bypassable);</span>
-<span class="source-line-no">518</span><span id="line-518">    }</span>
-<span class="source-line-no">519</span><span id="line-519"></span>
-<span class="source-line-no">520</span><span id="line-520">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user, boolean bypassable) {</span>
-<span class="source-line-no">521</span><span id="line-521">      super(user != null ? user : RpcServer.getRequestUser().orElse(null), bypassable);</span>
-<span class="source-line-no">522</span><span id="line-522">      this.observerGetter = observerGetter;</span>
-<span class="source-line-no">523</span><span id="line-523">    }</span>
-<span class="source-line-no">524</span><span id="line-524"></span>
-<span class="source-line-no">525</span><span id="line-525">    abstract void callObserver() throws IOException;</span>
+<span class="source-line-no">132</span><span id="line-132">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">133</span><span id="line-133"></span>
+<span class="source-line-no">134</span><span id="line-134">    // load default coprocessors from configure file</span>
+<span class="source-line-no">135</span><span id="line-135">    String[] defaultCPClasses = conf.getStrings(confKey);</span>
+<span class="source-line-no">136</span><span id="line-136">    if (defaultCPClasses == null || defaultCPClasses.length == 0) return;</span>
+<span class="source-line-no">137</span><span id="line-137"></span>
+<span class="source-line-no">138</span><span id="line-138">    int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;</span>
+<span class="source-line-no">139</span><span id="line-139">    for (String className : defaultCPClasses) {</span>
+<span class="source-line-no">140</span><span id="line-140">      // After HBASE-23710 and HBASE-26714 when configuring for system coprocessor, we accept</span>
+<span class="source-line-no">141</span><span id="line-141">      // an optional format of className|priority|path</span>
+<span class="source-line-no">142</span><span id="line-142">      String[] classNameToken = className.split("\\|");</span>
+<span class="source-line-no">143</span><span id="line-143">      boolean hasPriorityOverride = false;</span>
+<span class="source-line-no">144</span><span id="line-144">      boolean hasPath = false;</span>
+<span class="source-line-no">145</span><span id="line-145">      className = classNameToken[0];</span>
+<span class="source-line-no">146</span><span id="line-146">      int overridePriority = Coprocessor.PRIORITY_SYSTEM;</span>
+<span class="source-line-no">147</span><span id="line-147">      Path path = null;</span>
+<span class="source-line-no">148</span><span id="line-148">      if (classNameToken.length &gt; 1 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[1])) {</span>
+<span class="source-line-no">149</span><span id="line-149">        overridePriority = Integer.parseInt(classNameToken[1]);</span>
+<span class="source-line-no">150</span><span id="line-150">        hasPriorityOverride = true;</span>
+<span class="source-line-no">151</span><span id="line-151">      }</span>
+<span class="source-line-no">152</span><span id="line-152">      if (classNameToken.length &gt; 2 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[2])) {</span>
+<span class="source-line-no">153</span><span id="line-153">        path = new Path(classNameToken[2].trim());</span>
+<span class="source-line-no">154</span><span id="line-154">        hasPath = true;</span>
+<span class="source-line-no">155</span><span id="line-155">      }</span>
+<span class="source-line-no">156</span><span id="line-156">      className = className.trim();</span>
+<span class="source-line-no">157</span><span id="line-157">      if (findCoprocessor(className) != null) {</span>
+<span class="source-line-no">158</span><span id="line-158">        // If already loaded will just continue</span>
+<span class="source-line-no">159</span><span id="line-159">        LOG.warn("Attempted duplicate loading of " + className + "; skipped");</span>
+<span class="source-line-no">160</span><span id="line-160">        continue;</span>
+<span class="source-line-no">161</span><span id="line-161">      }</span>
+<span class="source-line-no">162</span><span id="line-162">      ClassLoader cl = this.getClass().getClassLoader();</span>
+<span class="source-line-no">163</span><span id="line-163">      try {</span>
+<span class="source-line-no">164</span><span id="line-164">        // override the class loader if a path for the system coprocessor is provided.</span>
+<span class="source-line-no">165</span><span id="line-165">        if (hasPath) {</span>
+<span class="source-line-no">166</span><span id="line-166">          cl = CoprocessorClassLoader.getClassLoader(path, this.getClass().getClassLoader(),</span>
+<span class="source-line-no">167</span><span id="line-167">            pathPrefix, conf);</span>
+<span class="source-line-no">168</span><span id="line-168">        }</span>
+<span class="source-line-no">169</span><span id="line-169">        Thread.currentThread().setContextClassLoader(cl);</span>
+<span class="source-line-no">170</span><span id="line-170">        implClass = cl.loadClass(className);</span>
+<span class="source-line-no">171</span><span id="line-171">        int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;</span>
+<span class="source-line-no">172</span><span id="line-172">        // Add coprocessors as we go to guard against case where a coprocessor is specified twice</span>
+<span class="source-line-no">173</span><span id="line-173">        // in the configuration</span>
+<span class="source-line-no">174</span><span id="line-174">        E env = checkAndLoadInstance(implClass, coprocPriority, conf);</span>
+<span class="source-line-no">175</span><span id="line-175">        if (env != null) {</span>
+<span class="source-line-no">176</span><span id="line-176">          this.coprocEnvironments.add(env);</span>
+<span class="source-line-no">177</span><span id="line-177">          LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);</span>
+<span class="source-line-no">178</span><span id="line-178">          if (!hasPriorityOverride) {</span>
+<span class="source-line-no">179</span><span id="line-179">            ++currentSystemPriority;</span>
+<span class="source-line-no">180</span><span id="line-180">          }</span>
+<span class="source-line-no">181</span><span id="line-181">        }</span>
+<span class="source-line-no">182</span><span id="line-182">      } catch (Throwable t) {</span>
+<span class="source-line-no">183</span><span id="line-183">        // We always abort if system coprocessors cannot be loaded</span>
+<span class="source-line-no">184</span><span id="line-184">        abortServer(className, t);</span>
+<span class="source-line-no">185</span><span id="line-185">      }</span>
+<span class="source-line-no">186</span><span id="line-186">    }</span>
+<span class="source-line-no">187</span><span id="line-187">  }</span>
+<span class="source-line-no">188</span><span id="line-188"></span>
+<span class="source-line-no">189</span><span id="line-189">  /**</span>
+<span class="source-line-no">190</span><span id="line-190">   * Load a coprocessor implementation into the host</span>
+<span class="source-line-no">191</span><span id="line-191">   * @param path      path to implementation jar</span>
+<span class="source-line-no">192</span><span id="line-192">   * @param className the main class name</span>
+<span class="source-line-no">193</span><span id="line-193">   * @param priority  chaining priority</span>
+<span class="source-line-no">194</span><span id="line-194">   * @param conf      configuration for coprocessor</span>
+<span class="source-line-no">195</span><span id="line-195">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">196</span><span id="line-196">   */</span>
+<span class="source-line-no">197</span><span id="line-197">  public E load(Path path, String className, int priority, Configuration conf) throws IOException {</span>
+<span class="source-line-no">198</span><span id="line-198">    String[] includedClassPrefixes = null;</span>
+<span class="source-line-no">199</span><span id="line-199">    if (conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY) != null) {</span>
+<span class="source-line-no">200</span><span id="line-200">      String prefixes = conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY);</span>
+<span class="source-line-no">201</span><span id="line-201">      includedClassPrefixes = prefixes.split(";");</span>
+<span class="source-line-no">202</span><span id="line-202">    }</span>
+<span class="source-line-no">203</span><span id="line-203">    return load(path, className, priority, conf, includedClassPrefixes);</span>
+<span class="source-line-no">204</span><span id="line-204">  }</span>
+<span class="source-line-no">205</span><span id="line-205"></span>
+<span class="source-line-no">206</span><span id="line-206">  /**</span>
+<span class="source-line-no">207</span><span id="line-207">   * Load a coprocessor implementation into the host</span>
+<span class="source-line-no">208</span><span id="line-208">   * @param path                  path to implementation jar</span>
+<span class="source-line-no">209</span><span id="line-209">   * @param className             the main class name</span>
+<span class="source-line-no">210</span><span id="line-210">   * @param priority              chaining priority</span>
+<span class="source-line-no">211</span><span id="line-211">   * @param conf                  configuration for coprocessor</span>
+<span class="source-line-no">212</span><span id="line-212">   * @param includedClassPrefixes class name prefixes to include</span>
+<span class="source-line-no">213</span><span id="line-213">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">214</span><span id="line-214">   */</span>
+<span class="source-line-no">215</span><span id="line-215">  public E load(Path path, String className, int priority, Configuration conf,</span>
+<span class="source-line-no">216</span><span id="line-216">    String[] includedClassPrefixes) throws IOException {</span>
+<span class="source-line-no">217</span><span id="line-217">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">218</span><span id="line-218">    LOG.debug("Loading coprocessor class " + className + " with path " + path + " and priority "</span>
+<span class="source-line-no">219</span><span id="line-219">      + priority);</span>
+<span class="source-line-no">220</span><span id="line-220"></span>
+<span class="source-line-no">221</span><span id="line-221">    boolean skipLoadDuplicateCoprocessor = conf.getBoolean(SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR,</span>
+<span class="source-line-no">222</span><span id="line-222">      DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR);</span>
+<span class="source-line-no">223</span><span id="line-223">    if (skipLoadDuplicateCoprocessor &amp;&amp; findCoprocessor(className) != null) {</span>
+<span class="source-line-no">224</span><span id="line-224">      // If already loaded will just continue</span>
+<span class="source-line-no">225</span><span id="line-225">      LOG.warn("Attempted duplicate loading of {}; skipped", className);</span>
+<span class="source-line-no">226</span><span id="line-226">      return null;</span>
+<span class="source-line-no">227</span><span id="line-227">    }</span>
+<span class="source-line-no">228</span><span id="line-228"></span>
+<span class="source-line-no">229</span><span id="line-229">    ClassLoader cl = null;</span>
+<span class="source-line-no">230</span><span id="line-230">    if (path == null) {</span>
+<span class="source-line-no">231</span><span id="line-231">      try {</span>
+<span class="source-line-no">232</span><span id="line-232">        implClass = getClass().getClassLoader().loadClass(className);</span>
+<span class="source-line-no">233</span><span id="line-233">      } catch (ClassNotFoundException e) {</span>
+<span class="source-line-no">234</span><span id="line-234">        throw new IOException("No jar path specified for " + className);</span>
+<span class="source-line-no">235</span><span id="line-235">      }</span>
+<span class="source-line-no">236</span><span id="line-236">    } else {</span>
+<span class="source-line-no">237</span><span id="line-237">      cl =</span>
+<span class="source-line-no">238</span><span id="line-238">        CoprocessorClassLoader.getClassLoader(path, getClass().getClassLoader(), pathPrefix, conf);</span>
+<span class="source-line-no">239</span><span id="line-239">      try {</span>
+<span class="source-line-no">240</span><span id="line-240">        implClass = ((CoprocessorClassLoader) cl).loadClass(className, includedClassPrefixes);</span>
+<span class="source-line-no">241</span><span id="line-241">      } catch (ClassNotFoundException e) {</span>
+<span class="source-line-no">242</span><span id="line-242">        throw new IOException("Cannot load external coprocessor class " + className, e);</span>
+<span class="source-line-no">243</span><span id="line-243">      }</span>
+<span class="source-line-no">244</span><span id="line-244">    }</span>
+<span class="source-line-no">245</span><span id="line-245"></span>
+<span class="source-line-no">246</span><span id="line-246">    // load custom code for coprocessor</span>
+<span class="source-line-no">247</span><span id="line-247">    Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">248</span><span id="line-248">    ClassLoader hostClassLoader = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">249</span><span id="line-249">    try {</span>
+<span class="source-line-no">250</span><span id="line-250">      // switch temporarily to the thread classloader for custom CP</span>
+<span class="source-line-no">251</span><span id="line-251">      currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">252</span><span id="line-252">      E cpInstance = checkAndLoadInstance(implClass, priority, conf);</span>
+<span class="source-line-no">253</span><span id="line-253">      return cpInstance;</span>
+<span class="source-line-no">254</span><span id="line-254">    } finally {</span>
+<span class="source-line-no">255</span><span id="line-255">      // restore the fresh (host) classloader</span>
+<span class="source-line-no">256</span><span id="line-256">      currentThread.setContextClassLoader(hostClassLoader);</span>
+<span class="source-line-no">257</span><span id="line-257">    }</span>
+<span class="source-line-no">258</span><span id="line-258">  }</span>
+<span class="source-line-no">259</span><span id="line-259"></span>
+<span class="source-line-no">260</span><span id="line-260">  public void load(Class&lt;? extends C&gt; implClass, int priority, Configuration conf)</span>
+<span class="source-line-no">261</span><span id="line-261">    throws IOException {</span>
+<span class="source-line-no">262</span><span id="line-262">    E env = checkAndLoadInstance(implClass, priority, conf);</span>
+<span class="source-line-no">263</span><span id="line-263">    coprocEnvironments.add(env);</span>
+<span class="source-line-no">264</span><span id="line-264">  }</span>
+<span class="source-line-no">265</span><span id="line-265"></span>
+<span class="source-line-no">266</span><span id="line-266">  /**</span>
+<span class="source-line-no">267</span><span id="line-267">   * @param implClass Implementation class</span>
+<span class="source-line-no">268</span><span id="line-268">   * @param priority  priority</span>
+<span class="source-line-no">269</span><span id="line-269">   * @param conf      configuration</span>
+<span class="source-line-no">270</span><span id="line-270">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">271</span><span id="line-271">   */</span>
+<span class="source-line-no">272</span><span id="line-272">  public E checkAndLoadInstance(Class&lt;?&gt; implClass, int priority, Configuration conf)</span>
+<span class="source-line-no">273</span><span id="line-273">    throws IOException {</span>
+<span class="source-line-no">274</span><span id="line-274">    // create the instance</span>
+<span class="source-line-no">275</span><span id="line-275">    C impl;</span>
+<span class="source-line-no">276</span><span id="line-276">    try {</span>
+<span class="source-line-no">277</span><span id="line-277">      impl = checkAndGetInstance(implClass);</span>
+<span class="source-line-no">278</span><span id="line-278">      if (impl == null) {</span>
+<span class="source-line-no">279</span><span id="line-279">        LOG.error("Cannot load coprocessor " + implClass.getSimpleName());</span>
+<span class="source-line-no">280</span><span id="line-280">        return null;</span>
+<span class="source-line-no">281</span><span id="line-281">      }</span>
+<span class="source-line-no">282</span><span id="line-282">    } catch (InstantiationException | IllegalAccessException e) {</span>
+<span class="source-line-no">283</span><span id="line-283">      throw new IOException(e);</span>
+<span class="source-line-no">284</span><span id="line-284">    }</span>
+<span class="source-line-no">285</span><span id="line-285">    // create the environment</span>
+<span class="source-line-no">286</span><span id="line-286">    E env = createEnvironment(impl, priority, loadSequence.incrementAndGet(), conf);</span>
+<span class="source-line-no">287</span><span id="line-287">    assert env instanceof BaseEnvironment;</span>
+<span class="source-line-no">288</span><span id="line-288">    ((BaseEnvironment&lt;C&gt;) env).startup();</span>
+<span class="source-line-no">289</span><span id="line-289">    // HBASE-4014: maintain list of loaded coprocessors for later crash analysis</span>
+<span class="source-line-no">290</span><span id="line-290">    // if server (master or regionserver) aborts.</span>
+<span class="source-line-no">291</span><span id="line-291">    coprocessorNames.add(implClass.getName());</span>
+<span class="source-line-no">292</span><span id="line-292">    return env;</span>
+<span class="source-line-no">293</span><span id="line-293">  }</span>
+<span class="source-line-no">294</span><span id="line-294"></span>
+<span class="source-line-no">295</span><span id="line-295">  /**</span>
+<span class="source-line-no">296</span><span id="line-296">   * Called when a new Coprocessor class is loaded</span>
+<span class="source-line-no">297</span><span id="line-297">   */</span>
+<span class="source-line-no">298</span><span id="line-298">  public abstract E createEnvironment(C instance, int priority, int sequence, Configuration conf);</span>
+<span class="source-line-no">299</span><span id="line-299"></span>
+<span class="source-line-no">300</span><span id="line-300">  /**</span>
+<span class="source-line-no">301</span><span id="line-301">   * Called when a new Coprocessor class needs to be loaded. Checks if type of the given class is</span>
+<span class="source-line-no">302</span><span id="line-302">   * what the corresponding host implementation expects. If it is of correct type, returns an</span>
+<span class="source-line-no">303</span><span id="line-303">   * instance of the coprocessor to be loaded. If not, returns null. If an exception occurs when</span>
+<span class="source-line-no">304</span><span id="line-304">   * trying to create instance of a coprocessor, it's passed up and eventually results into server</span>
+<span class="source-line-no">305</span><span id="line-305">   * aborting.</span>
+<span class="source-line-no">306</span><span id="line-306">   */</span>
+<span class="source-line-no">307</span><span id="line-307">  public abstract C checkAndGetInstance(Class&lt;?&gt; implClass)</span>
+<span class="source-line-no">308</span><span id="line-308">    throws InstantiationException, IllegalAccessException;</span>
+<span class="source-line-no">309</span><span id="line-309"></span>
+<span class="source-line-no">310</span><span id="line-310">  public void shutdown(E e) {</span>
+<span class="source-line-no">311</span><span id="line-311">    assert e instanceof BaseEnvironment;</span>
+<span class="source-line-no">312</span><span id="line-312">    if (LOG.isDebugEnabled()) {</span>
+<span class="source-line-no">313</span><span id="line-313">      LOG.debug("Stop coprocessor " + e.getInstance().getClass().getName());</span>
+<span class="source-line-no">314</span><span id="line-314">    }</span>
+<span class="source-line-no">315</span><span id="line-315">    ((BaseEnvironment&lt;C&gt;) e).shutdown();</span>
+<span class="source-line-no">316</span><span id="line-316">  }</span>
+<span class="source-line-no">317</span><span id="line-317"></span>
+<span class="source-line-no">318</span><span id="line-318">  /**</span>
+<span class="source-line-no">319</span><span id="line-319">   * Find coprocessors by full class name or simple name.</span>
+<span class="source-line-no">320</span><span id="line-320">   */</span>
+<span class="source-line-no">321</span><span id="line-321">  public C findCoprocessor(String className) {</span>
+<span class="source-line-no">322</span><span id="line-322">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">323</span><span id="line-323">      if (</span>
+<span class="source-line-no">324</span><span id="line-324">        env.getInstance().getClass().getName().equals(className)</span>
+<span class="source-line-no">325</span><span id="line-325">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
+<span class="source-line-no">326</span><span id="line-326">      ) {</span>
+<span class="source-line-no">327</span><span id="line-327">        return env.getInstance();</span>
+<span class="source-line-no">328</span><span id="line-328">      }</span>
+<span class="source-line-no">329</span><span id="line-329">    }</span>
+<span class="source-line-no">330</span><span id="line-330">    return null;</span>
+<span class="source-line-no">331</span><span id="line-331">  }</span>
+<span class="source-line-no">332</span><span id="line-332"></span>
+<span class="source-line-no">333</span><span id="line-333">  public &lt;T extends C&gt; T findCoprocessor(Class&lt;T&gt; cls) {</span>
+<span class="source-line-no">334</span><span id="line-334">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">335</span><span id="line-335">      if (cls.isAssignableFrom(env.getInstance().getClass())) {</span>
+<span class="source-line-no">336</span><span id="line-336">        return (T) env.getInstance();</span>
+<span class="source-line-no">337</span><span id="line-337">      }</span>
+<span class="source-line-no">338</span><span id="line-338">    }</span>
+<span class="source-line-no">339</span><span id="line-339">    return null;</span>
+<span class="source-line-no">340</span><span id="line-340">  }</span>
+<span class="source-line-no">341</span><span id="line-341"></span>
+<span class="source-line-no">342</span><span id="line-342">  /**</span>
+<span class="source-line-no">343</span><span id="line-343">   * Find list of coprocessors that extend/implement the given class/interface</span>
+<span class="source-line-no">344</span><span id="line-344">   * @param cls the class/interface to look for</span>
+<span class="source-line-no">345</span><span id="line-345">   * @return the list of coprocessors, or null if not found</span>
+<span class="source-line-no">346</span><span id="line-346">   */</span>
+<span class="source-line-no">347</span><span id="line-347">  public &lt;T extends C&gt; List&lt;T&gt; findCoprocessors(Class&lt;T&gt; cls) {</span>
+<span class="source-line-no">348</span><span id="line-348">    ArrayList&lt;T&gt; ret = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">349</span><span id="line-349"></span>
+<span class="source-line-no">350</span><span id="line-350">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">351</span><span id="line-351">      C cp = env.getInstance();</span>
+<span class="source-line-no">352</span><span id="line-352"></span>
+<span class="source-line-no">353</span><span id="line-353">      if (cp != null) {</span>
+<span class="source-line-no">354</span><span id="line-354">        if (cls.isAssignableFrom(cp.getClass())) {</span>
+<span class="source-line-no">355</span><span id="line-355">          ret.add((T) cp);</span>
+<span class="source-line-no">356</span><span id="line-356">        }</span>
+<span class="source-line-no">357</span><span id="line-357">      }</span>
+<span class="source-line-no">358</span><span id="line-358">    }</span>
+<span class="source-line-no">359</span><span id="line-359">    return ret;</span>
+<span class="source-line-no">360</span><span id="line-360">  }</span>
+<span class="source-line-no">361</span><span id="line-361"></span>
+<span class="source-line-no">362</span><span id="line-362">  /**</span>
+<span class="source-line-no">363</span><span id="line-363">   * Find a coprocessor environment by class name</span>
+<span class="source-line-no">364</span><span id="line-364">   * @param className the class name</span>
+<span class="source-line-no">365</span><span id="line-365">   * @return the coprocessor, or null if not found</span>
+<span class="source-line-no">366</span><span id="line-366">   */</span>
+<span class="source-line-no">367</span><span id="line-367">  public E findCoprocessorEnvironment(String className) {</span>
+<span class="source-line-no">368</span><span id="line-368">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">369</span><span id="line-369">      if (</span>
+<span class="source-line-no">370</span><span id="line-370">        env.getInstance().getClass().getName().equals(className)</span>
+<span class="source-line-no">371</span><span id="line-371">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
+<span class="source-line-no">372</span><span id="line-372">      ) {</span>
+<span class="source-line-no">373</span><span id="line-373">        return env;</span>
+<span class="source-line-no">374</span><span id="line-374">      }</span>
+<span class="source-line-no">375</span><span id="line-375">    }</span>
+<span class="source-line-no">376</span><span id="line-376">    return null;</span>
+<span class="source-line-no">377</span><span id="line-377">  }</span>
+<span class="source-line-no">378</span><span id="line-378"></span>
+<span class="source-line-no">379</span><span id="line-379">  /**</span>
+<span class="source-line-no">380</span><span id="line-380">   * Retrieves the set of classloaders used to instantiate Coprocessor classes defined in external</span>
+<span class="source-line-no">381</span><span id="line-381">   * jar files.</span>
+<span class="source-line-no">382</span><span id="line-382">   * @return A set of ClassLoader instances</span>
+<span class="source-line-no">383</span><span id="line-383">   */</span>
+<span class="source-line-no">384</span><span id="line-384">  Set&lt;ClassLoader&gt; getExternalClassLoaders() {</span>
+<span class="source-line-no">385</span><span id="line-385">    Set&lt;ClassLoader&gt; externalClassLoaders = new HashSet&lt;&gt;();</span>
+<span class="source-line-no">386</span><span id="line-386">    final ClassLoader systemClassLoader = this.getClass().getClassLoader();</span>
+<span class="source-line-no">387</span><span id="line-387">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">388</span><span id="line-388">      ClassLoader cl = env.getInstance().getClass().getClassLoader();</span>
+<span class="source-line-no">389</span><span id="line-389">      if (cl != systemClassLoader) {</span>
+<span class="source-line-no">390</span><span id="line-390">        // do not include system classloader</span>
+<span class="source-line-no">391</span><span id="line-391">        externalClassLoaders.add(cl);</span>
+<span class="source-line-no">392</span><span id="line-392">      }</span>
+<span class="source-line-no">393</span><span id="line-393">    }</span>
+<span class="source-line-no">394</span><span id="line-394">    return externalClassLoaders;</span>
+<span class="source-line-no">395</span><span id="line-395">  }</span>
+<span class="source-line-no">396</span><span id="line-396"></span>
+<span class="source-line-no">397</span><span id="line-397">  /**</span>
+<span class="source-line-no">398</span><span id="line-398">   * Environment priority comparator. Coprocessors are chained in sorted order.</span>
+<span class="source-line-no">399</span><span id="line-399">   */</span>
+<span class="source-line-no">400</span><span id="line-400">  static class EnvironmentPriorityComparator implements Comparator&lt;CoprocessorEnvironment&gt; {</span>
+<span class="source-line-no">401</span><span id="line-401">    @Override</span>
+<span class="source-line-no">402</span><span id="line-402">    public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) {</span>
+<span class="source-line-no">403</span><span id="line-403">      if (env1.getPriority() &lt; env2.getPriority()) {</span>
+<span class="source-line-no">404</span><span id="line-404">        return -1;</span>
+<span class="source-line-no">405</span><span id="line-405">      } else if (env1.getPriority() &gt; env2.getPriority()) {</span>
+<span class="source-line-no">406</span><span id="line-406">        return 1;</span>
+<span class="source-line-no">407</span><span id="line-407">      }</span>
+<span class="source-line-no">408</span><span id="line-408">      if (env1.getLoadSequence() &lt; env2.getLoadSequence()) {</span>
+<span class="source-line-no">409</span><span id="line-409">        return -1;</span>
+<span class="source-line-no">410</span><span id="line-410">      } else if (env1.getLoadSequence() &gt; env2.getLoadSequence()) {</span>
+<span class="source-line-no">411</span><span id="line-411">        return 1;</span>
+<span class="source-line-no">412</span><span id="line-412">      }</span>
+<span class="source-line-no">413</span><span id="line-413">      return 0;</span>
+<span class="source-line-no">414</span><span id="line-414">    }</span>
+<span class="source-line-no">415</span><span id="line-415">  }</span>
+<span class="source-line-no">416</span><span id="line-416"></span>
+<span class="source-line-no">417</span><span id="line-417">  protected void abortServer(final E environment, final Throwable e) {</span>
+<span class="source-line-no">418</span><span id="line-418">    abortServer(environment.getInstance().getClass().getName(), e);</span>
+<span class="source-line-no">419</span><span id="line-419">  }</span>
+<span class="source-line-no">420</span><span id="line-420"></span>
+<span class="source-line-no">421</span><span id="line-421">  protected void abortServer(final String coprocessorName, final Throwable e) {</span>
+<span class="source-line-no">422</span><span id="line-422">    String message = "The coprocessor " + coprocessorName + " threw " + e.toString();</span>
+<span class="source-line-no">423</span><span id="line-423">    LOG.error(message, e);</span>
+<span class="source-line-no">424</span><span id="line-424">    if (abortable != null) {</span>
+<span class="source-line-no">425</span><span id="line-425">      abortable.abort(message, e);</span>
+<span class="source-line-no">426</span><span id="line-426">    } else {</span>
+<span class="source-line-no">427</span><span id="line-427">      LOG.warn("No available Abortable, process was not aborted");</span>
+<span class="source-line-no">428</span><span id="line-428">    }</span>
+<span class="source-line-no">429</span><span id="line-429">  }</span>
+<span class="source-line-no">430</span><span id="line-430"></span>
+<span class="source-line-no">431</span><span id="line-431">  /**</span>
+<span class="source-line-no">432</span><span id="line-432">   * This is used by coprocessor hooks which are declared to throw IOException (or its subtypes).</span>
+<span class="source-line-no">433</span><span id="line-433">   * For such hooks, we should handle throwable objects depending on the Throwable's type. Those</span>
+<span class="source-line-no">434</span><span id="line-434">   * which are instances of IOException should be passed on to the client. This is in conformance</span>
+<span class="source-line-no">435</span><span id="line-435">   * with the HBase idiom regarding IOException: that it represents a circumstance that should be</span>
+<span class="source-line-no">436</span><span id="line-436">   * passed along to the client for its own handling. For example, a coprocessor that implements</span>
+<span class="source-line-no">437</span><span id="line-437">   * access controls would throw a subclass of IOException, such as AccessDeniedException, in its</span>
+<span class="source-line-no">438</span><span id="line-438">   * preGet() method to prevent an unauthorized client's performing a Get on a particular table.</span>
+<span class="source-line-no">439</span><span id="line-439">   * @param env Coprocessor Environment</span>
+<span class="source-line-no">440</span><span id="line-440">   * @param e   Throwable object thrown by coprocessor.</span>
+<span class="source-line-no">441</span><span id="line-441">   * @exception IOException Exception</span>
+<span class="source-line-no">442</span><span id="line-442">   */</span>
+<span class="source-line-no">443</span><span id="line-443">  // Note to devs: Class comments of all observers ({@link MasterObserver}, {@link WALObserver},</span>
+<span class="source-line-no">444</span><span id="line-444">  // etc) mention this nuance of our exception handling so that coprocessor can throw appropriate</span>
+<span class="source-line-no">445</span><span id="line-445">  // exceptions depending on situation. If any changes are made to this logic, make sure to</span>
+<span class="source-line-no">446</span><span id="line-446">  // update all classes' comments.</span>
+<span class="source-line-no">447</span><span id="line-447">  protected void handleCoprocessorThrowable(final E env, final Throwable e) throws IOException {</span>
+<span class="source-line-no">448</span><span id="line-448">    if (e instanceof IOException) {</span>
+<span class="source-line-no">449</span><span id="line-449">      throw (IOException) e;</span>
+<span class="source-line-no">450</span><span id="line-450">    }</span>
+<span class="source-line-no">451</span><span id="line-451">    // If we got here, e is not an IOException. A loaded coprocessor has a</span>
+<span class="source-line-no">452</span><span id="line-452">    // fatal bug, and the server (master or regionserver) should remove the</span>
+<span class="source-line-no">453</span><span id="line-453">    // faulty coprocessor from its set of active coprocessors. Setting</span>
+<span class="source-line-no">454</span><span id="line-454">    // 'hbase.coprocessor.abortonerror' to true will cause abortServer(),</span>
+<span class="source-line-no">455</span><span id="line-455">    // which may be useful in development and testing environments where</span>
+<span class="source-line-no">456</span><span id="line-456">    // 'failing fast' for error analysis is desired.</span>
+<span class="source-line-no">457</span><span id="line-457">    if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) {</span>
+<span class="source-line-no">458</span><span id="line-458">      // server is configured to abort.</span>
+<span class="source-line-no">459</span><span id="line-459">      abortServer(env, e);</span>
+<span class="source-line-no">460</span><span id="line-460">    } else {</span>
+<span class="source-line-no">461</span><span id="line-461">      // If available, pull a table name out of the environment</span>
+<span class="source-line-no">462</span><span id="line-462">      if (env instanceof RegionCoprocessorEnvironment) {</span>
+<span class="source-line-no">463</span><span id="line-463">        String tableName =</span>
+<span class="source-line-no">464</span><span id="line-464">          ((RegionCoprocessorEnvironment) env).getRegionInfo().getTable().getNameAsString();</span>
+<span class="source-line-no">465</span><span id="line-465">        LOG.error("Removing coprocessor '" + env.toString() + "' from table '" + tableName + "'",</span>
+<span class="source-line-no">466</span><span id="line-466">          e);</span>
+<span class="source-line-no">467</span><span id="line-467">      } else {</span>
+<span class="source-line-no">468</span><span id="line-468">        LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment", e);</span>
+<span class="source-line-no">469</span><span id="line-469">      }</span>
+<span class="source-line-no">470</span><span id="line-470"></span>
+<span class="source-line-no">471</span><span id="line-471">      coprocEnvironments.remove(env);</span>
+<span class="source-line-no">472</span><span id="line-472">      try {</span>
+<span class="source-line-no">473</span><span id="line-473">        shutdown(env);</span>
+<span class="source-line-no">474</span><span id="line-474">      } catch (Exception x) {</span>
+<span class="source-line-no">475</span><span id="line-475">        LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x);</span>
+<span class="source-line-no">476</span><span id="line-476">      }</span>
+<span class="source-line-no">477</span><span id="line-477">      throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e</span>
+<span class="source-line-no">478</span><span id="line-478">        + "' and has been removed from the active " + "coprocessor set.", e);</span>
+<span class="source-line-no">479</span><span id="line-479">    }</span>
+<span class="source-line-no">480</span><span id="line-480">  }</span>
+<span class="source-line-no">481</span><span id="line-481"></span>
+<span class="source-line-no">482</span><span id="line-482">  /**</span>
+<span class="source-line-no">483</span><span id="line-483">   * Used to limit legacy handling to once per Coprocessor class per classloader.</span>
+<span class="source-line-no">484</span><span id="line-484">   */</span>
+<span class="source-line-no">485</span><span id="line-485">  private static final Set&lt;Class&lt;? extends Coprocessor&gt;&gt; legacyWarning =</span>
+<span class="source-line-no">486</span><span id="line-486">    new ConcurrentSkipListSet&lt;&gt;(new Comparator&lt;Class&lt;? extends Coprocessor&gt;&gt;() {</span>
+<span class="source-line-no">487</span><span id="line-487">      @Override</span>
+<span class="source-line-no">488</span><span id="line-488">      public int compare(Class&lt;? extends Coprocessor&gt; c1, Class&lt;? extends Coprocessor&gt; c2) {</span>
+<span class="source-line-no">489</span><span id="line-489">        if (c1.equals(c2)) {</span>
+<span class="source-line-no">490</span><span id="line-490">          return 0;</span>
+<span class="source-line-no">491</span><span id="line-491">        }</span>
+<span class="source-line-no">492</span><span id="line-492">        return c1.getName().compareTo(c2.getName());</span>
+<span class="source-line-no">493</span><span id="line-493">      }</span>
+<span class="source-line-no">494</span><span id="line-494">    });</span>
+<span class="source-line-no">495</span><span id="line-495"></span>
+<span class="source-line-no">496</span><span id="line-496">  /**</span>
+<span class="source-line-no">497</span><span id="line-497">   * Implementations defined function to get an observer of type {@code O} from a coprocessor of</span>
+<span class="source-line-no">498</span><span id="line-498">   * type {@code C}. Concrete implementations of CoprocessorHost define one getter for each observer</span>
+<span class="source-line-no">499</span><span id="line-499">   * they can handle. For e.g. RegionCoprocessorHost will use 3 getters, one for each of</span>
+<span class="source-line-no">500</span><span id="line-500">   * RegionObserver, EndpointObserver and BulkLoadObserver. These getters are used by</span>
+<span class="source-line-no">501</span><span id="line-501">   * {@code ObserverOperation} to get appropriate observer from the coprocessor.</span>
+<span class="source-line-no">502</span><span id="line-502">   */</span>
+<span class="source-line-no">503</span><span id="line-503">  @FunctionalInterface</span>
+<span class="source-line-no">504</span><span id="line-504">  public interface ObserverGetter&lt;C, O&gt; extends Function&lt;C, Optional&lt;O&gt;&gt; {</span>
+<span class="source-line-no">505</span><span id="line-505">  }</span>
+<span class="source-line-no">506</span><span id="line-506"></span>
+<span class="source-line-no">507</span><span id="line-507">  private abstract class ObserverOperation&lt;O&gt; extends ObserverContextImpl&lt;E&gt; {</span>
+<span class="source-line-no">508</span><span id="line-508">    ObserverGetter&lt;C, O&gt; observerGetter;</span>
+<span class="source-line-no">509</span><span id="line-509"></span>
+<span class="source-line-no">510</span><span id="line-510">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
+<span class="source-line-no">511</span><span id="line-511">      this(observerGetter, null);</span>
+<span class="source-line-no">512</span><span id="line-512">    }</span>
+<span class="source-line-no">513</span><span id="line-513"></span>
+<span class="source-line-no">514</span><span id="line-514">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
+<span class="source-line-no">515</span><span id="line-515">      this(observerGetter, user, false);</span>
+<span class="source-line-no">516</span><span id="line-516">    }</span>
+<span class="source-line-no">517</span><span id="line-517"></span>
+<span class="source-line-no">518</span><span id="line-518">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, boolean bypassable) {</span>
+<span class="source-line-no">519</span><span id="line-519">      this(observerGetter, null, bypassable);</span>
+<span class="source-line-no">520</span><span id="line-520">    }</span>
+<span class="source-line-no">521</span><span id="line-521"></span>
+<span class="source-line-no">522</span><span id="line-522">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user, boolean bypassable) {</span>
+<span class="source-line-no">523</span><span id="line-523">      super(user != null ? user : RpcServer.getRequestUser().orElse(null), bypassable);</span>
+<span class="source-line-no">524</span><span id="line-524">      this.observerGetter = observerGetter;</span>
+<span class="source-line-no">525</span><span id="line-525">    }</span>
 <span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527">    protected void postEnvCall() {</span>
-<span class="source-line-no">528</span><span id="line-528">    }</span>
-<span class="source-line-no">529</span><span id="line-529">  }</span>
-<span class="source-line-no">530</span><span id="line-530"></span>
-<span class="source-line-no">531</span><span id="line-531">  // Can't derive ObserverOperation from ObserverOperationWithResult (R = Void) because then all</span>
-<span class="source-line-no">532</span><span id="line-532">  // ObserverCaller implementations will have to have a return statement.</span>
-<span class="source-line-no">533</span><span id="line-533">  // O = observer, E = environment, C = coprocessor, R=result type</span>
-<span class="source-line-no">534</span><span id="line-534">  public abstract class ObserverOperationWithoutResult&lt;O&gt; extends ObserverOperation&lt;O&gt; {</span>
-<span class="source-line-no">535</span><span id="line-535">    protected abstract void call(O observer) throws IOException;</span>
-<span class="source-line-no">536</span><span id="line-536"></span>
-<span class="source-line-no">537</span><span id="line-537">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
-<span class="source-line-no">538</span><span id="line-538">      super(observerGetter);</span>
-<span class="source-line-no">539</span><span id="line-539">    }</span>
-<span class="source-line-no">540</span><span id="line-540"></span>
-<span class="source-line-no">541</span><span id="line-541">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
-<span class="source-line-no">542</span><span id="line-542">      super(observerGetter, user);</span>
-<span class="source-line-no">543</span><span id="line-543">    }</span>
-<span class="source-line-no">544</span><span id="line-544"></span>
-<span class="source-line-no">545</span><span id="line-545">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user,</span>
-<span class="source-line-no">546</span><span id="line-546">      boolean bypassable) {</span>
-<span class="source-line-no">547</span><span id="line-547">      super(observerGetter, user, bypassable);</span>
-<span class="source-line-no">548</span><span id="line-548">    }</span>
-<span class="source-line-no">549</span><span id="line-549"></span>
-<span class="source-line-no">550</span><span id="line-550">    /**</span>
-<span class="source-line-no">551</span><span id="line-551">     * In case of coprocessors which have many kinds of observers (for eg, {@link RegionCoprocessor}</span>
-<span class="source-line-no">552</span><span id="line-552">     * has BulkLoadObserver, RegionObserver, etc), some implementations may not need all observers,</span>
-<span class="source-line-no">553</span><span id="line-553">     * in which case they will return null for that observer's getter. We simply ignore such cases.</span>
-<span class="source-line-no">554</span><span id="line-554">     */</span>
-<span class="source-line-no">555</span><span id="line-555">    @Override</span>
-<span class="source-line-no">556</span><span id="line-556">    void callObserver() throws IOException {</span>
-<span class="source-line-no">557</span><span id="line-557">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
-<span class="source-line-no">558</span><span id="line-558">      if (observer.isPresent()) {</span>
-<span class="source-line-no">559</span><span id="line-559">        call(observer.get());</span>
-<span class="source-line-no">560</span><span id="line-560">      }</span>
-<span class="source-line-no">561</span><span id="line-561">    }</span>
-<span class="source-line-no">562</span><span id="line-562">  }</span>
-<span class="source-line-no">563</span><span id="line-563"></span>
-<span class="source-line-no">564</span><span id="line-564">  public abstract class ObserverOperationWithResult&lt;O, R&gt; extends ObserverOperation&lt;O&gt; {</span>
-<span class="source-line-no">565</span><span id="line-565">    protected abstract R call(O observer) throws IOException;</span>
-<span class="source-line-no">566</span><span id="line-566"></span>
-<span class="source-line-no">567</span><span id="line-567">    private R result;</span>
+<span class="source-line-no">527</span><span id="line-527">    abstract void callObserver() throws IOException;</span>
+<span class="source-line-no">528</span><span id="line-528"></span>
+<span class="source-line-no">529</span><span id="line-529">    protected void postEnvCall() {</span>
+<span class="source-line-no">530</span><span id="line-530">    }</span>
+<span class="source-line-no">531</span><span id="line-531">  }</span>
+<span class="source-line-no">532</span><span id="line-532"></span>
+<span class="source-line-no">533</span><span id="line-533">  // Can't derive ObserverOperation from ObserverOperationWithResult (R = Void) because then all</span>
+<span class="source-line-no">534</span><span id="line-534">  // ObserverCaller implementations will have to have a return statement.</span>
+<span class="source-line-no">535</span><span id="line-535">  // O = observer, E = environment, C = coprocessor, R=result type</span>
+<span class="source-line-no">536</span><span id="line-536">  public abstract class ObserverOperationWithoutResult&lt;O&gt; extends ObserverOperation&lt;O&gt; {</span>
+<span class="source-line-no">537</span><span id="line-537">    protected abstract void call(O observer) throws IOException;</span>
+<span class="source-line-no">538</span><span id="line-538"></span>
+<span class="source-line-no">539</span><span id="line-539">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
+<span class="source-line-no">540</span><span id="line-540">      super(observerGetter);</span>
+<span class="source-line-no">541</span><span id="line-541">    }</span>
+<span class="source-line-no">542</span><span id="line-542"></span>
+<span class="source-line-no">543</span><span id="line-543">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
+<span class="source-line-no">544</span><span id="line-544">      super(observerGetter, user);</span>
+<span class="source-line-no">545</span><span id="line-545">    }</span>
+<span class="source-line-no">546</span><span id="line-546"></span>
+<span class="source-line-no">547</span><span id="line-547">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user,</span>
+<span class="source-line-no">548</span><span id="line-548">      boolean bypassable) {</span>
+<span class="source-line-no">549</span><span id="line-549">      super(observerGetter, user, bypassable);</span>
+<span class="source-line-no">550</span><span id="line-550">    }</span>
+<span class="source-line-no">551</span><span id="line-551"></span>
+<span class="source-line-no">552</span><span id="line-552">    /**</span>
+<span class="source-line-no">553</span><span id="line-553">     * In case of coprocessors which have many kinds of observers (for eg, {@link RegionCoprocessor}</span>
+<span class="source-line-no">554</span><span id="line-554">     * has BulkLoadObserver, RegionObserver, etc), some implementations may not need all observers,</span>
+<span class="source-line-no">555</span><span id="line-555">     * in which case they will return null for that observer's getter. We simply ignore such cases.</span>
+<span class="source-line-no">556</span><span id="line-556">     */</span>
+<span class="source-line-no">557</span><span id="line-557">    @Override</span>
+<span class="source-line-no">558</span><span id="line-558">    void callObserver() throws IOException {</span>
+<span class="source-line-no">559</span><span id="line-559">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
+<span class="source-line-no">560</span><span id="line-560">      if (observer.isPresent()) {</span>
+<span class="source-line-no">561</span><span id="line-561">        call(observer.get());</span>
+<span class="source-line-no">562</span><span id="line-562">      }</span>
+<span class="source-line-no">563</span><span id="line-563">    }</span>
+<span class="source-line-no">564</span><span id="line-564">  }</span>
+<span class="source-line-no">565</span><span id="line-565"></span>
+<span class="source-line-no">566</span><span id="line-566">  public abstract class ObserverOperationWithResult&lt;O, R&gt; extends ObserverOperation&lt;O&gt; {</span>
+<span class="source-line-no">567</span><span id="line-567">    protected abstract R call(O observer) throws IOException;</span>
 <span class="source-line-no">568</span><span id="line-568"></span>
-<span class="source-line-no">569</span><span id="line-569">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result) {</span>
-<span class="source-line-no">570</span><span id="line-570">      this(observerGetter, result, false);</span>
-<span class="source-line-no">571</span><span id="line-571">    }</span>
-<span class="source-line-no">572</span><span id="line-572"></span>
-<span class="source-line-no">573</span><span id="line-573">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result,</span>
-<span class="source-line-no">574</span><span id="line-574">      boolean bypassable) {</span>
-<span class="source-line-no">575</span><span id="line-575">      this(observerGetter, result, null, bypassable);</span>
-<span class="source-line-no">576</span><span id="line-576">    }</span>
-<span class="source-line-no">577</span><span id="line-577"></span>
-<span class="source-line-no">578</span><span id="line-578">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user) {</span>
-<span class="source-line-no">579</span><span id="line-579">      this(observerGetter, result, user, false);</span>
-<span class="source-line-no">580</span><span id="line-580">    }</span>
-<span class="source-line-no">581</span><span id="line-581"></span>
-<span class="source-line-no">582</span><span id="line-582">    private ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user,</span>
-<span class="source-line-no">583</span><span id="line-583">      boolean bypassable) {</span>
-<span class="source-line-no">584</span><span id="line-584">      super(observerGetter, user, bypassable);</span>
-<span class="source-line-no">585</span><span id="line-585">      this.result = result;</span>
-<span class="source-line-no">586</span><span id="line-586">    }</span>
-<span class="source-line-no">587</span><span id="line-587"></span>
-<span class="source-line-no">588</span><span id="line-588">    protected R getResult() {</span>
-<span class="source-line-no">589</span><span id="line-589">      return this.result;</span>
-<span class="source-line-no">590</span><span id="line-590">    }</span>
-<span class="source-line-no">591</span><span id="line-591"></span>
-<span class="source-line-no">592</span><span id="line-592">    @Override</span>
-<span class="source-line-no">593</span><span id="line-593">    void callObserver() throws IOException {</span>
-<span class="source-line-no">594</span><span id="line-594">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
-<span class="source-line-no">595</span><span id="line-595">      if (observer.isPresent()) {</span>
-<span class="source-line-no">596</span><span id="line-596">        result = call(observer.get());</span>
-<span class="source-line-no">597</span><span id="line-597">      }</span>
-<span class="source-line-no">598</span><span id="line-598">    }</span>
-<span class="source-line-no">599</span><span id="line-599">  }</span>
-<span class="source-line-no">600</span><span id="line-600"></span>
-<span class="source-line-no">601</span><span id="line-601">  //////////////////////////////////////////////////////////////////////////////////////////</span>
-<span class="source-line-no">602</span><span id="line-602">  // Functions to execute observer hooks and handle results (if any)</span>
+<span class="source-line-no">569</span><span id="line-569">    private R result;</span>
+<span class="source-line-no">570</span><span id="line-570"></span>
+<span class="source-line-no">571</span><span id="line-571">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result) {</span>
+<span class="source-line-no">572</span><span id="line-572">      this(observerGetter, result, false);</span>
+<span class="source-line-no">573</span><span id="line-573">    }</span>
+<span class="source-line-no">574</span><span id="line-574"></span>
+<span class="source-line-no">575</span><span id="line-575">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result,</span>
+<span class="source-line-no">576</span><span id="line-576">      boolean bypassable) {</span>
+<span class="source-line-no">577</span><span id="line-577">      this(observerGetter, result, null, bypassable);</span>
+<span class="source-line-no">578</span><span id="line-578">    }</span>
+<span class="source-line-no">579</span><span id="line-579"></span>
+<span class="source-line-no">580</span><span id="line-580">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user) {</span>
+<span class="source-line-no">581</span><span id="line-581">      this(observerGetter, result, user, false);</span>
+<span class="source-line-no">582</span><span id="line-582">    }</span>
+<span class="source-line-no">583</span><span id="line-583"></span>
+<span class="source-line-no">584</span><span id="line-584">    private ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user,</span>
+<span class="source-line-no">585</span><span id="line-585">      boolean bypassable) {</span>
+<span class="source-line-no">586</span><span id="line-586">      super(observerGetter, user, bypassable);</span>
+<span class="source-line-no">587</span><span id="line-587">      this.result = result;</span>
+<span class="source-line-no">588</span><span id="line-588">    }</span>
+<span class="source-line-no">589</span><span id="line-589"></span>
+<span class="source-line-no">590</span><span id="line-590">    protected R getResult() {</span>
+<span class="source-line-no">591</span><span id="line-591">      return this.result;</span>
+<span class="source-line-no">592</span><span id="line-592">    }</span>
+<span class="source-line-no">593</span><span id="line-593"></span>
+<span class="source-line-no">594</span><span id="line-594">    @Override</span>
+<span class="source-line-no">595</span><span id="line-595">    void callObserver() throws IOException {</span>
+<span class="source-line-no">596</span><span id="line-596">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
+<span class="source-line-no">597</span><span id="line-597">      if (observer.isPresent()) {</span>
+<span class="source-line-no">598</span><span id="line-598">        result = call(observer.get());</span>
+<span class="source-line-no">599</span><span id="line-599">      }</span>
+<span class="source-line-no">600</span><span id="line-600">    }</span>
+<span class="source-line-no">601</span><span id="line-601">  }</span>
+<span class="source-line-no">602</span><span id="line-602"></span>
 <span class="source-line-no">603</span><span id="line-603">  //////////////////////////////////////////////////////////////////////////////////////////</span>
-<span class="source-line-no">604</span><span id="line-604"></span>
-<span class="source-line-no">605</span><span id="line-605">  /**</span>
-<span class="source-line-no">606</span><span id="line-606">   * Do not call with an observerOperation that is null! Have the caller check.</span>
-<span class="source-line-no">607</span><span id="line-607">   */</span>
-<span class="source-line-no">608</span><span id="line-608">  protected &lt;O, R&gt; R execOperationWithResult(</span>
-<span class="source-line-no">609</span><span id="line-609">    final ObserverOperationWithResult&lt;O, R&gt; observerOperation) throws IOException {</span>
-<span class="source-line-no">610</span><span id="line-610">    boolean bypass = execOperation(observerOperation);</span>
-<span class="source-line-no">611</span><span id="line-611">    R result = observerOperation.getResult();</span>
-<span class="source-line-no">612</span><span id="line-612">    return bypass == observerOperation.isBypassable() ? result : null;</span>
-<span class="source-line-no">613</span><span id="line-613">  }</span>
-<span class="source-line-no">614</span><span id="line-614"></span>
-<span class="source-line-no">615</span><span id="line-615">  /**</span>
-<span class="source-line-no">616</span><span id="line-616">   * @return True if we are to bypass (Can only be &lt;code&gt;true&lt;/code&gt; if</span>
-<span class="source-line-no">617</span><span id="line-617">   *         ObserverOperation#isBypassable().</span>
-<span class="source-line-no">618</span><span id="line-618">   */</span>
-<span class="source-line-no">619</span><span id="line-619">  protected &lt;O&gt; boolean execOperation(final ObserverOperation&lt;O&gt; observerOperation)</span>
-<span class="source-line-no">620</span><span id="line-620">    throws IOException {</span>
-<span class="source-line-no">621</span><span id="line-621">    boolean bypass = false;</span>
-<span class="source-line-no">622</span><span id="line-622">    if (observerOperation == null) {</span>
-<span class="source-line-no">623</span><span id="line-623">      return bypass;</span>
-<span class="source-line-no">624</span><span id="line-624">    }</span>
-<span class="source-line-no">625</span><span id="line-625">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
-<span class="source-line-no">626</span><span id="line-626">    for (E env : envs) {</span>
-<span class="source-line-no">627</span><span id="line-627">      observerOperation.prepare(env);</span>
-<span class="source-line-no">628</span><span id="line-628">      Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">629</span><span id="line-629">      ClassLoader cl = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">630</span><span id="line-630">      try {</span>
-<span class="source-line-no">631</span><span id="line-631">        currentThread.setContextClassLoader(env.getClassLoader());</span>
-<span class="source-line-no">632</span><span id="line-632">        observerOperation.callObserver();</span>
-<span class="source-line-no">633</span><span id="line-633">      } catch (Throwable e) {</span>
-<span class="source-line-no">634</span><span id="line-634">        handleCoprocessorThrowable(env, e);</span>
-<span class="source-line-no">635</span><span id="line-635">      } finally {</span>
-<span class="source-line-no">636</span><span id="line-636">        currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">637</span><span id="line-637">      }</span>
-<span class="source-line-no">638</span><span id="line-638">      // Internal to shouldBypass, it checks if obeserverOperation#isBypassable().</span>
-<span class="source-line-no">639</span><span id="line-639">      bypass |= observerOperation.shouldBypass();</span>
-<span class="source-line-no">640</span><span id="line-640">      observerOperation.postEnvCall();</span>
-<span class="source-line-no">641</span><span id="line-641">      if (bypass) {</span>
-<span class="source-line-no">642</span><span id="line-642">        // If CP says bypass, skip out w/o calling any following CPs; they might ruin our response.</span>
-<span class="source-line-no">643</span><span id="line-643">        // In hbase1, this used to be called 'complete'. In hbase2, we unite bypass and 'complete'.</span>
-<span class="source-line-no">644</span><span id="line-644">        break;</span>
-<span class="source-line-no">645</span><span id="line-645">      }</span>
-<span class="source-line-no">646</span><span id="line-646">    }</span>
-<span class="source-line-no">647</span><span id="line-647">    return bypass;</span>
-<span class="source-line-no">648</span><span id="line-648">  }</span>
-<span class="source-line-no">649</span><span id="line-649"></span>
-<span class="source-line-no">650</span><span id="line-650">  /**</span>
-<span class="source-line-no">651</span><span id="line-651">   * Coprocessor classes can be configured in any order, based on that priority is set and chained</span>
-<span class="source-line-no">652</span><span id="line-652">   * in a sorted order. Should be used preStop*() hooks i.e. when master/regionserver is going down.</span>
-<span class="source-line-no">653</span><span id="line-653">   * This function first calls coprocessor methods (using ObserverOperation.call()) and then</span>
-<span class="source-line-no">654</span><span id="line-654">   * shutdowns the environment in postEnvCall(). &lt;br&gt;</span>
-<span class="source-line-no">655</span><span id="line-655">   * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors</span>
-<span class="source-line-no">656</span><span id="line-656">   * may remain shutdown if any exception occurs during next coprocessor execution which prevent</span>
-<span class="source-line-no">657</span><span id="line-657">   * master/regionserver stop or cluster shutdown. (Refer:</span>
-<span class="source-line-no">658</span><span id="line-658">   * &lt;a href="https://issues.apache.org/jira/browse/HBASE-16663"&gt;HBASE-16663&lt;/a&gt;</span>
-<span class="source-line-no">659</span><span id="line-659">   * @return true if bypaas coprocessor execution, false if not.</span>
-<span class="source-line-no">660</span><span id="line-660">   */</span>
-<span class="source-line-no">661</span><span id="line-661">  protected &lt;O&gt; boolean execShutdown(final ObserverOperation&lt;O&gt; observerOperation)</span>
-<span class="source-line-no">662</span><span id="line-662">    throws IOException {</span>
-<span class="source-line-no">663</span><span id="line-663">    if (observerOperation == null) return false;</span>
-<span class="source-line-no">664</span><span id="line-664">    boolean bypass = false;</span>
-<span class="source-line-no">665</span><span id="line-665">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
-<span class="source-line-no">666</span><span id="line-666">    // Iterate the coprocessors and execute ObserverOperation's call()</span>
-<span class="source-line-no">667</span><span id="line-667">    for (E env : envs) {</span>
-<span class="source-line-no">668</span><span id="line-668">      observerOperation.prepare(env);</span>
-<span class="source-line-no">669</span><span id="line-669">      Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">670</span><span id="line-670">      ClassLoader cl = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">671</span><span id="line-671">      try {</span>
-<span class="source-line-no">672</span><span id="line-672">        currentThread.setContextClassLoader(env.getClassLoader());</span>
-<span class="source-line-no">673</span><span id="line-673">        observerOperation.callObserver();</span>
-<span class="source-line-no">674</span><span id="line-674">      } catch (Throwable e) {</span>
-<span class="source-line-no">675</span><span id="line-675">        handleCoprocessorThrowable(env, e);</span>
-<span class="source-line-no">676</span><span id="line-676">      } finally {</span>
-<span class="source-line-no">677</span><span id="line-677">        currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">678</span><span id="line-678">      }</span>
-<span class="source-line-no">679</span><span id="line-679">      bypass |= observerOperation.shouldBypass();</span>
-<span class="source-line-no">680</span><span id="line-680">    }</span>
-<span class="source-line-no">681</span><span id="line-681"></span>
-<span class="source-line-no">682</span><span id="line-682">    // Iterate the coprocessors and execute ObserverOperation's postEnvCall()</span>
-<span class="source-line-no">683</span><span id="line-683">    for (E env : envs) {</span>
-<span class="source-line-no">684</span><span id="line-684">      observerOperation.prepare(env);</span>
-<span class="source-line-no">685</span><span id="line-685">      observerOperation.postEnvCall();</span>
-<span class="source-line-no">686</span><span id="line-686">    }</span>
-<span class="source-line-no">687</span><span id="line-687">    return bypass;</span>
-<span class="source-line-no">688</span><span id="line-688">  }</span>
-<span class="source-line-no">689</span><span id="line-689">}</span>
+<span class="source-line-no">604</span><span id="line-604">  // Functions to execute observer hooks and handle results (if any)</span>
+<span class="source-line-no">605</span><span id="line-605">  //////////////////////////////////////////////////////////////////////////////////////////</span>
+<span class="source-line-no">606</span><span id="line-606"></span>
+<span class="source-line-no">607</span><span id="line-607">  /**</span>
+<span class="source-line-no">608</span><span id="line-608">   * Do not call with an observerOperation that is null! Have the caller check.</span>
+<span class="source-line-no">609</span><span id="line-609">   */</span>
+<span class="source-line-no">610</span><span id="line-610">  protected &lt;O, R&gt; R execOperationWithResult(</span>
+<span class="source-line-no">611</span><span id="line-611">    final ObserverOperationWithResult&lt;O, R&gt; observerOperation) throws IOException {</span>
+<span class="source-line-no">612</span><span id="line-612">    boolean bypass = execOperation(observerOperation);</span>
+<span class="source-line-no">613</span><span id="line-613">    R result = observerOperation.getResult();</span>
+<span class="source-line-no">614</span><span id="line-614">    return bypass == observerOperation.isBypassable() ? result : null;</span>
+<span class="source-line-no">615</span><span id="line-615">  }</span>
+<span class="source-line-no">616</span><span id="line-616"></span>
+<span class="source-line-no">617</span><span id="line-617">  /**</span>
+<span class="source-line-no">618</span><span id="line-618">   * @return True if we are to bypass (Can only be &lt;code&gt;true&lt;/code&gt; if</span>
+<span class="source-line-no">619</span><span id="line-619">   *         ObserverOperation#isBypassable().</span>
+<span class="source-line-no">620</span><span id="line-620">   */</span>
+<span class="source-line-no">621</span><span id="line-621">  protected &lt;O&gt; boolean execOperation(final ObserverOperation&lt;O&gt; observerOperation)</span>
+<span class="source-line-no">622</span><span id="line-622">    throws IOException {</span>
+<span class="source-line-no">623</span><span id="line-623">    boolean bypass = false;</span>
+<span class="source-line-no">624</span><span id="line-624">    if (observerOperation == null) {</span>
+<span class="source-line-no">625</span><span id="line-625">      return bypass;</span>
+<span class="source-line-no">626</span><span id="line-626">    }</span>
+<span class="source-line-no">627</span><span id="line-627">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
+<span class="source-line-no">628</span><span id="line-628">    for (E env : envs) {</span>
+<span class="source-line-no">629</span><span id="line-629">      observerOperation.prepare(env);</span>
+<span class="source-line-no">630</span><span id="line-630">      Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">631</span><span id="line-631">      ClassLoader cl = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">632</span><span id="line-632">      try {</span>
+<span class="source-line-no">633</span><span id="line-633">        currentThread.setContextClassLoader(env.getClassLoader());</span>
+<span class="source-line-no">634</span><span id="line-634">        observerOperation.callObserver();</span>
+<span class="source-line-no">635</span><span id="line-635">      } catch (Throwable e) {</span>
+<span class="source-line-no">636</span><span id="line-636">        handleCoprocessorThrowable(env, e);</span>
+<span class="source-line-no">637</span><span id="line-637">      } finally {</span>
+<span class="source-line-no">638</span><span id="line-638">        currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">639</span><span id="line-639">      }</span>
+<span class="source-line-no">640</span><span id="line-640">      // Internal to shouldBypass, it checks if obeserverOperation#isBypassable().</span>
+<span class="source-line-no">641</span><span id="line-641">      bypass |= observerOperation.shouldBypass();</span>
+<span class="source-line-no">642</span><span id="line-642">      observerOperation.postEnvCall();</span>
+<span class="source-line-no">643</span><span id="line-643">      if (bypass) {</span>
+<span class="source-line-no">644</span><span id="line-644">        // If CP says bypass, skip out w/o calling any following CPs; they might ruin our response.</span>
+<span class="source-line-no">645</span><span id="line-645">        // In hbase1, this used to be called 'complete'. In hbase2, we unite bypass and 'complete'.</span>
+<span class="source-line-no">646</span><span id="line-646">        break;</span>
+<span class="source-line-no">647</span><span id="line-647">      }</span>
+<span class="source-line-no">648</span><span id="line-648">    }</span>
+<span class="source-line-no">649</span><span id="line-649">    return bypass;</span>
+<span class="source-line-no">650</span><span id="line-650">  }</span>
+<span class="source-line-no">651</span><span id="line-651"></span>
+<span class="source-line-no">652</span><span id="line-652">  /**</span>
+<span class="source-line-no">653</span><span id="line-653">   * Coprocessor classes can be configured in any order, based on that priority is set and chained</span>
+<span class="source-line-no">654</span><span id="line-654">   * in a sorted order. Should be used preStop*() hooks i.e. when master/regionserver is going down.</span>
+<span class="source-line-no">655</span><span id="line-655">   * This function first calls coprocessor methods (using ObserverOperation.call()) and then</span>
+<span class="source-line-no">656</span><span id="line-656">   * shutdowns the environment in postEnvCall(). &lt;br&gt;</span>
+<span class="source-line-no">657</span><span id="line-657">   * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors</span>
+<span class="source-line-no">658</span><span id="line-658">   * may remain shutdown if any exception occurs during next coprocessor execution which prevent</span>
+<span class="source-line-no">659</span><span id="line-659">   * master/regionserver stop or cluster shutdown. (Refer:</span>
+<span class="source-line-no">660</span><span id="line-660">   * &lt;a href="https://issues.apache.org/jira/browse/HBASE-16663"&gt;HBASE-16663&lt;/a&gt;</span>
+<span class="source-line-no">661</span><span id="line-661">   * @return true if bypaas coprocessor execution, false if not.</span>
+<span class="source-line-no">662</span><span id="line-662">   */</span>
+<span class="source-line-no">663</span><span id="line-663">  protected &lt;O&gt; boolean execShutdown(final ObserverOperation&lt;O&gt; observerOperation)</span>
+<span class="source-line-no">664</span><span id="line-664">    throws IOException {</span>
+<span class="source-line-no">665</span><span id="line-665">    if (observerOperation == null) return false;</span>
+<span class="source-line-no">666</span><span id="line-666">    boolean bypass = false;</span>
+<span class="source-line-no">667</span><span id="line-667">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
+<span class="source-line-no">668</span><span id="line-668">    // Iterate the coprocessors and execute ObserverOperation's call()</span>
+<span class="source-line-no">669</span><span id="line-669">    for (E env : envs) {</span>
+<span class="source-line-no">670</span><span id="line-670">      observerOperation.prepare(env);</span>
+<span class="source-line-no">671</span><span id="line-671">      Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">672</span><span id="line-672">      ClassLoader cl = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">673</span><span id="line-673">      try {</span>
+<span class="source-line-no">674</span><span id="line-674">        currentThread.setContextClassLoader(env.getClassLoader());</span>
+<span class="source-line-no">675</span><span id="line-675">        observerOperation.callObserver();</span>
+<span class="source-line-no">676</span><span id="line-676">      } catch (Throwable e) {</span>
+<span class="source-line-no">677</span><span id="line-677">        handleCoprocessorThrowable(env, e);</span>
+<span class="source-line-no">678</span><span id="line-678">      } finally {</span>
+<span class="source-line-no">679</span><span id="line-679">        currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">680</span><span id="line-680">      }</span>
+<span class="source-line-no">681</span><span id="line-681">      bypass |= observerOperation.shouldBypass();</span>
+<span class="source-line-no">682</span><span id="line-682">    }</span>
+<span class="source-line-no">683</span><span id="line-683"></span>
+<span class="source-line-no">684</span><span id="line-684">    // Iterate the coprocessors and execute ObserverOperation's postEnvCall()</span>
+<span class="source-line-no">685</span><span id="line-685">    for (E env : envs) {</span>
+<span class="source-line-no">686</span><span id="line-686">      observerOperation.prepare(env);</span>
+<span class="source-line-no">687</span><span id="line-687">      observerOperation.postEnvCall();</span>
+<span class="source-line-no">688</span><span id="line-688">    }</span>
+<span class="source-line-no">689</span><span id="line-689">    return bypass;</span>
+<span class="source-line-no">690</span><span id="line-690">  }</span>
+<span class="source-line-no">691</span><span id="line-691">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.html b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.html
index 9a3f6440d81..10a8137276a 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.html
@@ -74,632 +74,634 @@
 <span class="source-line-no">061</span><span id="line-61">  public static final String USER_REGION_COPROCESSOR_CONF_KEY =</span>
 <span class="source-line-no">062</span><span id="line-62">    "hbase.coprocessor.user.region.classes";</span>
 <span class="source-line-no">063</span><span id="line-63">  public static final String MASTER_COPROCESSOR_CONF_KEY = "hbase.coprocessor.master.classes";</span>
-<span class="source-line-no">064</span><span id="line-64">  public static final String WAL_COPROCESSOR_CONF_KEY = "hbase.coprocessor.wal.classes";</span>
-<span class="source-line-no">065</span><span id="line-65">  public static final String RPC_COPROCESSOR_CONF_KEY = "hbase.coprocessor.rpc.classes";</span>
-<span class="source-line-no">066</span><span id="line-66">  public static final String ABORT_ON_ERROR_KEY = "hbase.coprocessor.abortonerror";</span>
-<span class="source-line-no">067</span><span id="line-67">  public static final boolean DEFAULT_ABORT_ON_ERROR = true;</span>
-<span class="source-line-no">068</span><span id="line-68">  public static final String COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.enabled";</span>
-<span class="source-line-no">069</span><span id="line-69">  public static final boolean DEFAULT_COPROCESSORS_ENABLED = true;</span>
-<span class="source-line-no">070</span><span id="line-70">  public static final String USER_COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.user.enabled";</span>
-<span class="source-line-no">071</span><span id="line-71">  public static final boolean DEFAULT_USER_COPROCESSORS_ENABLED = true;</span>
-<span class="source-line-no">072</span><span id="line-72">  public static final String SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR =</span>
-<span class="source-line-no">073</span><span id="line-73">    "hbase.skip.load.duplicate.table.coprocessor";</span>
-<span class="source-line-no">074</span><span id="line-74">  public static final boolean DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR = false;</span>
-<span class="source-line-no">075</span><span id="line-75"></span>
-<span class="source-line-no">076</span><span id="line-76">  private static final Logger LOG = LoggerFactory.getLogger(CoprocessorHost.class);</span>
-<span class="source-line-no">077</span><span id="line-77">  protected Abortable abortable;</span>
-<span class="source-line-no">078</span><span id="line-78">  /** Ordered set of loaded coprocessors with lock */</span>
-<span class="source-line-no">079</span><span id="line-79">  protected final SortedList&lt;E&gt; coprocEnvironments =</span>
-<span class="source-line-no">080</span><span id="line-80">    new SortedList&lt;&gt;(new EnvironmentPriorityComparator());</span>
-<span class="source-line-no">081</span><span id="line-81">  protected Configuration conf;</span>
-<span class="source-line-no">082</span><span id="line-82">  // unique file prefix to use for local copies of jars when classloading</span>
-<span class="source-line-no">083</span><span id="line-83">  protected String pathPrefix;</span>
-<span class="source-line-no">084</span><span id="line-84">  protected AtomicInteger loadSequence = new AtomicInteger();</span>
-<span class="source-line-no">085</span><span id="line-85"></span>
-<span class="source-line-no">086</span><span id="line-86">  public CoprocessorHost(Abortable abortable) {</span>
-<span class="source-line-no">087</span><span id="line-87">    this.abortable = abortable;</span>
-<span class="source-line-no">088</span><span id="line-88">    this.pathPrefix = UUID.randomUUID().toString();</span>
-<span class="source-line-no">089</span><span id="line-89">  }</span>
-<span class="source-line-no">090</span><span id="line-90"></span>
-<span class="source-line-no">091</span><span id="line-91">  /**</span>
-<span class="source-line-no">092</span><span id="line-92">   * Not to be confused with the per-object _coprocessors_ (above), coprocessorNames is static and</span>
-<span class="source-line-no">093</span><span id="line-93">   * stores the set of all coprocessors ever loaded by any thread in this JVM. It is strictly</span>
-<span class="source-line-no">094</span><span id="line-94">   * additive: coprocessors are added to coprocessorNames, by checkAndLoadInstance() but are never</span>
-<span class="source-line-no">095</span><span id="line-95">   * removed, since the intention is to preserve a history of all loaded coprocessors for diagnosis</span>
-<span class="source-line-no">096</span><span id="line-96">   * in case of server crash (HBASE-4014).</span>
-<span class="source-line-no">097</span><span id="line-97">   */</span>
-<span class="source-line-no">098</span><span id="line-98">  private static Set&lt;String&gt; coprocessorNames = Collections.synchronizedSet(new HashSet&lt;String&gt;());</span>
-<span class="source-line-no">099</span><span id="line-99"></span>
-<span class="source-line-no">100</span><span id="line-100">  public static Set&lt;String&gt; getLoadedCoprocessors() {</span>
-<span class="source-line-no">101</span><span id="line-101">    synchronized (coprocessorNames) {</span>
-<span class="source-line-no">102</span><span id="line-102">      return new HashSet(coprocessorNames);</span>
-<span class="source-line-no">103</span><span id="line-103">    }</span>
-<span class="source-line-no">104</span><span id="line-104">  }</span>
-<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106">  /**</span>
-<span class="source-line-no">107</span><span id="line-107">   * Used to create a parameter to the HServerLoad constructor so that HServerLoad can provide</span>
-<span class="source-line-no">108</span><span id="line-108">   * information about the coprocessors loaded by this regionserver. (HBASE-4070: Improve region</span>
-<span class="source-line-no">109</span><span id="line-109">   * server metrics to report loaded coprocessors to master).</span>
-<span class="source-line-no">110</span><span id="line-110">   */</span>
-<span class="source-line-no">111</span><span id="line-111">  public Set&lt;String&gt; getCoprocessors() {</span>
-<span class="source-line-no">112</span><span id="line-112">    Set&lt;String&gt; returnValue = new TreeSet&lt;&gt;();</span>
-<span class="source-line-no">113</span><span id="line-113">    for (E e : coprocEnvironments) {</span>
-<span class="source-line-no">114</span><span id="line-114">      returnValue.add(e.getInstance().getClass().getSimpleName());</span>
-<span class="source-line-no">115</span><span id="line-115">    }</span>
-<span class="source-line-no">116</span><span id="line-116">    return returnValue;</span>
-<span class="source-line-no">117</span><span id="line-117">  }</span>
-<span class="source-line-no">118</span><span id="line-118"></span>
-<span class="source-line-no">119</span><span id="line-119">  /**</span>
-<span class="source-line-no">120</span><span id="line-120">   * Load system coprocessors once only. Read the class names from configuration. Called by</span>
-<span class="source-line-no">121</span><span id="line-121">   * constructor.</span>
-<span class="source-line-no">122</span><span id="line-122">   */</span>
-<span class="source-line-no">123</span><span id="line-123">  protected void loadSystemCoprocessors(Configuration conf, String confKey) {</span>
-<span class="source-line-no">124</span><span id="line-124">    boolean coprocessorsEnabled =</span>
-<span class="source-line-no">125</span><span id="line-125">      conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, DEFAULT_COPROCESSORS_ENABLED);</span>
-<span class="source-line-no">126</span><span id="line-126">    if (!coprocessorsEnabled) {</span>
-<span class="source-line-no">127</span><span id="line-127">      return;</span>
-<span class="source-line-no">128</span><span id="line-128">    }</span>
-<span class="source-line-no">129</span><span id="line-129"></span>
-<span class="source-line-no">130</span><span id="line-130">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">064</span><span id="line-64">  public static final String CLIENT_META_COPROCESSOR_CONF_KEY =</span>
+<span class="source-line-no">065</span><span id="line-65">    "hbase.coprocessor.clientmeta.classes";</span>
+<span class="source-line-no">066</span><span id="line-66">  public static final String WAL_COPROCESSOR_CONF_KEY = "hbase.coprocessor.wal.classes";</span>
+<span class="source-line-no">067</span><span id="line-67">  public static final String RPC_COPROCESSOR_CONF_KEY = "hbase.coprocessor.rpc.classes";</span>
+<span class="source-line-no">068</span><span id="line-68">  public static final String ABORT_ON_ERROR_KEY = "hbase.coprocessor.abortonerror";</span>
+<span class="source-line-no">069</span><span id="line-69">  public static final boolean DEFAULT_ABORT_ON_ERROR = true;</span>
+<span class="source-line-no">070</span><span id="line-70">  public static final String COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.enabled";</span>
+<span class="source-line-no">071</span><span id="line-71">  public static final boolean DEFAULT_COPROCESSORS_ENABLED = true;</span>
+<span class="source-line-no">072</span><span id="line-72">  public static final String USER_COPROCESSORS_ENABLED_CONF_KEY = "hbase.coprocessor.user.enabled";</span>
+<span class="source-line-no">073</span><span id="line-73">  public static final boolean DEFAULT_USER_COPROCESSORS_ENABLED = true;</span>
+<span class="source-line-no">074</span><span id="line-74">  public static final String SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR =</span>
+<span class="source-line-no">075</span><span id="line-75">    "hbase.skip.load.duplicate.table.coprocessor";</span>
+<span class="source-line-no">076</span><span id="line-76">  public static final boolean DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR = false;</span>
+<span class="source-line-no">077</span><span id="line-77"></span>
+<span class="source-line-no">078</span><span id="line-78">  private static final Logger LOG = LoggerFactory.getLogger(CoprocessorHost.class);</span>
+<span class="source-line-no">079</span><span id="line-79">  protected Abortable abortable;</span>
+<span class="source-line-no">080</span><span id="line-80">  /** Ordered set of loaded coprocessors with lock */</span>
+<span class="source-line-no">081</span><span id="line-81">  protected final SortedList&lt;E&gt; coprocEnvironments =</span>
+<span class="source-line-no">082</span><span id="line-82">    new SortedList&lt;&gt;(new EnvironmentPriorityComparator());</span>
+<span class="source-line-no">083</span><span id="line-83">  protected Configuration conf;</span>
+<span class="source-line-no">084</span><span id="line-84">  // unique file prefix to use for local copies of jars when classloading</span>
+<span class="source-line-no">085</span><span id="line-85">  protected String pathPrefix;</span>
+<span class="source-line-no">086</span><span id="line-86">  protected AtomicInteger loadSequence = new AtomicInteger();</span>
+<span class="source-line-no">087</span><span id="line-87"></span>
+<span class="source-line-no">088</span><span id="line-88">  public CoprocessorHost(Abortable abortable) {</span>
+<span class="source-line-no">089</span><span id="line-89">    this.abortable = abortable;</span>
+<span class="source-line-no">090</span><span id="line-90">    this.pathPrefix = UUID.randomUUID().toString();</span>
+<span class="source-line-no">091</span><span id="line-91">  }</span>
+<span class="source-line-no">092</span><span id="line-92"></span>
+<span class="source-line-no">093</span><span id="line-93">  /**</span>
+<span class="source-line-no">094</span><span id="line-94">   * Not to be confused with the per-object _coprocessors_ (above), coprocessorNames is static and</span>
+<span class="source-line-no">095</span><span id="line-95">   * stores the set of all coprocessors ever loaded by any thread in this JVM. It is strictly</span>
+<span class="source-line-no">096</span><span id="line-96">   * additive: coprocessors are added to coprocessorNames, by checkAndLoadInstance() but are never</span>
+<span class="source-line-no">097</span><span id="line-97">   * removed, since the intention is to preserve a history of all loaded coprocessors for diagnosis</span>
+<span class="source-line-no">098</span><span id="line-98">   * in case of server crash (HBASE-4014).</span>
+<span class="source-line-no">099</span><span id="line-99">   */</span>
+<span class="source-line-no">100</span><span id="line-100">  private static Set&lt;String&gt; coprocessorNames = Collections.synchronizedSet(new HashSet&lt;String&gt;());</span>
+<span class="source-line-no">101</span><span id="line-101"></span>
+<span class="source-line-no">102</span><span id="line-102">  public static Set&lt;String&gt; getLoadedCoprocessors() {</span>
+<span class="source-line-no">103</span><span id="line-103">    synchronized (coprocessorNames) {</span>
+<span class="source-line-no">104</span><span id="line-104">      return new HashSet(coprocessorNames);</span>
+<span class="source-line-no">105</span><span id="line-105">    }</span>
+<span class="source-line-no">106</span><span id="line-106">  }</span>
+<span class="source-line-no">107</span><span id="line-107"></span>
+<span class="source-line-no">108</span><span id="line-108">  /**</span>
+<span class="source-line-no">109</span><span id="line-109">   * Used to create a parameter to the HServerLoad constructor so that HServerLoad can provide</span>
+<span class="source-line-no">110</span><span id="line-110">   * information about the coprocessors loaded by this regionserver. (HBASE-4070: Improve region</span>
+<span class="source-line-no">111</span><span id="line-111">   * server metrics to report loaded coprocessors to master).</span>
+<span class="source-line-no">112</span><span id="line-112">   */</span>
+<span class="source-line-no">113</span><span id="line-113">  public Set&lt;String&gt; getCoprocessors() {</span>
+<span class="source-line-no">114</span><span id="line-114">    Set&lt;String&gt; returnValue = new TreeSet&lt;&gt;();</span>
+<span class="source-line-no">115</span><span id="line-115">    for (E e : coprocEnvironments) {</span>
+<span class="source-line-no">116</span><span id="line-116">      returnValue.add(e.getInstance().getClass().getSimpleName());</span>
+<span class="source-line-no">117</span><span id="line-117">    }</span>
+<span class="source-line-no">118</span><span id="line-118">    return returnValue;</span>
+<span class="source-line-no">119</span><span id="line-119">  }</span>
+<span class="source-line-no">120</span><span id="line-120"></span>
+<span class="source-line-no">121</span><span id="line-121">  /**</span>
+<span class="source-line-no">122</span><span id="line-122">   * Load system coprocessors once only. Read the class names from configuration. Called by</span>
+<span class="source-line-no">123</span><span id="line-123">   * constructor.</span>
+<span class="source-line-no">124</span><span id="line-124">   */</span>
+<span class="source-line-no">125</span><span id="line-125">  protected void loadSystemCoprocessors(Configuration conf, String confKey) {</span>
+<span class="source-line-no">126</span><span id="line-126">    boolean coprocessorsEnabled =</span>
+<span class="source-line-no">127</span><span id="line-127">      conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, DEFAULT_COPROCESSORS_ENABLED);</span>
+<span class="source-line-no">128</span><span id="line-128">    if (!coprocessorsEnabled) {</span>
+<span class="source-line-no">129</span><span id="line-129">      return;</span>
+<span class="source-line-no">130</span><span id="line-130">    }</span>
 <span class="source-line-no">131</span><span id="line-131"></span>
-<span class="source-line-no">132</span><span id="line-132">    // load default coprocessors from configure file</span>
-<span class="source-line-no">133</span><span id="line-133">    String[] defaultCPClasses = conf.getStrings(confKey);</span>
-<span class="source-line-no">134</span><span id="line-134">    if (defaultCPClasses == null || defaultCPClasses.length == 0) return;</span>
-<span class="source-line-no">135</span><span id="line-135"></span>
-<span class="source-line-no">136</span><span id="line-136">    int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;</span>
-<span class="source-line-no">137</span><span id="line-137">    for (String className : defaultCPClasses) {</span>
-<span class="source-line-no">138</span><span id="line-138">      // After HBASE-23710 and HBASE-26714 when configuring for system coprocessor, we accept</span>
-<span class="source-line-no">139</span><span id="line-139">      // an optional format of className|priority|path</span>
-<span class="source-line-no">140</span><span id="line-140">      String[] classNameToken = className.split("\\|");</span>
-<span class="source-line-no">141</span><span id="line-141">      boolean hasPriorityOverride = false;</span>
-<span class="source-line-no">142</span><span id="line-142">      boolean hasPath = false;</span>
-<span class="source-line-no">143</span><span id="line-143">      className = classNameToken[0];</span>
-<span class="source-line-no">144</span><span id="line-144">      int overridePriority = Coprocessor.PRIORITY_SYSTEM;</span>
-<span class="source-line-no">145</span><span id="line-145">      Path path = null;</span>
-<span class="source-line-no">146</span><span id="line-146">      if (classNameToken.length &gt; 1 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[1])) {</span>
-<span class="source-line-no">147</span><span id="line-147">        overridePriority = Integer.parseInt(classNameToken[1]);</span>
-<span class="source-line-no">148</span><span id="line-148">        hasPriorityOverride = true;</span>
-<span class="source-line-no">149</span><span id="line-149">      }</span>
-<span class="source-line-no">150</span><span id="line-150">      if (classNameToken.length &gt; 2 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[2])) {</span>
-<span class="source-line-no">151</span><span id="line-151">        path = new Path(classNameToken[2].trim());</span>
-<span class="source-line-no">152</span><span id="line-152">        hasPath = true;</span>
-<span class="source-line-no">153</span><span id="line-153">      }</span>
-<span class="source-line-no">154</span><span id="line-154">      className = className.trim();</span>
-<span class="source-line-no">155</span><span id="line-155">      if (findCoprocessor(className) != null) {</span>
-<span class="source-line-no">156</span><span id="line-156">        // If already loaded will just continue</span>
-<span class="source-line-no">157</span><span id="line-157">        LOG.warn("Attempted duplicate loading of " + className + "; skipped");</span>
-<span class="source-line-no">158</span><span id="line-158">        continue;</span>
-<span class="source-line-no">159</span><span id="line-159">      }</span>
-<span class="source-line-no">160</span><span id="line-160">      ClassLoader cl = this.getClass().getClassLoader();</span>
-<span class="source-line-no">161</span><span id="line-161">      try {</span>
-<span class="source-line-no">162</span><span id="line-162">        // override the class loader if a path for the system coprocessor is provided.</span>
-<span class="source-line-no">163</span><span id="line-163">        if (hasPath) {</span>
-<span class="source-line-no">164</span><span id="line-164">          cl = CoprocessorClassLoader.getClassLoader(path, this.getClass().getClassLoader(),</span>
-<span class="source-line-no">165</span><span id="line-165">            pathPrefix, conf);</span>
-<span class="source-line-no">166</span><span id="line-166">        }</span>
-<span class="source-line-no">167</span><span id="line-167">        Thread.currentThread().setContextClassLoader(cl);</span>
-<span class="source-line-no">168</span><span id="line-168">        implClass = cl.loadClass(className);</span>
-<span class="source-line-no">169</span><span id="line-169">        int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;</span>
-<span class="source-line-no">170</span><span id="line-170">        // Add coprocessors as we go to guard against case where a coprocessor is specified twice</span>
-<span class="source-line-no">171</span><span id="line-171">        // in the configuration</span>
-<span class="source-line-no">172</span><span id="line-172">        E env = checkAndLoadInstance(implClass, coprocPriority, conf);</span>
-<span class="source-line-no">173</span><span id="line-173">        if (env != null) {</span>
-<span class="source-line-no">174</span><span id="line-174">          this.coprocEnvironments.add(env);</span>
-<span class="source-line-no">175</span><span id="line-175">          LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);</span>
-<span class="source-line-no">176</span><span id="line-176">          if (!hasPriorityOverride) {</span>
-<span class="source-line-no">177</span><span id="line-177">            ++currentSystemPriority;</span>
-<span class="source-line-no">178</span><span id="line-178">          }</span>
-<span class="source-line-no">179</span><span id="line-179">        }</span>
-<span class="source-line-no">180</span><span id="line-180">      } catch (Throwable t) {</span>
-<span class="source-line-no">181</span><span id="line-181">        // We always abort if system coprocessors cannot be loaded</span>
-<span class="source-line-no">182</span><span id="line-182">        abortServer(className, t);</span>
-<span class="source-line-no">183</span><span id="line-183">      }</span>
-<span class="source-line-no">184</span><span id="line-184">    }</span>
-<span class="source-line-no">185</span><span id="line-185">  }</span>
-<span class="source-line-no">186</span><span id="line-186"></span>
-<span class="source-line-no">187</span><span id="line-187">  /**</span>
-<span class="source-line-no">188</span><span id="line-188">   * Load a coprocessor implementation into the host</span>
-<span class="source-line-no">189</span><span id="line-189">   * @param path      path to implementation jar</span>
-<span class="source-line-no">190</span><span id="line-190">   * @param className the main class name</span>
-<span class="source-line-no">191</span><span id="line-191">   * @param priority  chaining priority</span>
-<span class="source-line-no">192</span><span id="line-192">   * @param conf      configuration for coprocessor</span>
-<span class="source-line-no">193</span><span id="line-193">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">194</span><span id="line-194">   */</span>
-<span class="source-line-no">195</span><span id="line-195">  public E load(Path path, String className, int priority, Configuration conf) throws IOException {</span>
-<span class="source-line-no">196</span><span id="line-196">    String[] includedClassPrefixes = null;</span>
-<span class="source-line-no">197</span><span id="line-197">    if (conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY) != null) {</span>
-<span class="source-line-no">198</span><span id="line-198">      String prefixes = conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY);</span>
-<span class="source-line-no">199</span><span id="line-199">      includedClassPrefixes = prefixes.split(";");</span>
-<span class="source-line-no">200</span><span id="line-200">    }</span>
-<span class="source-line-no">201</span><span id="line-201">    return load(path, className, priority, conf, includedClassPrefixes);</span>
-<span class="source-line-no">202</span><span id="line-202">  }</span>
-<span class="source-line-no">203</span><span id="line-203"></span>
-<span class="source-line-no">204</span><span id="line-204">  /**</span>
-<span class="source-line-no">205</span><span id="line-205">   * Load a coprocessor implementation into the host</span>
-<span class="source-line-no">206</span><span id="line-206">   * @param path                  path to implementation jar</span>
-<span class="source-line-no">207</span><span id="line-207">   * @param className             the main class name</span>
-<span class="source-line-no">208</span><span id="line-208">   * @param priority              chaining priority</span>
-<span class="source-line-no">209</span><span id="line-209">   * @param conf                  configuration for coprocessor</span>
-<span class="source-line-no">210</span><span id="line-210">   * @param includedClassPrefixes class name prefixes to include</span>
-<span class="source-line-no">211</span><span id="line-211">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">212</span><span id="line-212">   */</span>
-<span class="source-line-no">213</span><span id="line-213">  public E load(Path path, String className, int priority, Configuration conf,</span>
-<span class="source-line-no">214</span><span id="line-214">    String[] includedClassPrefixes) throws IOException {</span>
-<span class="source-line-no">215</span><span id="line-215">    Class&lt;?&gt; implClass;</span>
-<span class="source-line-no">216</span><span id="line-216">    LOG.debug("Loading coprocessor class " + className + " with path " + path + " and priority "</span>
-<span class="source-line-no">217</span><span id="line-217">      + priority);</span>
-<span class="source-line-no">218</span><span id="line-218"></span>
-<span class="source-line-no">219</span><span id="line-219">    boolean skipLoadDuplicateCoprocessor = conf.getBoolean(SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR,</span>
-<span class="source-line-no">220</span><span id="line-220">      DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR);</span>
-<span class="source-line-no">221</span><span id="line-221">    if (skipLoadDuplicateCoprocessor &amp;&amp; findCoprocessor(className) != null) {</span>
-<span class="source-line-no">222</span><span id="line-222">      // If already loaded will just continue</span>
-<span class="source-line-no">223</span><span id="line-223">      LOG.warn("Attempted duplicate loading of {}; skipped", className);</span>
-<span class="source-line-no">224</span><span id="line-224">      return null;</span>
-<span class="source-line-no">225</span><span id="line-225">    }</span>
-<span class="source-line-no">226</span><span id="line-226"></span>
-<span class="source-line-no">227</span><span id="line-227">    ClassLoader cl = null;</span>
-<span class="source-line-no">228</span><span id="line-228">    if (path == null) {</span>
-<span class="source-line-no">229</span><span id="line-229">      try {</span>
-<span class="source-line-no">230</span><span id="line-230">        implClass = getClass().getClassLoader().loadClass(className);</span>
-<span class="source-line-no">231</span><span id="line-231">      } catch (ClassNotFoundException e) {</span>
-<span class="source-line-no">232</span><span id="line-232">        throw new IOException("No jar path specified for " + className);</span>
-<span class="source-line-no">233</span><span id="line-233">      }</span>
-<span class="source-line-no">234</span><span id="line-234">    } else {</span>
-<span class="source-line-no">235</span><span id="line-235">      cl =</span>
-<span class="source-line-no">236</span><span id="line-236">        CoprocessorClassLoader.getClassLoader(path, getClass().getClassLoader(), pathPrefix, conf);</span>
-<span class="source-line-no">237</span><span id="line-237">      try {</span>
-<span class="source-line-no">238</span><span id="line-238">        implClass = ((CoprocessorClassLoader) cl).loadClass(className, includedClassPrefixes);</span>
-<span class="source-line-no">239</span><span id="line-239">      } catch (ClassNotFoundException e) {</span>
-<span class="source-line-no">240</span><span id="line-240">        throw new IOException("Cannot load external coprocessor class " + className, e);</span>
-<span class="source-line-no">241</span><span id="line-241">      }</span>
-<span class="source-line-no">242</span><span id="line-242">    }</span>
-<span class="source-line-no">243</span><span id="line-243"></span>
-<span class="source-line-no">244</span><span id="line-244">    // load custom code for coprocessor</span>
-<span class="source-line-no">245</span><span id="line-245">    Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">246</span><span id="line-246">    ClassLoader hostClassLoader = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">247</span><span id="line-247">    try {</span>
-<span class="source-line-no">248</span><span id="line-248">      // switch temporarily to the thread classloader for custom CP</span>
-<span class="source-line-no">249</span><span id="line-249">      currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">250</span><span id="line-250">      E cpInstance = checkAndLoadInstance(implClass, priority, conf);</span>
-<span class="source-line-no">251</span><span id="line-251">      return cpInstance;</span>
-<span class="source-line-no">252</span><span id="line-252">    } finally {</span>
-<span class="source-line-no">253</span><span id="line-253">      // restore the fresh (host) classloader</span>
-<span class="source-line-no">254</span><span id="line-254">      currentThread.setContextClassLoader(hostClassLoader);</span>
-<span class="source-line-no">255</span><span id="line-255">    }</span>
-<span class="source-line-no">256</span><span id="line-256">  }</span>
-<span class="source-line-no">257</span><span id="line-257"></span>
-<span class="source-line-no">258</span><span id="line-258">  public void load(Class&lt;? extends C&gt; implClass, int priority, Configuration conf)</span>
-<span class="source-line-no">259</span><span id="line-259">    throws IOException {</span>
-<span class="source-line-no">260</span><span id="line-260">    E env = checkAndLoadInstance(implClass, priority, conf);</span>
-<span class="source-line-no">261</span><span id="line-261">    coprocEnvironments.add(env);</span>
-<span class="source-line-no">262</span><span id="line-262">  }</span>
-<span class="source-line-no">263</span><span id="line-263"></span>
-<span class="source-line-no">264</span><span id="line-264">  /**</span>
-<span class="source-line-no">265</span><span id="line-265">   * @param implClass Implementation class</span>
-<span class="source-line-no">266</span><span id="line-266">   * @param priority  priority</span>
-<span class="source-line-no">267</span><span id="line-267">   * @param conf      configuration</span>
-<span class="source-line-no">268</span><span id="line-268">   * @throws java.io.IOException Exception</span>
-<span class="source-line-no">269</span><span id="line-269">   */</span>
-<span class="source-line-no">270</span><span id="line-270">  public E checkAndLoadInstance(Class&lt;?&gt; implClass, int priority, Configuration conf)</span>
-<span class="source-line-no">271</span><span id="line-271">    throws IOException {</span>
-<span class="source-line-no">272</span><span id="line-272">    // create the instance</span>
-<span class="source-line-no">273</span><span id="line-273">    C impl;</span>
-<span class="source-line-no">274</span><span id="line-274">    try {</span>
-<span class="source-line-no">275</span><span id="line-275">      impl = checkAndGetInstance(implClass);</span>
-<span class="source-line-no">276</span><span id="line-276">      if (impl == null) {</span>
-<span class="source-line-no">277</span><span id="line-277">        LOG.error("Cannot load coprocessor " + implClass.getSimpleName());</span>
-<span class="source-line-no">278</span><span id="line-278">        return null;</span>
-<span class="source-line-no">279</span><span id="line-279">      }</span>
-<span class="source-line-no">280</span><span id="line-280">    } catch (InstantiationException | IllegalAccessException e) {</span>
-<span class="source-line-no">281</span><span id="line-281">      throw new IOException(e);</span>
-<span class="source-line-no">282</span><span id="line-282">    }</span>
-<span class="source-line-no">283</span><span id="line-283">    // create the environment</span>
-<span class="source-line-no">284</span><span id="line-284">    E env = createEnvironment(impl, priority, loadSequence.incrementAndGet(), conf);</span>
-<span class="source-line-no">285</span><span id="line-285">    assert env instanceof BaseEnvironment;</span>
-<span class="source-line-no">286</span><span id="line-286">    ((BaseEnvironment&lt;C&gt;) env).startup();</span>
-<span class="source-line-no">287</span><span id="line-287">    // HBASE-4014: maintain list of loaded coprocessors for later crash analysis</span>
-<span class="source-line-no">288</span><span id="line-288">    // if server (master or regionserver) aborts.</span>
-<span class="source-line-no">289</span><span id="line-289">    coprocessorNames.add(implClass.getName());</span>
-<span class="source-line-no">290</span><span id="line-290">    return env;</span>
-<span class="source-line-no">291</span><span id="line-291">  }</span>
-<span class="source-line-no">292</span><span id="line-292"></span>
-<span class="source-line-no">293</span><span id="line-293">  /**</span>
-<span class="source-line-no">294</span><span id="line-294">   * Called when a new Coprocessor class is loaded</span>
-<span class="source-line-no">295</span><span id="line-295">   */</span>
-<span class="source-line-no">296</span><span id="line-296">  public abstract E createEnvironment(C instance, int priority, int sequence, Configuration conf);</span>
-<span class="source-line-no">297</span><span id="line-297"></span>
-<span class="source-line-no">298</span><span id="line-298">  /**</span>
-<span class="source-line-no">299</span><span id="line-299">   * Called when a new Coprocessor class needs to be loaded. Checks if type of the given class is</span>
-<span class="source-line-no">300</span><span id="line-300">   * what the corresponding host implementation expects. If it is of correct type, returns an</span>
-<span class="source-line-no">301</span><span id="line-301">   * instance of the coprocessor to be loaded. If not, returns null. If an exception occurs when</span>
-<span class="source-line-no">302</span><span id="line-302">   * trying to create instance of a coprocessor, it's passed up and eventually results into server</span>
-<span class="source-line-no">303</span><span id="line-303">   * aborting.</span>
-<span class="source-line-no">304</span><span id="line-304">   */</span>
-<span class="source-line-no">305</span><span id="line-305">  public abstract C checkAndGetInstance(Class&lt;?&gt; implClass)</span>
-<span class="source-line-no">306</span><span id="line-306">    throws InstantiationException, IllegalAccessException;</span>
-<span class="source-line-no">307</span><span id="line-307"></span>
-<span class="source-line-no">308</span><span id="line-308">  public void shutdown(E e) {</span>
-<span class="source-line-no">309</span><span id="line-309">    assert e instanceof BaseEnvironment;</span>
-<span class="source-line-no">310</span><span id="line-310">    if (LOG.isDebugEnabled()) {</span>
-<span class="source-line-no">311</span><span id="line-311">      LOG.debug("Stop coprocessor " + e.getInstance().getClass().getName());</span>
-<span class="source-line-no">312</span><span id="line-312">    }</span>
-<span class="source-line-no">313</span><span id="line-313">    ((BaseEnvironment&lt;C&gt;) e).shutdown();</span>
-<span class="source-line-no">314</span><span id="line-314">  }</span>
-<span class="source-line-no">315</span><span id="line-315"></span>
-<span class="source-line-no">316</span><span id="line-316">  /**</span>
-<span class="source-line-no">317</span><span id="line-317">   * Find coprocessors by full class name or simple name.</span>
-<span class="source-line-no">318</span><span id="line-318">   */</span>
-<span class="source-line-no">319</span><span id="line-319">  public C findCoprocessor(String className) {</span>
-<span class="source-line-no">320</span><span id="line-320">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">321</span><span id="line-321">      if (</span>
-<span class="source-line-no">322</span><span id="line-322">        env.getInstance().getClass().getName().equals(className)</span>
-<span class="source-line-no">323</span><span id="line-323">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
-<span class="source-line-no">324</span><span id="line-324">      ) {</span>
-<span class="source-line-no">325</span><span id="line-325">        return env.getInstance();</span>
-<span class="source-line-no">326</span><span id="line-326">      }</span>
-<span class="source-line-no">327</span><span id="line-327">    }</span>
-<span class="source-line-no">328</span><span id="line-328">    return null;</span>
-<span class="source-line-no">329</span><span id="line-329">  }</span>
-<span class="source-line-no">330</span><span id="line-330"></span>
-<span class="source-line-no">331</span><span id="line-331">  public &lt;T extends C&gt; T findCoprocessor(Class&lt;T&gt; cls) {</span>
-<span class="source-line-no">332</span><span id="line-332">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">333</span><span id="line-333">      if (cls.isAssignableFrom(env.getInstance().getClass())) {</span>
-<span class="source-line-no">334</span><span id="line-334">        return (T) env.getInstance();</span>
-<span class="source-line-no">335</span><span id="line-335">      }</span>
-<span class="source-line-no">336</span><span id="line-336">    }</span>
-<span class="source-line-no">337</span><span id="line-337">    return null;</span>
-<span class="source-line-no">338</span><span id="line-338">  }</span>
-<span class="source-line-no">339</span><span id="line-339"></span>
-<span class="source-line-no">340</span><span id="line-340">  /**</span>
-<span class="source-line-no">341</span><span id="line-341">   * Find list of coprocessors that extend/implement the given class/interface</span>
-<span class="source-line-no">342</span><span id="line-342">   * @param cls the class/interface to look for</span>
-<span class="source-line-no">343</span><span id="line-343">   * @return the list of coprocessors, or null if not found</span>
-<span class="source-line-no">344</span><span id="line-344">   */</span>
-<span class="source-line-no">345</span><span id="line-345">  public &lt;T extends C&gt; List&lt;T&gt; findCoprocessors(Class&lt;T&gt; cls) {</span>
-<span class="source-line-no">346</span><span id="line-346">    ArrayList&lt;T&gt; ret = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">347</span><span id="line-347"></span>
-<span class="source-line-no">348</span><span id="line-348">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">349</span><span id="line-349">      C cp = env.getInstance();</span>
-<span class="source-line-no">350</span><span id="line-350"></span>
-<span class="source-line-no">351</span><span id="line-351">      if (cp != null) {</span>
-<span class="source-line-no">352</span><span id="line-352">        if (cls.isAssignableFrom(cp.getClass())) {</span>
-<span class="source-line-no">353</span><span id="line-353">          ret.add((T) cp);</span>
-<span class="source-line-no">354</span><span id="line-354">        }</span>
-<span class="source-line-no">355</span><span id="line-355">      }</span>
-<span class="source-line-no">356</span><span id="line-356">    }</span>
-<span class="source-line-no">357</span><span id="line-357">    return ret;</span>
-<span class="source-line-no">358</span><span id="line-358">  }</span>
-<span class="source-line-no">359</span><span id="line-359"></span>
-<span class="source-line-no">360</span><span id="line-360">  /**</span>
-<span class="source-line-no">361</span><span id="line-361">   * Find a coprocessor environment by class name</span>
-<span class="source-line-no">362</span><span id="line-362">   * @param className the class name</span>
-<span class="source-line-no">363</span><span id="line-363">   * @return the coprocessor, or null if not found</span>
-<span class="source-line-no">364</span><span id="line-364">   */</span>
-<span class="source-line-no">365</span><span id="line-365">  public E findCoprocessorEnvironment(String className) {</span>
-<span class="source-line-no">366</span><span id="line-366">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">367</span><span id="line-367">      if (</span>
-<span class="source-line-no">368</span><span id="line-368">        env.getInstance().getClass().getName().equals(className)</span>
-<span class="source-line-no">369</span><span id="line-369">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
-<span class="source-line-no">370</span><span id="line-370">      ) {</span>
-<span class="source-line-no">371</span><span id="line-371">        return env;</span>
-<span class="source-line-no">372</span><span id="line-372">      }</span>
-<span class="source-line-no">373</span><span id="line-373">    }</span>
-<span class="source-line-no">374</span><span id="line-374">    return null;</span>
-<span class="source-line-no">375</span><span id="line-375">  }</span>
-<span class="source-line-no">376</span><span id="line-376"></span>
-<span class="source-line-no">377</span><span id="line-377">  /**</span>
-<span class="source-line-no">378</span><span id="line-378">   * Retrieves the set of classloaders used to instantiate Coprocessor classes defined in external</span>
-<span class="source-line-no">379</span><span id="line-379">   * jar files.</span>
-<span class="source-line-no">380</span><span id="line-380">   * @return A set of ClassLoader instances</span>
-<span class="source-line-no">381</span><span id="line-381">   */</span>
-<span class="source-line-no">382</span><span id="line-382">  Set&lt;ClassLoader&gt; getExternalClassLoaders() {</span>
-<span class="source-line-no">383</span><span id="line-383">    Set&lt;ClassLoader&gt; externalClassLoaders = new HashSet&lt;&gt;();</span>
-<span class="source-line-no">384</span><span id="line-384">    final ClassLoader systemClassLoader = this.getClass().getClassLoader();</span>
-<span class="source-line-no">385</span><span id="line-385">    for (E env : coprocEnvironments) {</span>
-<span class="source-line-no">386</span><span id="line-386">      ClassLoader cl = env.getInstance().getClass().getClassLoader();</span>
-<span class="source-line-no">387</span><span id="line-387">      if (cl != systemClassLoader) {</span>
-<span class="source-line-no">388</span><span id="line-388">        // do not include system classloader</span>
-<span class="source-line-no">389</span><span id="line-389">        externalClassLoaders.add(cl);</span>
-<span class="source-line-no">390</span><span id="line-390">      }</span>
-<span class="source-line-no">391</span><span id="line-391">    }</span>
-<span class="source-line-no">392</span><span id="line-392">    return externalClassLoaders;</span>
-<span class="source-line-no">393</span><span id="line-393">  }</span>
-<span class="source-line-no">394</span><span id="line-394"></span>
-<span class="source-line-no">395</span><span id="line-395">  /**</span>
-<span class="source-line-no">396</span><span id="line-396">   * Environment priority comparator. Coprocessors are chained in sorted order.</span>
-<span class="source-line-no">397</span><span id="line-397">   */</span>
-<span class="source-line-no">398</span><span id="line-398">  static class EnvironmentPriorityComparator implements Comparator&lt;CoprocessorEnvironment&gt; {</span>
-<span class="source-line-no">399</span><span id="line-399">    @Override</span>
-<span class="source-line-no">400</span><span id="line-400">    public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) {</span>
-<span class="source-line-no">401</span><span id="line-401">      if (env1.getPriority() &lt; env2.getPriority()) {</span>
-<span class="source-line-no">402</span><span id="line-402">        return -1;</span>
-<span class="source-line-no">403</span><span id="line-403">      } else if (env1.getPriority() &gt; env2.getPriority()) {</span>
-<span class="source-line-no">404</span><span id="line-404">        return 1;</span>
-<span class="source-line-no">405</span><span id="line-405">      }</span>
-<span class="source-line-no">406</span><span id="line-406">      if (env1.getLoadSequence() &lt; env2.getLoadSequence()) {</span>
-<span class="source-line-no">407</span><span id="line-407">        return -1;</span>
-<span class="source-line-no">408</span><span id="line-408">      } else if (env1.getLoadSequence() &gt; env2.getLoadSequence()) {</span>
-<span class="source-line-no">409</span><span id="line-409">        return 1;</span>
-<span class="source-line-no">410</span><span id="line-410">      }</span>
-<span class="source-line-no">411</span><span id="line-411">      return 0;</span>
-<span class="source-line-no">412</span><span id="line-412">    }</span>
-<span class="source-line-no">413</span><span id="line-413">  }</span>
-<span class="source-line-no">414</span><span id="line-414"></span>
-<span class="source-line-no">415</span><span id="line-415">  protected void abortServer(final E environment, final Throwable e) {</span>
-<span class="source-line-no">416</span><span id="line-416">    abortServer(environment.getInstance().getClass().getName(), e);</span>
-<span class="source-line-no">417</span><span id="line-417">  }</span>
-<span class="source-line-no">418</span><span id="line-418"></span>
-<span class="source-line-no">419</span><span id="line-419">  protected void abortServer(final String coprocessorName, final Throwable e) {</span>
-<span class="source-line-no">420</span><span id="line-420">    String message = "The coprocessor " + coprocessorName + " threw " + e.toString();</span>
-<span class="source-line-no">421</span><span id="line-421">    LOG.error(message, e);</span>
-<span class="source-line-no">422</span><span id="line-422">    if (abortable != null) {</span>
-<span class="source-line-no">423</span><span id="line-423">      abortable.abort(message, e);</span>
-<span class="source-line-no">424</span><span id="line-424">    } else {</span>
-<span class="source-line-no">425</span><span id="line-425">      LOG.warn("No available Abortable, process was not aborted");</span>
-<span class="source-line-no">426</span><span id="line-426">    }</span>
-<span class="source-line-no">427</span><span id="line-427">  }</span>
-<span class="source-line-no">428</span><span id="line-428"></span>
-<span class="source-line-no">429</span><span id="line-429">  /**</span>
-<span class="source-line-no">430</span><span id="line-430">   * This is used by coprocessor hooks which are declared to throw IOException (or its subtypes).</span>
-<span class="source-line-no">431</span><span id="line-431">   * For such hooks, we should handle throwable objects depending on the Throwable's type. Those</span>
-<span class="source-line-no">432</span><span id="line-432">   * which are instances of IOException should be passed on to the client. This is in conformance</span>
-<span class="source-line-no">433</span><span id="line-433">   * with the HBase idiom regarding IOException: that it represents a circumstance that should be</span>
-<span class="source-line-no">434</span><span id="line-434">   * passed along to the client for its own handling. For example, a coprocessor that implements</span>
-<span class="source-line-no">435</span><span id="line-435">   * access controls would throw a subclass of IOException, such as AccessDeniedException, in its</span>
-<span class="source-line-no">436</span><span id="line-436">   * preGet() method to prevent an unauthorized client's performing a Get on a particular table.</span>
-<span class="source-line-no">437</span><span id="line-437">   * @param env Coprocessor Environment</span>
-<span class="source-line-no">438</span><span id="line-438">   * @param e   Throwable object thrown by coprocessor.</span>
-<span class="source-line-no">439</span><span id="line-439">   * @exception IOException Exception</span>
-<span class="source-line-no">440</span><span id="line-440">   */</span>
-<span class="source-line-no">441</span><span id="line-441">  // Note to devs: Class comments of all observers ({@link MasterObserver}, {@link WALObserver},</span>
-<span class="source-line-no">442</span><span id="line-442">  // etc) mention this nuance of our exception handling so that coprocessor can throw appropriate</span>
-<span class="source-line-no">443</span><span id="line-443">  // exceptions depending on situation. If any changes are made to this logic, make sure to</span>
-<span class="source-line-no">444</span><span id="line-444">  // update all classes' comments.</span>
-<span class="source-line-no">445</span><span id="line-445">  protected void handleCoprocessorThrowable(final E env, final Throwable e) throws IOException {</span>
-<span class="source-line-no">446</span><span id="line-446">    if (e instanceof IOException) {</span>
-<span class="source-line-no">447</span><span id="line-447">      throw (IOException) e;</span>
-<span class="source-line-no">448</span><span id="line-448">    }</span>
-<span class="source-line-no">449</span><span id="line-449">    // If we got here, e is not an IOException. A loaded coprocessor has a</span>
-<span class="source-line-no">450</span><span id="line-450">    // fatal bug, and the server (master or regionserver) should remove the</span>
-<span class="source-line-no">451</span><span id="line-451">    // faulty coprocessor from its set of active coprocessors. Setting</span>
-<span class="source-line-no">452</span><span id="line-452">    // 'hbase.coprocessor.abortonerror' to true will cause abortServer(),</span>
-<span class="source-line-no">453</span><span id="line-453">    // which may be useful in development and testing environments where</span>
-<span class="source-line-no">454</span><span id="line-454">    // 'failing fast' for error analysis is desired.</span>
-<span class="source-line-no">455</span><span id="line-455">    if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) {</span>
-<span class="source-line-no">456</span><span id="line-456">      // server is configured to abort.</span>
-<span class="source-line-no">457</span><span id="line-457">      abortServer(env, e);</span>
-<span class="source-line-no">458</span><span id="line-458">    } else {</span>
-<span class="source-line-no">459</span><span id="line-459">      // If available, pull a table name out of the environment</span>
-<span class="source-line-no">460</span><span id="line-460">      if (env instanceof RegionCoprocessorEnvironment) {</span>
-<span class="source-line-no">461</span><span id="line-461">        String tableName =</span>
-<span class="source-line-no">462</span><span id="line-462">          ((RegionCoprocessorEnvironment) env).getRegionInfo().getTable().getNameAsString();</span>
-<span class="source-line-no">463</span><span id="line-463">        LOG.error("Removing coprocessor '" + env.toString() + "' from table '" + tableName + "'",</span>
-<span class="source-line-no">464</span><span id="line-464">          e);</span>
-<span class="source-line-no">465</span><span id="line-465">      } else {</span>
-<span class="source-line-no">466</span><span id="line-466">        LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment", e);</span>
-<span class="source-line-no">467</span><span id="line-467">      }</span>
-<span class="source-line-no">468</span><span id="line-468"></span>
-<span class="source-line-no">469</span><span id="line-469">      coprocEnvironments.remove(env);</span>
-<span class="source-line-no">470</span><span id="line-470">      try {</span>
-<span class="source-line-no">471</span><span id="line-471">        shutdown(env);</span>
-<span class="source-line-no">472</span><span id="line-472">      } catch (Exception x) {</span>
-<span class="source-line-no">473</span><span id="line-473">        LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x);</span>
-<span class="source-line-no">474</span><span id="line-474">      }</span>
-<span class="source-line-no">475</span><span id="line-475">      throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e</span>
-<span class="source-line-no">476</span><span id="line-476">        + "' and has been removed from the active " + "coprocessor set.", e);</span>
-<span class="source-line-no">477</span><span id="line-477">    }</span>
-<span class="source-line-no">478</span><span id="line-478">  }</span>
-<span class="source-line-no">479</span><span id="line-479"></span>
-<span class="source-line-no">480</span><span id="line-480">  /**</span>
-<span class="source-line-no">481</span><span id="line-481">   * Used to limit legacy handling to once per Coprocessor class per classloader.</span>
-<span class="source-line-no">482</span><span id="line-482">   */</span>
-<span class="source-line-no">483</span><span id="line-483">  private static final Set&lt;Class&lt;? extends Coprocessor&gt;&gt; legacyWarning =</span>
-<span class="source-line-no">484</span><span id="line-484">    new ConcurrentSkipListSet&lt;&gt;(new Comparator&lt;Class&lt;? extends Coprocessor&gt;&gt;() {</span>
-<span class="source-line-no">485</span><span id="line-485">      @Override</span>
-<span class="source-line-no">486</span><span id="line-486">      public int compare(Class&lt;? extends Coprocessor&gt; c1, Class&lt;? extends Coprocessor&gt; c2) {</span>
-<span class="source-line-no">487</span><span id="line-487">        if (c1.equals(c2)) {</span>
-<span class="source-line-no">488</span><span id="line-488">          return 0;</span>
-<span class="source-line-no">489</span><span id="line-489">        }</span>
-<span class="source-line-no">490</span><span id="line-490">        return c1.getName().compareTo(c2.getName());</span>
-<span class="source-line-no">491</span><span id="line-491">      }</span>
-<span class="source-line-no">492</span><span id="line-492">    });</span>
-<span class="source-line-no">493</span><span id="line-493"></span>
-<span class="source-line-no">494</span><span id="line-494">  /**</span>
-<span class="source-line-no">495</span><span id="line-495">   * Implementations defined function to get an observer of type {@code O} from a coprocessor of</span>
-<span class="source-line-no">496</span><span id="line-496">   * type {@code C}. Concrete implementations of CoprocessorHost define one getter for each observer</span>
-<span class="source-line-no">497</span><span id="line-497">   * they can handle. For e.g. RegionCoprocessorHost will use 3 getters, one for each of</span>
-<span class="source-line-no">498</span><span id="line-498">   * RegionObserver, EndpointObserver and BulkLoadObserver. These getters are used by</span>
-<span class="source-line-no">499</span><span id="line-499">   * {@code ObserverOperation} to get appropriate observer from the coprocessor.</span>
-<span class="source-line-no">500</span><span id="line-500">   */</span>
-<span class="source-line-no">501</span><span id="line-501">  @FunctionalInterface</span>
-<span class="source-line-no">502</span><span id="line-502">  public interface ObserverGetter&lt;C, O&gt; extends Function&lt;C, Optional&lt;O&gt;&gt; {</span>
-<span class="source-line-no">503</span><span id="line-503">  }</span>
-<span class="source-line-no">504</span><span id="line-504"></span>
-<span class="source-line-no">505</span><span id="line-505">  private abstract class ObserverOperation&lt;O&gt; extends ObserverContextImpl&lt;E&gt; {</span>
-<span class="source-line-no">506</span><span id="line-506">    ObserverGetter&lt;C, O&gt; observerGetter;</span>
-<span class="source-line-no">507</span><span id="line-507"></span>
-<span class="source-line-no">508</span><span id="line-508">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
-<span class="source-line-no">509</span><span id="line-509">      this(observerGetter, null);</span>
-<span class="source-line-no">510</span><span id="line-510">    }</span>
-<span class="source-line-no">511</span><span id="line-511"></span>
-<span class="source-line-no">512</span><span id="line-512">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
-<span class="source-line-no">513</span><span id="line-513">      this(observerGetter, user, false);</span>
-<span class="source-line-no">514</span><span id="line-514">    }</span>
-<span class="source-line-no">515</span><span id="line-515"></span>
-<span class="source-line-no">516</span><span id="line-516">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, boolean bypassable) {</span>
-<span class="source-line-no">517</span><span id="line-517">      this(observerGetter, null, bypassable);</span>
-<span class="source-line-no">518</span><span id="line-518">    }</span>
-<span class="source-line-no">519</span><span id="line-519"></span>
-<span class="source-line-no">520</span><span id="line-520">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user, boolean bypassable) {</span>
-<span class="source-line-no">521</span><span id="line-521">      super(user != null ? user : RpcServer.getRequestUser().orElse(null), bypassable);</span>
-<span class="source-line-no">522</span><span id="line-522">      this.observerGetter = observerGetter;</span>
-<span class="source-line-no">523</span><span id="line-523">    }</span>
-<span class="source-line-no">524</span><span id="line-524"></span>
-<span class="source-line-no">525</span><span id="line-525">    abstract void callObserver() throws IOException;</span>
+<span class="source-line-no">132</span><span id="line-132">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">133</span><span id="line-133"></span>
+<span class="source-line-no">134</span><span id="line-134">    // load default coprocessors from configure file</span>
+<span class="source-line-no">135</span><span id="line-135">    String[] defaultCPClasses = conf.getStrings(confKey);</span>
+<span class="source-line-no">136</span><span id="line-136">    if (defaultCPClasses == null || defaultCPClasses.length == 0) return;</span>
+<span class="source-line-no">137</span><span id="line-137"></span>
+<span class="source-line-no">138</span><span id="line-138">    int currentSystemPriority = Coprocessor.PRIORITY_SYSTEM;</span>
+<span class="source-line-no">139</span><span id="line-139">    for (String className : defaultCPClasses) {</span>
+<span class="source-line-no">140</span><span id="line-140">      // After HBASE-23710 and HBASE-26714 when configuring for system coprocessor, we accept</span>
+<span class="source-line-no">141</span><span id="line-141">      // an optional format of className|priority|path</span>
+<span class="source-line-no">142</span><span id="line-142">      String[] classNameToken = className.split("\\|");</span>
+<span class="source-line-no">143</span><span id="line-143">      boolean hasPriorityOverride = false;</span>
+<span class="source-line-no">144</span><span id="line-144">      boolean hasPath = false;</span>
+<span class="source-line-no">145</span><span id="line-145">      className = classNameToken[0];</span>
+<span class="source-line-no">146</span><span id="line-146">      int overridePriority = Coprocessor.PRIORITY_SYSTEM;</span>
+<span class="source-line-no">147</span><span id="line-147">      Path path = null;</span>
+<span class="source-line-no">148</span><span id="line-148">      if (classNameToken.length &gt; 1 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[1])) {</span>
+<span class="source-line-no">149</span><span id="line-149">        overridePriority = Integer.parseInt(classNameToken[1]);</span>
+<span class="source-line-no">150</span><span id="line-150">        hasPriorityOverride = true;</span>
+<span class="source-line-no">151</span><span id="line-151">      }</span>
+<span class="source-line-no">152</span><span id="line-152">      if (classNameToken.length &gt; 2 &amp;&amp; !Strings.isNullOrEmpty(classNameToken[2])) {</span>
+<span class="source-line-no">153</span><span id="line-153">        path = new Path(classNameToken[2].trim());</span>
+<span class="source-line-no">154</span><span id="line-154">        hasPath = true;</span>
+<span class="source-line-no">155</span><span id="line-155">      }</span>
+<span class="source-line-no">156</span><span id="line-156">      className = className.trim();</span>
+<span class="source-line-no">157</span><span id="line-157">      if (findCoprocessor(className) != null) {</span>
+<span class="source-line-no">158</span><span id="line-158">        // If already loaded will just continue</span>
+<span class="source-line-no">159</span><span id="line-159">        LOG.warn("Attempted duplicate loading of " + className + "; skipped");</span>
+<span class="source-line-no">160</span><span id="line-160">        continue;</span>
+<span class="source-line-no">161</span><span id="line-161">      }</span>
+<span class="source-line-no">162</span><span id="line-162">      ClassLoader cl = this.getClass().getClassLoader();</span>
+<span class="source-line-no">163</span><span id="line-163">      try {</span>
+<span class="source-line-no">164</span><span id="line-164">        // override the class loader if a path for the system coprocessor is provided.</span>
+<span class="source-line-no">165</span><span id="line-165">        if (hasPath) {</span>
+<span class="source-line-no">166</span><span id="line-166">          cl = CoprocessorClassLoader.getClassLoader(path, this.getClass().getClassLoader(),</span>
+<span class="source-line-no">167</span><span id="line-167">            pathPrefix, conf);</span>
+<span class="source-line-no">168</span><span id="line-168">        }</span>
+<span class="source-line-no">169</span><span id="line-169">        Thread.currentThread().setContextClassLoader(cl);</span>
+<span class="source-line-no">170</span><span id="line-170">        implClass = cl.loadClass(className);</span>
+<span class="source-line-no">171</span><span id="line-171">        int coprocPriority = hasPriorityOverride ? overridePriority : currentSystemPriority;</span>
+<span class="source-line-no">172</span><span id="line-172">        // Add coprocessors as we go to guard against case where a coprocessor is specified twice</span>
+<span class="source-line-no">173</span><span id="line-173">        // in the configuration</span>
+<span class="source-line-no">174</span><span id="line-174">        E env = checkAndLoadInstance(implClass, coprocPriority, conf);</span>
+<span class="source-line-no">175</span><span id="line-175">        if (env != null) {</span>
+<span class="source-line-no">176</span><span id="line-176">          this.coprocEnvironments.add(env);</span>
+<span class="source-line-no">177</span><span id="line-177">          LOG.info("System coprocessor {} loaded, priority={}.", className, coprocPriority);</span>
+<span class="source-line-no">178</span><span id="line-178">          if (!hasPriorityOverride) {</span>
+<span class="source-line-no">179</span><span id="line-179">            ++currentSystemPriority;</span>
+<span class="source-line-no">180</span><span id="line-180">          }</span>
+<span class="source-line-no">181</span><span id="line-181">        }</span>
+<span class="source-line-no">182</span><span id="line-182">      } catch (Throwable t) {</span>
+<span class="source-line-no">183</span><span id="line-183">        // We always abort if system coprocessors cannot be loaded</span>
+<span class="source-line-no">184</span><span id="line-184">        abortServer(className, t);</span>
+<span class="source-line-no">185</span><span id="line-185">      }</span>
+<span class="source-line-no">186</span><span id="line-186">    }</span>
+<span class="source-line-no">187</span><span id="line-187">  }</span>
+<span class="source-line-no">188</span><span id="line-188"></span>
+<span class="source-line-no">189</span><span id="line-189">  /**</span>
+<span class="source-line-no">190</span><span id="line-190">   * Load a coprocessor implementation into the host</span>
+<span class="source-line-no">191</span><span id="line-191">   * @param path      path to implementation jar</span>
+<span class="source-line-no">192</span><span id="line-192">   * @param className the main class name</span>
+<span class="source-line-no">193</span><span id="line-193">   * @param priority  chaining priority</span>
+<span class="source-line-no">194</span><span id="line-194">   * @param conf      configuration for coprocessor</span>
+<span class="source-line-no">195</span><span id="line-195">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">196</span><span id="line-196">   */</span>
+<span class="source-line-no">197</span><span id="line-197">  public E load(Path path, String className, int priority, Configuration conf) throws IOException {</span>
+<span class="source-line-no">198</span><span id="line-198">    String[] includedClassPrefixes = null;</span>
+<span class="source-line-no">199</span><span id="line-199">    if (conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY) != null) {</span>
+<span class="source-line-no">200</span><span id="line-200">      String prefixes = conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY);</span>
+<span class="source-line-no">201</span><span id="line-201">      includedClassPrefixes = prefixes.split(";");</span>
+<span class="source-line-no">202</span><span id="line-202">    }</span>
+<span class="source-line-no">203</span><span id="line-203">    return load(path, className, priority, conf, includedClassPrefixes);</span>
+<span class="source-line-no">204</span><span id="line-204">  }</span>
+<span class="source-line-no">205</span><span id="line-205"></span>
+<span class="source-line-no">206</span><span id="line-206">  /**</span>
+<span class="source-line-no">207</span><span id="line-207">   * Load a coprocessor implementation into the host</span>
+<span class="source-line-no">208</span><span id="line-208">   * @param path                  path to implementation jar</span>
+<span class="source-line-no">209</span><span id="line-209">   * @param className             the main class name</span>
+<span class="source-line-no">210</span><span id="line-210">   * @param priority              chaining priority</span>
+<span class="source-line-no">211</span><span id="line-211">   * @param conf                  configuration for coprocessor</span>
+<span class="source-line-no">212</span><span id="line-212">   * @param includedClassPrefixes class name prefixes to include</span>
+<span class="source-line-no">213</span><span id="line-213">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">214</span><span id="line-214">   */</span>
+<span class="source-line-no">215</span><span id="line-215">  public E load(Path path, String className, int priority, Configuration conf,</span>
+<span class="source-line-no">216</span><span id="line-216">    String[] includedClassPrefixes) throws IOException {</span>
+<span class="source-line-no">217</span><span id="line-217">    Class&lt;?&gt; implClass;</span>
+<span class="source-line-no">218</span><span id="line-218">    LOG.debug("Loading coprocessor class " + className + " with path " + path + " and priority "</span>
+<span class="source-line-no">219</span><span id="line-219">      + priority);</span>
+<span class="source-line-no">220</span><span id="line-220"></span>
+<span class="source-line-no">221</span><span id="line-221">    boolean skipLoadDuplicateCoprocessor = conf.getBoolean(SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR,</span>
+<span class="source-line-no">222</span><span id="line-222">      DEFAULT_SKIP_LOAD_DUPLICATE_TABLE_COPROCESSOR);</span>
+<span class="source-line-no">223</span><span id="line-223">    if (skipLoadDuplicateCoprocessor &amp;&amp; findCoprocessor(className) != null) {</span>
+<span class="source-line-no">224</span><span id="line-224">      // If already loaded will just continue</span>
+<span class="source-line-no">225</span><span id="line-225">      LOG.warn("Attempted duplicate loading of {}; skipped", className);</span>
+<span class="source-line-no">226</span><span id="line-226">      return null;</span>
+<span class="source-line-no">227</span><span id="line-227">    }</span>
+<span class="source-line-no">228</span><span id="line-228"></span>
+<span class="source-line-no">229</span><span id="line-229">    ClassLoader cl = null;</span>
+<span class="source-line-no">230</span><span id="line-230">    if (path == null) {</span>
+<span class="source-line-no">231</span><span id="line-231">      try {</span>
+<span class="source-line-no">232</span><span id="line-232">        implClass = getClass().getClassLoader().loadClass(className);</span>
+<span class="source-line-no">233</span><span id="line-233">      } catch (ClassNotFoundException e) {</span>
+<span class="source-line-no">234</span><span id="line-234">        throw new IOException("No jar path specified for " + className);</span>
+<span class="source-line-no">235</span><span id="line-235">      }</span>
+<span class="source-line-no">236</span><span id="line-236">    } else {</span>
+<span class="source-line-no">237</span><span id="line-237">      cl =</span>
+<span class="source-line-no">238</span><span id="line-238">        CoprocessorClassLoader.getClassLoader(path, getClass().getClassLoader(), pathPrefix, conf);</span>
+<span class="source-line-no">239</span><span id="line-239">      try {</span>
+<span class="source-line-no">240</span><span id="line-240">        implClass = ((CoprocessorClassLoader) cl).loadClass(className, includedClassPrefixes);</span>
+<span class="source-line-no">241</span><span id="line-241">      } catch (ClassNotFoundException e) {</span>
+<span class="source-line-no">242</span><span id="line-242">        throw new IOException("Cannot load external coprocessor class " + className, e);</span>
+<span class="source-line-no">243</span><span id="line-243">      }</span>
+<span class="source-line-no">244</span><span id="line-244">    }</span>
+<span class="source-line-no">245</span><span id="line-245"></span>
+<span class="source-line-no">246</span><span id="line-246">    // load custom code for coprocessor</span>
+<span class="source-line-no">247</span><span id="line-247">    Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">248</span><span id="line-248">    ClassLoader hostClassLoader = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">249</span><span id="line-249">    try {</span>
+<span class="source-line-no">250</span><span id="line-250">      // switch temporarily to the thread classloader for custom CP</span>
+<span class="source-line-no">251</span><span id="line-251">      currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">252</span><span id="line-252">      E cpInstance = checkAndLoadInstance(implClass, priority, conf);</span>
+<span class="source-line-no">253</span><span id="line-253">      return cpInstance;</span>
+<span class="source-line-no">254</span><span id="line-254">    } finally {</span>
+<span class="source-line-no">255</span><span id="line-255">      // restore the fresh (host) classloader</span>
+<span class="source-line-no">256</span><span id="line-256">      currentThread.setContextClassLoader(hostClassLoader);</span>
+<span class="source-line-no">257</span><span id="line-257">    }</span>
+<span class="source-line-no">258</span><span id="line-258">  }</span>
+<span class="source-line-no">259</span><span id="line-259"></span>
+<span class="source-line-no">260</span><span id="line-260">  public void load(Class&lt;? extends C&gt; implClass, int priority, Configuration conf)</span>
+<span class="source-line-no">261</span><span id="line-261">    throws IOException {</span>
+<span class="source-line-no">262</span><span id="line-262">    E env = checkAndLoadInstance(implClass, priority, conf);</span>
+<span class="source-line-no">263</span><span id="line-263">    coprocEnvironments.add(env);</span>
+<span class="source-line-no">264</span><span id="line-264">  }</span>
+<span class="source-line-no">265</span><span id="line-265"></span>
+<span class="source-line-no">266</span><span id="line-266">  /**</span>
+<span class="source-line-no">267</span><span id="line-267">   * @param implClass Implementation class</span>
+<span class="source-line-no">268</span><span id="line-268">   * @param priority  priority</span>
+<span class="source-line-no">269</span><span id="line-269">   * @param conf      configuration</span>
+<span class="source-line-no">270</span><span id="line-270">   * @throws java.io.IOException Exception</span>
+<span class="source-line-no">271</span><span id="line-271">   */</span>
+<span class="source-line-no">272</span><span id="line-272">  public E checkAndLoadInstance(Class&lt;?&gt; implClass, int priority, Configuration conf)</span>
+<span class="source-line-no">273</span><span id="line-273">    throws IOException {</span>
+<span class="source-line-no">274</span><span id="line-274">    // create the instance</span>
+<span class="source-line-no">275</span><span id="line-275">    C impl;</span>
+<span class="source-line-no">276</span><span id="line-276">    try {</span>
+<span class="source-line-no">277</span><span id="line-277">      impl = checkAndGetInstance(implClass);</span>
+<span class="source-line-no">278</span><span id="line-278">      if (impl == null) {</span>
+<span class="source-line-no">279</span><span id="line-279">        LOG.error("Cannot load coprocessor " + implClass.getSimpleName());</span>
+<span class="source-line-no">280</span><span id="line-280">        return null;</span>
+<span class="source-line-no">281</span><span id="line-281">      }</span>
+<span class="source-line-no">282</span><span id="line-282">    } catch (InstantiationException | IllegalAccessException e) {</span>
+<span class="source-line-no">283</span><span id="line-283">      throw new IOException(e);</span>
+<span class="source-line-no">284</span><span id="line-284">    }</span>
+<span class="source-line-no">285</span><span id="line-285">    // create the environment</span>
+<span class="source-line-no">286</span><span id="line-286">    E env = createEnvironment(impl, priority, loadSequence.incrementAndGet(), conf);</span>
+<span class="source-line-no">287</span><span id="line-287">    assert env instanceof BaseEnvironment;</span>
+<span class="source-line-no">288</span><span id="line-288">    ((BaseEnvironment&lt;C&gt;) env).startup();</span>
+<span class="source-line-no">289</span><span id="line-289">    // HBASE-4014: maintain list of loaded coprocessors for later crash analysis</span>
+<span class="source-line-no">290</span><span id="line-290">    // if server (master or regionserver) aborts.</span>
+<span class="source-line-no">291</span><span id="line-291">    coprocessorNames.add(implClass.getName());</span>
+<span class="source-line-no">292</span><span id="line-292">    return env;</span>
+<span class="source-line-no">293</span><span id="line-293">  }</span>
+<span class="source-line-no">294</span><span id="line-294"></span>
+<span class="source-line-no">295</span><span id="line-295">  /**</span>
+<span class="source-line-no">296</span><span id="line-296">   * Called when a new Coprocessor class is loaded</span>
+<span class="source-line-no">297</span><span id="line-297">   */</span>
+<span class="source-line-no">298</span><span id="line-298">  public abstract E createEnvironment(C instance, int priority, int sequence, Configuration conf);</span>
+<span class="source-line-no">299</span><span id="line-299"></span>
+<span class="source-line-no">300</span><span id="line-300">  /**</span>
+<span class="source-line-no">301</span><span id="line-301">   * Called when a new Coprocessor class needs to be loaded. Checks if type of the given class is</span>
+<span class="source-line-no">302</span><span id="line-302">   * what the corresponding host implementation expects. If it is of correct type, returns an</span>
+<span class="source-line-no">303</span><span id="line-303">   * instance of the coprocessor to be loaded. If not, returns null. If an exception occurs when</span>
+<span class="source-line-no">304</span><span id="line-304">   * trying to create instance of a coprocessor, it's passed up and eventually results into server</span>
+<span class="source-line-no">305</span><span id="line-305">   * aborting.</span>
+<span class="source-line-no">306</span><span id="line-306">   */</span>
+<span class="source-line-no">307</span><span id="line-307">  public abstract C checkAndGetInstance(Class&lt;?&gt; implClass)</span>
+<span class="source-line-no">308</span><span id="line-308">    throws InstantiationException, IllegalAccessException;</span>
+<span class="source-line-no">309</span><span id="line-309"></span>
+<span class="source-line-no">310</span><span id="line-310">  public void shutdown(E e) {</span>
+<span class="source-line-no">311</span><span id="line-311">    assert e instanceof BaseEnvironment;</span>
+<span class="source-line-no">312</span><span id="line-312">    if (LOG.isDebugEnabled()) {</span>
+<span class="source-line-no">313</span><span id="line-313">      LOG.debug("Stop coprocessor " + e.getInstance().getClass().getName());</span>
+<span class="source-line-no">314</span><span id="line-314">    }</span>
+<span class="source-line-no">315</span><span id="line-315">    ((BaseEnvironment&lt;C&gt;) e).shutdown();</span>
+<span class="source-line-no">316</span><span id="line-316">  }</span>
+<span class="source-line-no">317</span><span id="line-317"></span>
+<span class="source-line-no">318</span><span id="line-318">  /**</span>
+<span class="source-line-no">319</span><span id="line-319">   * Find coprocessors by full class name or simple name.</span>
+<span class="source-line-no">320</span><span id="line-320">   */</span>
+<span class="source-line-no">321</span><span id="line-321">  public C findCoprocessor(String className) {</span>
+<span class="source-line-no">322</span><span id="line-322">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">323</span><span id="line-323">      if (</span>
+<span class="source-line-no">324</span><span id="line-324">        env.getInstance().getClass().getName().equals(className)</span>
+<span class="source-line-no">325</span><span id="line-325">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
+<span class="source-line-no">326</span><span id="line-326">      ) {</span>
+<span class="source-line-no">327</span><span id="line-327">        return env.getInstance();</span>
+<span class="source-line-no">328</span><span id="line-328">      }</span>
+<span class="source-line-no">329</span><span id="line-329">    }</span>
+<span class="source-line-no">330</span><span id="line-330">    return null;</span>
+<span class="source-line-no">331</span><span id="line-331">  }</span>
+<span class="source-line-no">332</span><span id="line-332"></span>
+<span class="source-line-no">333</span><span id="line-333">  public &lt;T extends C&gt; T findCoprocessor(Class&lt;T&gt; cls) {</span>
+<span class="source-line-no">334</span><span id="line-334">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">335</span><span id="line-335">      if (cls.isAssignableFrom(env.getInstance().getClass())) {</span>
+<span class="source-line-no">336</span><span id="line-336">        return (T) env.getInstance();</span>
+<span class="source-line-no">337</span><span id="line-337">      }</span>
+<span class="source-line-no">338</span><span id="line-338">    }</span>
+<span class="source-line-no">339</span><span id="line-339">    return null;</span>
+<span class="source-line-no">340</span><span id="line-340">  }</span>
+<span class="source-line-no">341</span><span id="line-341"></span>
+<span class="source-line-no">342</span><span id="line-342">  /**</span>
+<span class="source-line-no">343</span><span id="line-343">   * Find list of coprocessors that extend/implement the given class/interface</span>
+<span class="source-line-no">344</span><span id="line-344">   * @param cls the class/interface to look for</span>
+<span class="source-line-no">345</span><span id="line-345">   * @return the list of coprocessors, or null if not found</span>
+<span class="source-line-no">346</span><span id="line-346">   */</span>
+<span class="source-line-no">347</span><span id="line-347">  public &lt;T extends C&gt; List&lt;T&gt; findCoprocessors(Class&lt;T&gt; cls) {</span>
+<span class="source-line-no">348</span><span id="line-348">    ArrayList&lt;T&gt; ret = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">349</span><span id="line-349"></span>
+<span class="source-line-no">350</span><span id="line-350">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">351</span><span id="line-351">      C cp = env.getInstance();</span>
+<span class="source-line-no">352</span><span id="line-352"></span>
+<span class="source-line-no">353</span><span id="line-353">      if (cp != null) {</span>
+<span class="source-line-no">354</span><span id="line-354">        if (cls.isAssignableFrom(cp.getClass())) {</span>
+<span class="source-line-no">355</span><span id="line-355">          ret.add((T) cp);</span>
+<span class="source-line-no">356</span><span id="line-356">        }</span>
+<span class="source-line-no">357</span><span id="line-357">      }</span>
+<span class="source-line-no">358</span><span id="line-358">    }</span>
+<span class="source-line-no">359</span><span id="line-359">    return ret;</span>
+<span class="source-line-no">360</span><span id="line-360">  }</span>
+<span class="source-line-no">361</span><span id="line-361"></span>
+<span class="source-line-no">362</span><span id="line-362">  /**</span>
+<span class="source-line-no">363</span><span id="line-363">   * Find a coprocessor environment by class name</span>
+<span class="source-line-no">364</span><span id="line-364">   * @param className the class name</span>
+<span class="source-line-no">365</span><span id="line-365">   * @return the coprocessor, or null if not found</span>
+<span class="source-line-no">366</span><span id="line-366">   */</span>
+<span class="source-line-no">367</span><span id="line-367">  public E findCoprocessorEnvironment(String className) {</span>
+<span class="source-line-no">368</span><span id="line-368">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">369</span><span id="line-369">      if (</span>
+<span class="source-line-no">370</span><span id="line-370">        env.getInstance().getClass().getName().equals(className)</span>
+<span class="source-line-no">371</span><span id="line-371">          || env.getInstance().getClass().getSimpleName().equals(className)</span>
+<span class="source-line-no">372</span><span id="line-372">      ) {</span>
+<span class="source-line-no">373</span><span id="line-373">        return env;</span>
+<span class="source-line-no">374</span><span id="line-374">      }</span>
+<span class="source-line-no">375</span><span id="line-375">    }</span>
+<span class="source-line-no">376</span><span id="line-376">    return null;</span>
+<span class="source-line-no">377</span><span id="line-377">  }</span>
+<span class="source-line-no">378</span><span id="line-378"></span>
+<span class="source-line-no">379</span><span id="line-379">  /**</span>
+<span class="source-line-no">380</span><span id="line-380">   * Retrieves the set of classloaders used to instantiate Coprocessor classes defined in external</span>
+<span class="source-line-no">381</span><span id="line-381">   * jar files.</span>
+<span class="source-line-no">382</span><span id="line-382">   * @return A set of ClassLoader instances</span>
+<span class="source-line-no">383</span><span id="line-383">   */</span>
+<span class="source-line-no">384</span><span id="line-384">  Set&lt;ClassLoader&gt; getExternalClassLoaders() {</span>
+<span class="source-line-no">385</span><span id="line-385">    Set&lt;ClassLoader&gt; externalClassLoaders = new HashSet&lt;&gt;();</span>
+<span class="source-line-no">386</span><span id="line-386">    final ClassLoader systemClassLoader = this.getClass().getClassLoader();</span>
+<span class="source-line-no">387</span><span id="line-387">    for (E env : coprocEnvironments) {</span>
+<span class="source-line-no">388</span><span id="line-388">      ClassLoader cl = env.getInstance().getClass().getClassLoader();</span>
+<span class="source-line-no">389</span><span id="line-389">      if (cl != systemClassLoader) {</span>
+<span class="source-line-no">390</span><span id="line-390">        // do not include system classloader</span>
+<span class="source-line-no">391</span><span id="line-391">        externalClassLoaders.add(cl);</span>
+<span class="source-line-no">392</span><span id="line-392">      }</span>
+<span class="source-line-no">393</span><span id="line-393">    }</span>
+<span class="source-line-no">394</span><span id="line-394">    return externalClassLoaders;</span>
+<span class="source-line-no">395</span><span id="line-395">  }</span>
+<span class="source-line-no">396</span><span id="line-396"></span>
+<span class="source-line-no">397</span><span id="line-397">  /**</span>
+<span class="source-line-no">398</span><span id="line-398">   * Environment priority comparator. Coprocessors are chained in sorted order.</span>
+<span class="source-line-no">399</span><span id="line-399">   */</span>
+<span class="source-line-no">400</span><span id="line-400">  static class EnvironmentPriorityComparator implements Comparator&lt;CoprocessorEnvironment&gt; {</span>
+<span class="source-line-no">401</span><span id="line-401">    @Override</span>
+<span class="source-line-no">402</span><span id="line-402">    public int compare(final CoprocessorEnvironment env1, final CoprocessorEnvironment env2) {</span>
+<span class="source-line-no">403</span><span id="line-403">      if (env1.getPriority() &lt; env2.getPriority()) {</span>
+<span class="source-line-no">404</span><span id="line-404">        return -1;</span>
+<span class="source-line-no">405</span><span id="line-405">      } else if (env1.getPriority() &gt; env2.getPriority()) {</span>
+<span class="source-line-no">406</span><span id="line-406">        return 1;</span>
+<span class="source-line-no">407</span><span id="line-407">      }</span>
+<span class="source-line-no">408</span><span id="line-408">      if (env1.getLoadSequence() &lt; env2.getLoadSequence()) {</span>
+<span class="source-line-no">409</span><span id="line-409">        return -1;</span>
+<span class="source-line-no">410</span><span id="line-410">      } else if (env1.getLoadSequence() &gt; env2.getLoadSequence()) {</span>
+<span class="source-line-no">411</span><span id="line-411">        return 1;</span>
+<span class="source-line-no">412</span><span id="line-412">      }</span>
+<span class="source-line-no">413</span><span id="line-413">      return 0;</span>
+<span class="source-line-no">414</span><span id="line-414">    }</span>
+<span class="source-line-no">415</span><span id="line-415">  }</span>
+<span class="source-line-no">416</span><span id="line-416"></span>
+<span class="source-line-no">417</span><span id="line-417">  protected void abortServer(final E environment, final Throwable e) {</span>
+<span class="source-line-no">418</span><span id="line-418">    abortServer(environment.getInstance().getClass().getName(), e);</span>
+<span class="source-line-no">419</span><span id="line-419">  }</span>
+<span class="source-line-no">420</span><span id="line-420"></span>
+<span class="source-line-no">421</span><span id="line-421">  protected void abortServer(final String coprocessorName, final Throwable e) {</span>
+<span class="source-line-no">422</span><span id="line-422">    String message = "The coprocessor " + coprocessorName + " threw " + e.toString();</span>
+<span class="source-line-no">423</span><span id="line-423">    LOG.error(message, e);</span>
+<span class="source-line-no">424</span><span id="line-424">    if (abortable != null) {</span>
+<span class="source-line-no">425</span><span id="line-425">      abortable.abort(message, e);</span>
+<span class="source-line-no">426</span><span id="line-426">    } else {</span>
+<span class="source-line-no">427</span><span id="line-427">      LOG.warn("No available Abortable, process was not aborted");</span>
+<span class="source-line-no">428</span><span id="line-428">    }</span>
+<span class="source-line-no">429</span><span id="line-429">  }</span>
+<span class="source-line-no">430</span><span id="line-430"></span>
+<span class="source-line-no">431</span><span id="line-431">  /**</span>
+<span class="source-line-no">432</span><span id="line-432">   * This is used by coprocessor hooks which are declared to throw IOException (or its subtypes).</span>
+<span class="source-line-no">433</span><span id="line-433">   * For such hooks, we should handle throwable objects depending on the Throwable's type. Those</span>
+<span class="source-line-no">434</span><span id="line-434">   * which are instances of IOException should be passed on to the client. This is in conformance</span>
+<span class="source-line-no">435</span><span id="line-435">   * with the HBase idiom regarding IOException: that it represents a circumstance that should be</span>
+<span class="source-line-no">436</span><span id="line-436">   * passed along to the client for its own handling. For example, a coprocessor that implements</span>
+<span class="source-line-no">437</span><span id="line-437">   * access controls would throw a subclass of IOException, such as AccessDeniedException, in its</span>
+<span class="source-line-no">438</span><span id="line-438">   * preGet() method to prevent an unauthorized client's performing a Get on a particular table.</span>
+<span class="source-line-no">439</span><span id="line-439">   * @param env Coprocessor Environment</span>
+<span class="source-line-no">440</span><span id="line-440">   * @param e   Throwable object thrown by coprocessor.</span>
+<span class="source-line-no">441</span><span id="line-441">   * @exception IOException Exception</span>
+<span class="source-line-no">442</span><span id="line-442">   */</span>
+<span class="source-line-no">443</span><span id="line-443">  // Note to devs: Class comments of all observers ({@link MasterObserver}, {@link WALObserver},</span>
+<span class="source-line-no">444</span><span id="line-444">  // etc) mention this nuance of our exception handling so that coprocessor can throw appropriate</span>
+<span class="source-line-no">445</span><span id="line-445">  // exceptions depending on situation. If any changes are made to this logic, make sure to</span>
+<span class="source-line-no">446</span><span id="line-446">  // update all classes' comments.</span>
+<span class="source-line-no">447</span><span id="line-447">  protected void handleCoprocessorThrowable(final E env, final Throwable e) throws IOException {</span>
+<span class="source-line-no">448</span><span id="line-448">    if (e instanceof IOException) {</span>
+<span class="source-line-no">449</span><span id="line-449">      throw (IOException) e;</span>
+<span class="source-line-no">450</span><span id="line-450">    }</span>
+<span class="source-line-no">451</span><span id="line-451">    // If we got here, e is not an IOException. A loaded coprocessor has a</span>
+<span class="source-line-no">452</span><span id="line-452">    // fatal bug, and the server (master or regionserver) should remove the</span>
+<span class="source-line-no">453</span><span id="line-453">    // faulty coprocessor from its set of active coprocessors. Setting</span>
+<span class="source-line-no">454</span><span id="line-454">    // 'hbase.coprocessor.abortonerror' to true will cause abortServer(),</span>
+<span class="source-line-no">455</span><span id="line-455">    // which may be useful in development and testing environments where</span>
+<span class="source-line-no">456</span><span id="line-456">    // 'failing fast' for error analysis is desired.</span>
+<span class="source-line-no">457</span><span id="line-457">    if (env.getConfiguration().getBoolean(ABORT_ON_ERROR_KEY, DEFAULT_ABORT_ON_ERROR)) {</span>
+<span class="source-line-no">458</span><span id="line-458">      // server is configured to abort.</span>
+<span class="source-line-no">459</span><span id="line-459">      abortServer(env, e);</span>
+<span class="source-line-no">460</span><span id="line-460">    } else {</span>
+<span class="source-line-no">461</span><span id="line-461">      // If available, pull a table name out of the environment</span>
+<span class="source-line-no">462</span><span id="line-462">      if (env instanceof RegionCoprocessorEnvironment) {</span>
+<span class="source-line-no">463</span><span id="line-463">        String tableName =</span>
+<span class="source-line-no">464</span><span id="line-464">          ((RegionCoprocessorEnvironment) env).getRegionInfo().getTable().getNameAsString();</span>
+<span class="source-line-no">465</span><span id="line-465">        LOG.error("Removing coprocessor '" + env.toString() + "' from table '" + tableName + "'",</span>
+<span class="source-line-no">466</span><span id="line-466">          e);</span>
+<span class="source-line-no">467</span><span id="line-467">      } else {</span>
+<span class="source-line-no">468</span><span id="line-468">        LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment", e);</span>
+<span class="source-line-no">469</span><span id="line-469">      }</span>
+<span class="source-line-no">470</span><span id="line-470"></span>
+<span class="source-line-no">471</span><span id="line-471">      coprocEnvironments.remove(env);</span>
+<span class="source-line-no">472</span><span id="line-472">      try {</span>
+<span class="source-line-no">473</span><span id="line-473">        shutdown(env);</span>
+<span class="source-line-no">474</span><span id="line-474">      } catch (Exception x) {</span>
+<span class="source-line-no">475</span><span id="line-475">        LOG.error("Uncaught exception when shutting down coprocessor '" + env.toString() + "'", x);</span>
+<span class="source-line-no">476</span><span id="line-476">      }</span>
+<span class="source-line-no">477</span><span id="line-477">      throw new DoNotRetryIOException("Coprocessor: '" + env.toString() + "' threw: '" + e</span>
+<span class="source-line-no">478</span><span id="line-478">        + "' and has been removed from the active " + "coprocessor set.", e);</span>
+<span class="source-line-no">479</span><span id="line-479">    }</span>
+<span class="source-line-no">480</span><span id="line-480">  }</span>
+<span class="source-line-no">481</span><span id="line-481"></span>
+<span class="source-line-no">482</span><span id="line-482">  /**</span>
+<span class="source-line-no">483</span><span id="line-483">   * Used to limit legacy handling to once per Coprocessor class per classloader.</span>
+<span class="source-line-no">484</span><span id="line-484">   */</span>
+<span class="source-line-no">485</span><span id="line-485">  private static final Set&lt;Class&lt;? extends Coprocessor&gt;&gt; legacyWarning =</span>
+<span class="source-line-no">486</span><span id="line-486">    new ConcurrentSkipListSet&lt;&gt;(new Comparator&lt;Class&lt;? extends Coprocessor&gt;&gt;() {</span>
+<span class="source-line-no">487</span><span id="line-487">      @Override</span>
+<span class="source-line-no">488</span><span id="line-488">      public int compare(Class&lt;? extends Coprocessor&gt; c1, Class&lt;? extends Coprocessor&gt; c2) {</span>
+<span class="source-line-no">489</span><span id="line-489">        if (c1.equals(c2)) {</span>
+<span class="source-line-no">490</span><span id="line-490">          return 0;</span>
+<span class="source-line-no">491</span><span id="line-491">        }</span>
+<span class="source-line-no">492</span><span id="line-492">        return c1.getName().compareTo(c2.getName());</span>
+<span class="source-line-no">493</span><span id="line-493">      }</span>
+<span class="source-line-no">494</span><span id="line-494">    });</span>
+<span class="source-line-no">495</span><span id="line-495"></span>
+<span class="source-line-no">496</span><span id="line-496">  /**</span>
+<span class="source-line-no">497</span><span id="line-497">   * Implementations defined function to get an observer of type {@code O} from a coprocessor of</span>
+<span class="source-line-no">498</span><span id="line-498">   * type {@code C}. Concrete implementations of CoprocessorHost define one getter for each observer</span>
+<span class="source-line-no">499</span><span id="line-499">   * they can handle. For e.g. RegionCoprocessorHost will use 3 getters, one for each of</span>
+<span class="source-line-no">500</span><span id="line-500">   * RegionObserver, EndpointObserver and BulkLoadObserver. These getters are used by</span>
+<span class="source-line-no">501</span><span id="line-501">   * {@code ObserverOperation} to get appropriate observer from the coprocessor.</span>
+<span class="source-line-no">502</span><span id="line-502">   */</span>
+<span class="source-line-no">503</span><span id="line-503">  @FunctionalInterface</span>
+<span class="source-line-no">504</span><span id="line-504">  public interface ObserverGetter&lt;C, O&gt; extends Function&lt;C, Optional&lt;O&gt;&gt; {</span>
+<span class="source-line-no">505</span><span id="line-505">  }</span>
+<span class="source-line-no">506</span><span id="line-506"></span>
+<span class="source-line-no">507</span><span id="line-507">  private abstract class ObserverOperation&lt;O&gt; extends ObserverContextImpl&lt;E&gt; {</span>
+<span class="source-line-no">508</span><span id="line-508">    ObserverGetter&lt;C, O&gt; observerGetter;</span>
+<span class="source-line-no">509</span><span id="line-509"></span>
+<span class="source-line-no">510</span><span id="line-510">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
+<span class="source-line-no">511</span><span id="line-511">      this(observerGetter, null);</span>
+<span class="source-line-no">512</span><span id="line-512">    }</span>
+<span class="source-line-no">513</span><span id="line-513"></span>
+<span class="source-line-no">514</span><span id="line-514">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
+<span class="source-line-no">515</span><span id="line-515">      this(observerGetter, user, false);</span>
+<span class="source-line-no">516</span><span id="line-516">    }</span>
+<span class="source-line-no">517</span><span id="line-517"></span>
+<span class="source-line-no">518</span><span id="line-518">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, boolean bypassable) {</span>
+<span class="source-line-no">519</span><span id="line-519">      this(observerGetter, null, bypassable);</span>
+<span class="source-line-no">520</span><span id="line-520">    }</span>
+<span class="source-line-no">521</span><span id="line-521"></span>
+<span class="source-line-no">522</span><span id="line-522">    ObserverOperation(ObserverGetter&lt;C, O&gt; observerGetter, User user, boolean bypassable) {</span>
+<span class="source-line-no">523</span><span id="line-523">      super(user != null ? user : RpcServer.getRequestUser().orElse(null), bypassable);</span>
+<span class="source-line-no">524</span><span id="line-524">      this.observerGetter = observerGetter;</span>
+<span class="source-line-no">525</span><span id="line-525">    }</span>
 <span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527">    protected void postEnvCall() {</span>
-<span class="source-line-no">528</span><span id="line-528">    }</span>
-<span class="source-line-no">529</span><span id="line-529">  }</span>
-<span class="source-line-no">530</span><span id="line-530"></span>
-<span class="source-line-no">531</span><span id="line-531">  // Can't derive ObserverOperation from ObserverOperationWithResult (R = Void) because then all</span>
-<span class="source-line-no">532</span><span id="line-532">  // ObserverCaller implementations will have to have a return statement.</span>
-<span class="source-line-no">533</span><span id="line-533">  // O = observer, E = environment, C = coprocessor, R=result type</span>
-<span class="source-line-no">534</span><span id="line-534">  public abstract class ObserverOperationWithoutResult&lt;O&gt; extends ObserverOperation&lt;O&gt; {</span>
-<span class="source-line-no">535</span><span id="line-535">    protected abstract void call(O observer) throws IOException;</span>
-<span class="source-line-no">536</span><span id="line-536"></span>
-<span class="source-line-no">537</span><span id="line-537">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
-<span class="source-line-no">538</span><span id="line-538">      super(observerGetter);</span>
-<span class="source-line-no">539</span><span id="line-539">    }</span>
-<span class="source-line-no">540</span><span id="line-540"></span>
-<span class="source-line-no">541</span><span id="line-541">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
-<span class="source-line-no">542</span><span id="line-542">      super(observerGetter, user);</span>
-<span class="source-line-no">543</span><span id="line-543">    }</span>
-<span class="source-line-no">544</span><span id="line-544"></span>
-<span class="source-line-no">545</span><span id="line-545">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user,</span>
-<span class="source-line-no">546</span><span id="line-546">      boolean bypassable) {</span>
-<span class="source-line-no">547</span><span id="line-547">      super(observerGetter, user, bypassable);</span>
-<span class="source-line-no">548</span><span id="line-548">    }</span>
-<span class="source-line-no">549</span><span id="line-549"></span>
-<span class="source-line-no">550</span><span id="line-550">    /**</span>
-<span class="source-line-no">551</span><span id="line-551">     * In case of coprocessors which have many kinds of observers (for eg, {@link RegionCoprocessor}</span>
-<span class="source-line-no">552</span><span id="line-552">     * has BulkLoadObserver, RegionObserver, etc), some implementations may not need all observers,</span>
-<span class="source-line-no">553</span><span id="line-553">     * in which case they will return null for that observer's getter. We simply ignore such cases.</span>
-<span class="source-line-no">554</span><span id="line-554">     */</span>
-<span class="source-line-no">555</span><span id="line-555">    @Override</span>
-<span class="source-line-no">556</span><span id="line-556">    void callObserver() throws IOException {</span>
-<span class="source-line-no">557</span><span id="line-557">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
-<span class="source-line-no">558</span><span id="line-558">      if (observer.isPresent()) {</span>
-<span class="source-line-no">559</span><span id="line-559">        call(observer.get());</span>
-<span class="source-line-no">560</span><span id="line-560">      }</span>
-<span class="source-line-no">561</span><span id="line-561">    }</span>
-<span class="source-line-no">562</span><span id="line-562">  }</span>
-<span class="source-line-no">563</span><span id="line-563"></span>
-<span class="source-line-no">564</span><span id="line-564">  public abstract class ObserverOperationWithResult&lt;O, R&gt; extends ObserverOperation&lt;O&gt; {</span>
-<span class="source-line-no">565</span><span id="line-565">    protected abstract R call(O observer) throws IOException;</span>
-<span class="source-line-no">566</span><span id="line-566"></span>
-<span class="source-line-no">567</span><span id="line-567">    private R result;</span>
+<span class="source-line-no">527</span><span id="line-527">    abstract void callObserver() throws IOException;</span>
+<span class="source-line-no">528</span><span id="line-528"></span>
+<span class="source-line-no">529</span><span id="line-529">    protected void postEnvCall() {</span>
+<span class="source-line-no">530</span><span id="line-530">    }</span>
+<span class="source-line-no">531</span><span id="line-531">  }</span>
+<span class="source-line-no">532</span><span id="line-532"></span>
+<span class="source-line-no">533</span><span id="line-533">  // Can't derive ObserverOperation from ObserverOperationWithResult (R = Void) because then all</span>
+<span class="source-line-no">534</span><span id="line-534">  // ObserverCaller implementations will have to have a return statement.</span>
+<span class="source-line-no">535</span><span id="line-535">  // O = observer, E = environment, C = coprocessor, R=result type</span>
+<span class="source-line-no">536</span><span id="line-536">  public abstract class ObserverOperationWithoutResult&lt;O&gt; extends ObserverOperation&lt;O&gt; {</span>
+<span class="source-line-no">537</span><span id="line-537">    protected abstract void call(O observer) throws IOException;</span>
+<span class="source-line-no">538</span><span id="line-538"></span>
+<span class="source-line-no">539</span><span id="line-539">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter) {</span>
+<span class="source-line-no">540</span><span id="line-540">      super(observerGetter);</span>
+<span class="source-line-no">541</span><span id="line-541">    }</span>
+<span class="source-line-no">542</span><span id="line-542"></span>
+<span class="source-line-no">543</span><span id="line-543">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user) {</span>
+<span class="source-line-no">544</span><span id="line-544">      super(observerGetter, user);</span>
+<span class="source-line-no">545</span><span id="line-545">    }</span>
+<span class="source-line-no">546</span><span id="line-546"></span>
+<span class="source-line-no">547</span><span id="line-547">    public ObserverOperationWithoutResult(ObserverGetter&lt;C, O&gt; observerGetter, User user,</span>
+<span class="source-line-no">548</span><span id="line-548">      boolean bypassable) {</span>
+<span class="source-line-no">549</span><span id="line-549">      super(observerGetter, user, bypassable);</span>
+<span class="source-line-no">550</span><span id="line-550">    }</span>
+<span class="source-line-no">551</span><span id="line-551"></span>
+<span class="source-line-no">552</span><span id="line-552">    /**</span>
+<span class="source-line-no">553</span><span id="line-553">     * In case of coprocessors which have many kinds of observers (for eg, {@link RegionCoprocessor}</span>
+<span class="source-line-no">554</span><span id="line-554">     * has BulkLoadObserver, RegionObserver, etc), some implementations may not need all observers,</span>
+<span class="source-line-no">555</span><span id="line-555">     * in which case they will return null for that observer's getter. We simply ignore such cases.</span>
+<span class="source-line-no">556</span><span id="line-556">     */</span>
+<span class="source-line-no">557</span><span id="line-557">    @Override</span>
+<span class="source-line-no">558</span><span id="line-558">    void callObserver() throws IOException {</span>
+<span class="source-line-no">559</span><span id="line-559">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
+<span class="source-line-no">560</span><span id="line-560">      if (observer.isPresent()) {</span>
+<span class="source-line-no">561</span><span id="line-561">        call(observer.get());</span>
+<span class="source-line-no">562</span><span id="line-562">      }</span>
+<span class="source-line-no">563</span><span id="line-563">    }</span>
+<span class="source-line-no">564</span><span id="line-564">  }</span>
+<span class="source-line-no">565</span><span id="line-565"></span>
+<span class="source-line-no">566</span><span id="line-566">  public abstract class ObserverOperationWithResult&lt;O, R&gt; extends ObserverOperation&lt;O&gt; {</span>
+<span class="source-line-no">567</span><span id="line-567">    protected abstract R call(O observer) throws IOException;</span>
 <span class="source-line-no">568</span><span id="line-568"></span>
-<span class="source-line-no">569</span><span id="line-569">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result) {</span>
-<span class="source-line-no">570</span><span id="line-570">      this(observerGetter, result, false);</span>
-<span class="source-line-no">571</span><span id="line-571">    }</span>
-<span class="source-line-no">572</span><span id="line-572"></span>
-<span class="source-line-no">573</span><span id="line-573">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result,</span>
-<span class="source-line-no">574</span><span id="line-574">      boolean bypassable) {</span>
-<span class="source-line-no">575</span><span id="line-575">      this(observerGetter, result, null, bypassable);</span>
-<span class="source-line-no">576</span><span id="line-576">    }</span>
-<span class="source-line-no">577</span><span id="line-577"></span>
-<span class="source-line-no">578</span><span id="line-578">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user) {</span>
-<span class="source-line-no">579</span><span id="line-579">      this(observerGetter, result, user, false);</span>
-<span class="source-line-no">580</span><span id="line-580">    }</span>
-<span class="source-line-no">581</span><span id="line-581"></span>
-<span class="source-line-no">582</span><span id="line-582">    private ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user,</span>
-<span class="source-line-no">583</span><span id="line-583">      boolean bypassable) {</span>
-<span class="source-line-no">584</span><span id="line-584">      super(observerGetter, user, bypassable);</span>
-<span class="source-line-no">585</span><span id="line-585">      this.result = result;</span>
-<span class="source-line-no">586</span><span id="line-586">    }</span>
-<span class="source-line-no">587</span><span id="line-587"></span>
-<span class="source-line-no">588</span><span id="line-588">    protected R getResult() {</span>
-<span class="source-line-no">589</span><span id="line-589">      return this.result;</span>
-<span class="source-line-no">590</span><span id="line-590">    }</span>
-<span class="source-line-no">591</span><span id="line-591"></span>
-<span class="source-line-no">592</span><span id="line-592">    @Override</span>
-<span class="source-line-no">593</span><span id="line-593">    void callObserver() throws IOException {</span>
-<span class="source-line-no">594</span><span id="line-594">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
-<span class="source-line-no">595</span><span id="line-595">      if (observer.isPresent()) {</span>
-<span class="source-line-no">596</span><span id="line-596">        result = call(observer.get());</span>
-<span class="source-line-no">597</span><span id="line-597">      }</span>
-<span class="source-line-no">598</span><span id="line-598">    }</span>
-<span class="source-line-no">599</span><span id="line-599">  }</span>
-<span class="source-line-no">600</span><span id="line-600"></span>
-<span class="source-line-no">601</span><span id="line-601">  //////////////////////////////////////////////////////////////////////////////////////////</span>
-<span class="source-line-no">602</span><span id="line-602">  // Functions to execute observer hooks and handle results (if any)</span>
+<span class="source-line-no">569</span><span id="line-569">    private R result;</span>
+<span class="source-line-no">570</span><span id="line-570"></span>
+<span class="source-line-no">571</span><span id="line-571">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result) {</span>
+<span class="source-line-no">572</span><span id="line-572">      this(observerGetter, result, false);</span>
+<span class="source-line-no">573</span><span id="line-573">    }</span>
+<span class="source-line-no">574</span><span id="line-574"></span>
+<span class="source-line-no">575</span><span id="line-575">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result,</span>
+<span class="source-line-no">576</span><span id="line-576">      boolean bypassable) {</span>
+<span class="source-line-no">577</span><span id="line-577">      this(observerGetter, result, null, bypassable);</span>
+<span class="source-line-no">578</span><span id="line-578">    }</span>
+<span class="source-line-no">579</span><span id="line-579"></span>
+<span class="source-line-no">580</span><span id="line-580">    public ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user) {</span>
+<span class="source-line-no">581</span><span id="line-581">      this(observerGetter, result, user, false);</span>
+<span class="source-line-no">582</span><span id="line-582">    }</span>
+<span class="source-line-no">583</span><span id="line-583"></span>
+<span class="source-line-no">584</span><span id="line-584">    private ObserverOperationWithResult(ObserverGetter&lt;C, O&gt; observerGetter, R result, User user,</span>
+<span class="source-line-no">585</span><span id="line-585">      boolean bypassable) {</span>
+<span class="source-line-no">586</span><span id="line-586">      super(observerGetter, user, bypassable);</span>
+<span class="source-line-no">587</span><span id="line-587">      this.result = result;</span>
+<span class="source-line-no">588</span><span id="line-588">    }</span>
+<span class="source-line-no">589</span><span id="line-589"></span>
+<span class="source-line-no">590</span><span id="line-590">    protected R getResult() {</span>
+<span class="source-line-no">591</span><span id="line-591">      return this.result;</span>
+<span class="source-line-no">592</span><span id="line-592">    }</span>
+<span class="source-line-no">593</span><span id="line-593"></span>
+<span class="source-line-no">594</span><span id="line-594">    @Override</span>
+<span class="source-line-no">595</span><span id="line-595">    void callObserver() throws IOException {</span>
+<span class="source-line-no">596</span><span id="line-596">      Optional&lt;O&gt; observer = observerGetter.apply(getEnvironment().getInstance());</span>
+<span class="source-line-no">597</span><span id="line-597">      if (observer.isPresent()) {</span>
+<span class="source-line-no">598</span><span id="line-598">        result = call(observer.get());</span>
+<span class="source-line-no">599</span><span id="line-599">      }</span>
+<span class="source-line-no">600</span><span id="line-600">    }</span>
+<span class="source-line-no">601</span><span id="line-601">  }</span>
+<span class="source-line-no">602</span><span id="line-602"></span>
 <span class="source-line-no">603</span><span id="line-603">  //////////////////////////////////////////////////////////////////////////////////////////</span>
-<span class="source-line-no">604</span><span id="line-604"></span>
-<span class="source-line-no">605</span><span id="line-605">  /**</span>
-<span class="source-line-no">606</span><span id="line-606">   * Do not call with an observerOperation that is null! Have the caller check.</span>
-<span class="source-line-no">607</span><span id="line-607">   */</span>
-<span class="source-line-no">608</span><span id="line-608">  protected &lt;O, R&gt; R execOperationWithResult(</span>
-<span class="source-line-no">609</span><span id="line-609">    final ObserverOperationWithResult&lt;O, R&gt; observerOperation) throws IOException {</span>
-<span class="source-line-no">610</span><span id="line-610">    boolean bypass = execOperation(observerOperation);</span>
-<span class="source-line-no">611</span><span id="line-611">    R result = observerOperation.getResult();</span>
-<span class="source-line-no">612</span><span id="line-612">    return bypass == observerOperation.isBypassable() ? result : null;</span>
-<span class="source-line-no">613</span><span id="line-613">  }</span>
-<span class="source-line-no">614</span><span id="line-614"></span>
-<span class="source-line-no">615</span><span id="line-615">  /**</span>
-<span class="source-line-no">616</span><span id="line-616">   * @return True if we are to bypass (Can only be &lt;code&gt;true&lt;/code&gt; if</span>
-<span class="source-line-no">617</span><span id="line-617">   *         ObserverOperation#isBypassable().</span>
-<span class="source-line-no">618</span><span id="line-618">   */</span>
-<span class="source-line-no">619</span><span id="line-619">  protected &lt;O&gt; boolean execOperation(final ObserverOperation&lt;O&gt; observerOperation)</span>
-<span class="source-line-no">620</span><span id="line-620">    throws IOException {</span>
-<span class="source-line-no">621</span><span id="line-621">    boolean bypass = false;</span>
-<span class="source-line-no">622</span><span id="line-622">    if (observerOperation == null) {</span>
-<span class="source-line-no">623</span><span id="line-623">      return bypass;</span>
-<span class="source-line-no">624</span><span id="line-624">    }</span>
-<span class="source-line-no">625</span><span id="line-625">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
-<span class="source-line-no">626</span><span id="line-626">    for (E env : envs) {</span>
-<span class="source-line-no">627</span><span id="line-627">      observerOperation.prepare(env);</span>
-<span class="source-line-no">628</span><span id="line-628">      Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">629</span><span id="line-629">      ClassLoader cl = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">630</span><span id="line-630">      try {</span>
-<span class="source-line-no">631</span><span id="line-631">        currentThread.setContextClassLoader(env.getClassLoader());</span>
-<span class="source-line-no">632</span><span id="line-632">        observerOperation.callObserver();</span>
-<span class="source-line-no">633</span><span id="line-633">      } catch (Throwable e) {</span>
-<span class="source-line-no">634</span><span id="line-634">        handleCoprocessorThrowable(env, e);</span>
-<span class="source-line-no">635</span><span id="line-635">      } finally {</span>
-<span class="source-line-no">636</span><span id="line-636">        currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">637</span><span id="line-637">      }</span>
-<span class="source-line-no">638</span><span id="line-638">      // Internal to shouldBypass, it checks if obeserverOperation#isBypassable().</span>
-<span class="source-line-no">639</span><span id="line-639">      bypass |= observerOperation.shouldBypass();</span>
-<span class="source-line-no">640</span><span id="line-640">      observerOperation.postEnvCall();</span>
-<span class="source-line-no">641</span><span id="line-641">      if (bypass) {</span>
-<span class="source-line-no">642</span><span id="line-642">        // If CP says bypass, skip out w/o calling any following CPs; they might ruin our response.</span>
-<span class="source-line-no">643</span><span id="line-643">        // In hbase1, this used to be called 'complete'. In hbase2, we unite bypass and 'complete'.</span>
-<span class="source-line-no">644</span><span id="line-644">        break;</span>
-<span class="source-line-no">645</span><span id="line-645">      }</span>
-<span class="source-line-no">646</span><span id="line-646">    }</span>
-<span class="source-line-no">647</span><span id="line-647">    return bypass;</span>
-<span class="source-line-no">648</span><span id="line-648">  }</span>
-<span class="source-line-no">649</span><span id="line-649"></span>
-<span class="source-line-no">650</span><span id="line-650">  /**</span>
-<span class="source-line-no">651</span><span id="line-651">   * Coprocessor classes can be configured in any order, based on that priority is set and chained</span>
-<span class="source-line-no">652</span><span id="line-652">   * in a sorted order. Should be used preStop*() hooks i.e. when master/regionserver is going down.</span>
-<span class="source-line-no">653</span><span id="line-653">   * This function first calls coprocessor methods (using ObserverOperation.call()) and then</span>
-<span class="source-line-no">654</span><span id="line-654">   * shutdowns the environment in postEnvCall(). &lt;br&gt;</span>
-<span class="source-line-no">655</span><span id="line-655">   * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors</span>
-<span class="source-line-no">656</span><span id="line-656">   * may remain shutdown if any exception occurs during next coprocessor execution which prevent</span>
-<span class="source-line-no">657</span><span id="line-657">   * master/regionserver stop or cluster shutdown. (Refer:</span>
-<span class="source-line-no">658</span><span id="line-658">   * &lt;a href="https://issues.apache.org/jira/browse/HBASE-16663"&gt;HBASE-16663&lt;/a&gt;</span>
-<span class="source-line-no">659</span><span id="line-659">   * @return true if bypaas coprocessor execution, false if not.</span>
-<span class="source-line-no">660</span><span id="line-660">   */</span>
-<span class="source-line-no">661</span><span id="line-661">  protected &lt;O&gt; boolean execShutdown(final ObserverOperation&lt;O&gt; observerOperation)</span>
-<span class="source-line-no">662</span><span id="line-662">    throws IOException {</span>
-<span class="source-line-no">663</span><span id="line-663">    if (observerOperation == null) return false;</span>
-<span class="source-line-no">664</span><span id="line-664">    boolean bypass = false;</span>
-<span class="source-line-no">665</span><span id="line-665">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
-<span class="source-line-no">666</span><span id="line-666">    // Iterate the coprocessors and execute ObserverOperation's call()</span>
-<span class="source-line-no">667</span><span id="line-667">    for (E env : envs) {</span>
-<span class="source-line-no">668</span><span id="line-668">      observerOperation.prepare(env);</span>
-<span class="source-line-no">669</span><span id="line-669">      Thread currentThread = Thread.currentThread();</span>
-<span class="source-line-no">670</span><span id="line-670">      ClassLoader cl = currentThread.getContextClassLoader();</span>
-<span class="source-line-no">671</span><span id="line-671">      try {</span>
-<span class="source-line-no">672</span><span id="line-672">        currentThread.setContextClassLoader(env.getClassLoader());</span>
-<span class="source-line-no">673</span><span id="line-673">        observerOperation.callObserver();</span>
-<span class="source-line-no">674</span><span id="line-674">      } catch (Throwable e) {</span>
-<span class="source-line-no">675</span><span id="line-675">        handleCoprocessorThrowable(env, e);</span>
-<span class="source-line-no">676</span><span id="line-676">      } finally {</span>
-<span class="source-line-no">677</span><span id="line-677">        currentThread.setContextClassLoader(cl);</span>
-<span class="source-line-no">678</span><span id="line-678">      }</span>
-<span class="source-line-no">679</span><span id="line-679">      bypass |= observerOperation.shouldBypass();</span>
-<span class="source-line-no">680</span><span id="line-680">    }</span>
-<span class="source-line-no">681</span><span id="line-681"></span>
-<span class="source-line-no">682</span><span id="line-682">    // Iterate the coprocessors and execute ObserverOperation's postEnvCall()</span>
-<span class="source-line-no">683</span><span id="line-683">    for (E env : envs) {</span>
-<span class="source-line-no">684</span><span id="line-684">      observerOperation.prepare(env);</span>
-<span class="source-line-no">685</span><span id="line-685">      observerOperation.postEnvCall();</span>
-<span class="source-line-no">686</span><span id="line-686">    }</span>
-<span class="source-line-no">687</span><span id="line-687">    return bypass;</span>
-<span class="source-line-no">688</span><span id="line-688">  }</span>
-<span class="source-line-no">689</span><span id="line-689">}</span>
+<span class="source-line-no">604</span><span id="line-604">  // Functions to execute observer hooks and handle results (if any)</span>
+<span class="source-line-no">605</span><span id="line-605">  //////////////////////////////////////////////////////////////////////////////////////////</span>
+<span class="source-line-no">606</span><span id="line-606"></span>
+<span class="source-line-no">607</span><span id="line-607">  /**</span>
+<span class="source-line-no">608</span><span id="line-608">   * Do not call with an observerOperation that is null! Have the caller check.</span>
+<span class="source-line-no">609</span><span id="line-609">   */</span>
+<span class="source-line-no">610</span><span id="line-610">  protected &lt;O, R&gt; R execOperationWithResult(</span>
+<span class="source-line-no">611</span><span id="line-611">    final ObserverOperationWithResult&lt;O, R&gt; observerOperation) throws IOException {</span>
+<span class="source-line-no">612</span><span id="line-612">    boolean bypass = execOperation(observerOperation);</span>
+<span class="source-line-no">613</span><span id="line-613">    R result = observerOperation.getResult();</span>
+<span class="source-line-no">614</span><span id="line-614">    return bypass == observerOperation.isBypassable() ? result : null;</span>
+<span class="source-line-no">615</span><span id="line-615">  }</span>
+<span class="source-line-no">616</span><span id="line-616"></span>
+<span class="source-line-no">617</span><span id="line-617">  /**</span>
+<span class="source-line-no">618</span><span id="line-618">   * @return True if we are to bypass (Can only be &lt;code&gt;true&lt;/code&gt; if</span>
+<span class="source-line-no">619</span><span id="line-619">   *         ObserverOperation#isBypassable().</span>
+<span class="source-line-no">620</span><span id="line-620">   */</span>
+<span class="source-line-no">621</span><span id="line-621">  protected &lt;O&gt; boolean execOperation(final ObserverOperation&lt;O&gt; observerOperation)</span>
+<span class="source-line-no">622</span><span id="line-622">    throws IOException {</span>
+<span class="source-line-no">623</span><span id="line-623">    boolean bypass = false;</span>
+<span class="source-line-no">624</span><span id="line-624">    if (observerOperation == null) {</span>
+<span class="source-line-no">625</span><span id="line-625">      return bypass;</span>
+<span class="source-line-no">626</span><span id="line-626">    }</span>
+<span class="source-line-no">627</span><span id="line-627">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
+<span class="source-line-no">628</span><span id="line-628">    for (E env : envs) {</span>
+<span class="source-line-no">629</span><span id="line-629">      observerOperation.prepare(env);</span>
+<span class="source-line-no">630</span><span id="line-630">      Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">631</span><span id="line-631">      ClassLoader cl = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">632</span><span id="line-632">      try {</span>
+<span class="source-line-no">633</span><span id="line-633">        currentThread.setContextClassLoader(env.getClassLoader());</span>
+<span class="source-line-no">634</span><span id="line-634">        observerOperation.callObserver();</span>
+<span class="source-line-no">635</span><span id="line-635">      } catch (Throwable e) {</span>
+<span class="source-line-no">636</span><span id="line-636">        handleCoprocessorThrowable(env, e);</span>
+<span class="source-line-no">637</span><span id="line-637">      } finally {</span>
+<span class="source-line-no">638</span><span id="line-638">        currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">639</span><span id="line-639">      }</span>
+<span class="source-line-no">640</span><span id="line-640">      // Internal to shouldBypass, it checks if obeserverOperation#isBypassable().</span>
+<span class="source-line-no">641</span><span id="line-641">      bypass |= observerOperation.shouldBypass();</span>
+<span class="source-line-no">642</span><span id="line-642">      observerOperation.postEnvCall();</span>
+<span class="source-line-no">643</span><span id="line-643">      if (bypass) {</span>
+<span class="source-line-no">644</span><span id="line-644">        // If CP says bypass, skip out w/o calling any following CPs; they might ruin our response.</span>
+<span class="source-line-no">645</span><span id="line-645">        // In hbase1, this used to be called 'complete'. In hbase2, we unite bypass and 'complete'.</span>
+<span class="source-line-no">646</span><span id="line-646">        break;</span>
+<span class="source-line-no">647</span><span id="line-647">      }</span>
+<span class="source-line-no">648</span><span id="line-648">    }</span>
+<span class="source-line-no">649</span><span id="line-649">    return bypass;</span>
+<span class="source-line-no">650</span><span id="line-650">  }</span>
+<span class="source-line-no">651</span><span id="line-651"></span>
+<span class="source-line-no">652</span><span id="line-652">  /**</span>
+<span class="source-line-no">653</span><span id="line-653">   * Coprocessor classes can be configured in any order, based on that priority is set and chained</span>
+<span class="source-line-no">654</span><span id="line-654">   * in a sorted order. Should be used preStop*() hooks i.e. when master/regionserver is going down.</span>
+<span class="source-line-no">655</span><span id="line-655">   * This function first calls coprocessor methods (using ObserverOperation.call()) and then</span>
+<span class="source-line-no">656</span><span id="line-656">   * shutdowns the environment in postEnvCall(). &lt;br&gt;</span>
+<span class="source-line-no">657</span><span id="line-657">   * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors</span>
+<span class="source-line-no">658</span><span id="line-658">   * may remain shutdown if any exception occurs during next coprocessor execution which prevent</span>
+<span class="source-line-no">659</span><span id="line-659">   * master/regionserver stop or cluster shutdown. (Refer:</span>
+<span class="source-line-no">660</span><span id="line-660">   * &lt;a href="https://issues.apache.org/jira/browse/HBASE-16663"&gt;HBASE-16663&lt;/a&gt;</span>
+<span class="source-line-no">661</span><span id="line-661">   * @return true if bypaas coprocessor execution, false if not.</span>
+<span class="source-line-no">662</span><span id="line-662">   */</span>
+<span class="source-line-no">663</span><span id="line-663">  protected &lt;O&gt; boolean execShutdown(final ObserverOperation&lt;O&gt; observerOperation)</span>
+<span class="source-line-no">664</span><span id="line-664">    throws IOException {</span>
+<span class="source-line-no">665</span><span id="line-665">    if (observerOperation == null) return false;</span>
+<span class="source-line-no">666</span><span id="line-666">    boolean bypass = false;</span>
+<span class="source-line-no">667</span><span id="line-667">    List&lt;E&gt; envs = coprocEnvironments.get();</span>
+<span class="source-line-no">668</span><span id="line-668">    // Iterate the coprocessors and execute ObserverOperation's call()</span>
+<span class="source-line-no">669</span><span id="line-669">    for (E env : envs) {</span>
+<span class="source-line-no">670</span><span id="line-670">      observerOperation.prepare(env);</span>
+<span class="source-line-no">671</span><span id="line-671">      Thread currentThread = Thread.currentThread();</span>
+<span class="source-line-no">672</span><span id="line-672">      ClassLoader cl = currentThread.getContextClassLoader();</span>
+<span class="source-line-no">673</span><span id="line-673">      try {</span>
+<span class="source-line-no">674</span><span id="line-674">        currentThread.setContextClassLoader(env.getClassLoader());</span>
+<span class="source-line-no">675</span><span id="line-675">        observerOperation.callObserver();</span>
+<span class="source-line-no">676</span><span id="line-676">      } catch (Throwable e) {</span>
+<span class="source-line-no">677</span><span id="line-677">        handleCoprocessorThrowable(env, e);</span>
+<span class="source-line-no">678</span><span id="line-678">      } finally {</span>
+<span class="source-line-no">679</span><span id="line-679">        currentThread.setContextClassLoader(cl);</span>
+<span class="source-line-no">680</span><span id="line-680">      }</span>
+<span class="source-line-no">681</span><span id="line-681">      bypass |= observerOperation.shouldBypass();</span>
+<span class="source-line-no">682</span><span id="line-682">    }</span>
+<span class="source-line-no">683</span><span id="line-683"></span>
+<span class="source-line-no">684</span><span id="line-684">    // Iterate the coprocessors and execute ObserverOperation's postEnvCall()</span>
+<span class="source-line-no">685</span><span id="line-685">    for (E env : envs) {</span>
+<span class="source-line-no">686</span><span id="line-686">      observerOperation.prepare(env);</span>
+<span class="source-line-no">687</span><span id="line-687">      observerOperation.postEnvCall();</span>
+<span class="source-line-no">688</span><span id="line-688">    }</span>
+<span class="source-line-no">689</span><span id="line-689">    return bypass;</span>
+<span class="source-line-no">690</span><span id="line-690">  }</span>
+<span class="source-line-no">691</span><span id="line-691">}</span>
 
 
 
diff --git a/apidocs/type-search-index.js b/apidocs/type-search-index.js
index 1dbde9afffb..51876378c27 100644
--- a/apidocs/type-search-index.js
+++ b/apidocs/type-search-index.js
@@ -1 +1 @@
-typeSearchIndex = [{"p":"org.apache.hadoop.hbase","l":"Abortable"},{"p":"org.apache.hadoop.hbase.util","l":"AbstractByteRange"},{"p":"org.apache.hadoop.hbase.client","l":"AbstractClientScanner"},{"p":"org.apache.hadoop.hbase.io.encoding","l":"AbstractDataBlockEncoder"},{"p":"org.apache.hadoop.hbase.io.encoding","l":"AbstractDataBlockEncoder.AbstractEncodedSeeker"},{"p":"org.apache.hadoop.hbase.util","l":"AbstractFileStatusFilter"},{"p":"org.apache.hadoop.hbase.regionserver.wal","l":"Abst [...]
\ No newline at end of file
+typeSearchIndex = [{"p":"org.apache.hadoop.hbase","l":"Abortable"},{"p":"org.apache.hadoop.hbase.util","l":"AbstractByteRange"},{"p":"org.apache.hadoop.hbase.client","l":"AbstractClientScanner"},{"p":"org.apache.hadoop.hbase.io.encoding","l":"AbstractDataBlockEncoder"},{"p":"org.apache.hadoop.hbase.io.encoding","l":"AbstractDataBlockEncoder.AbstractEncodedSeeker"},{"p":"org.apache.hadoop.hbase.util","l":"AbstractFileStatusFilter"},{"p":"org.apache.hadoop.hbase.regionserver.wal","l":"Abst [...]
\ No newline at end of file
diff --git a/book.html b/book.html
index dcae09b80b1..2e03ba982c9 100644
--- a/book.html
+++ b/book.html
@@ -50183,7 +50183,7 @@ org/apache/hadoop/hbase/security/access/AccessControlClient.revoke:(Lorg/apache/
 <div id="footer">
 <div id="footer-text">
 Version 4.0.0-alpha-1-SNAPSHOT<br>
-Last updated 2025-12-10 14:31:46 UTC
+Last updated 2025-12-12 14:31:42 UTC
 </div>
 </div>
 <script type="text/x-mathjax-config">
diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html
index 0304e8184e5..517fef60da1 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <!--
  | Generated by Apache Maven Doxia Site Renderer 1.11.1
- from org.apache.maven.plugins:maven-checkstyle-plugin:3.6.0:checkstyle-aggregate at 2025-12-10
+ from org.apache.maven.plugins:maven-checkstyle-plugin:3.6.0:checkstyle-aggregate at 2025-12-12
 
  | Rendered using Apache Maven Default Skin
 -->
@@ -45,7 +45,7 @@ Apache HBase
 
 
       <div class="xleft">
-        <span id="publishDate">Last Published: 2025-12-10</span>
+        <span id="publishDate">Last Published: 2025-12-12</span>
            | <span id="projectVersion">Version: 4.0.0-alpha-1-SNAPSHOT</span>
 
 
@@ -961,7 +961,7 @@ Apache HBase
 <th><img src="images/icon_warning_sml.gif" alt="" />&#160;Warnings</th>
 <th><img src="images/icon_error_sml.gif" alt="" />&#160;Errors</th></tr>
 <tr class="b">
-<td>5188</td>
+<td>5193</td>
 <td>0</td>
 <td>0</td>
 <td>1857</td></tr></table></section><section><a name="Files"></a>
@@ -7621,13 +7621,13 @@ Apache HBase
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>134</td></tr>
+<td>136</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>663</td></tr></table></section><section><a name="orgapachehadoophbasecoprocessorMetricsCoprocessor.java"></a>
+<td>665</td></tr></table></section><section><a name="orgapachehadoophbasecoprocessorMetricsCoprocessor.java"></a>
 <h4><a name="org.2Fapache.2Fhadoop.2Fhbase.2Fcoprocessor.2FMetricsCoprocessor.java"></a>org/apache/hadoop/hbase/coprocessor/MetricsCoprocessor.java</h4>
 <table border="0" class="bodyTable">
 <tr class="a">
diff --git a/dependency-convergence.html b/dependency-convergence.html
index 3dba9163344..e326f3e8492 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <!--
  | Generated by Apache Maven Doxia Site Renderer 1.11.1
- from org.apache.maven.plugins:maven-project-info-reports-plugin:3.1.2:dependency-convergence at 2025-12-10
+ from org.apache.maven.plugins:maven-project-info-reports-plugin:3.1.2:dependency-convergence at 2025-12-12
 
  | Rendered using Apache Maven Default Skin
 -->
@@ -45,7 +45,7 @@ Apache HBase
 
 
       <div class="xleft">
-        <span id="publishDate">Last Published: 2025-12-10</span>
+        <span id="publishDate">Last Published: 2025-12-12</span>
            | <span id="projectVersion">Version: 4.0.0-alpha-1-SNAPSHOT</span>
 
 
diff --git a/dependency-info.html b/dependency-info.html
index fe5c507dac6..110a43bcf2b 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <!--
  | Generated by Apache Maven Doxia Site Renderer 1.11.1
- from org.apache.maven.plugins:maven-project-info-reports-plugin:3.1.2:dependency-info at 2025-12-10
+ from org.apache.maven.plugins:maven-project-info-reports-plugin:3.1.2:dependency-info at 2025-12-12
 
  | Rendered using Apache Maven Default Skin
 -->
@@ -45,7 +45,7 @@ Apache HBase
 
 
       <div class="xleft">
-        <span id="publishDate">Last Published: 2025-12-10</span>
+        <span id="publishDate">Last Published: 2025-12-12</span>
            | <span id="projectVersion">Version: 4.0.0-alpha-1-SNAPSHOT</span>
 
 
diff --git a/dependency-management.html b/dependency-management.html
index ce02a317dc7..f83720bf4c3 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <!--
  | Generated by Apache Maven Doxia Site Renderer 1.11.1
- from org.apache.maven.plugins:maven-project-info-reports-plugin:3.1.2:dependency-management at 2025-12-10
+ from org.apache.maven.plugins:maven-project-info-reports-plugin:3.1.2:dependency-management at 2025-12-12
 
  | Rendered using Apache Maven Default Skin
 -->
@@ -45,7 +45,7 @@ Apache HBase
 
 
       <div class="xleft">
-        <span id="publishDate">Last Published: 2025-12-10</span>
+        <span id="publishDate">Last Published: 2025-12-12</span>
            | <span id="projectVersion">Version: 4.0.0-alpha-1-SNAPSHOT</span>
 
 
diff --git a/devapidocs/allclasses-index.html b/devapidocs/allclasses-index.html
index 15208270c57..1669275fc00 100644
--- a/devapidocs/allclasses-index.html
+++ b/devapidocs/allclasses-index.html
@@ -2074,950 +2074,963 @@ loadScripts(document, 'script');</script>
 <div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">A helper class used to access the package private field in o.a.h.h.client package.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessor.html" title="interface in org.apache.hadoop.hbase.coprocessor">ClientMetaCoprocessor</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessorEnvironment.html" title="interface in org.apache.hadoop.hbase.coprocessor">ClientMetaCoprocessorEnvironment</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">&nbsp;</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessorHost.html" title="class in org.apache.hadoop.hbase.coprocessor">ClientMetaCoprocessorHost</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/coprocessor/ClientMetaCoprocessorHost.ClientMetaEnvironment.html" title="class in org.apache.hadoop.hbase.coprocessor">ClientMetaCoprocessorHost.ClientMetaEnvironment</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/coprocessor/ClientMetaObserver.html" title="interface in org.apache.hadoop.hbase.coprocessor">ClientMetaObserver</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
+<div class="block">Defines coprocessor hooks for interacting operations for ClientMetaService which is responsible
+ for ZooKeeperless HBase service discovery.</div>
+</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">The (asynchronous) meta table accessor used at client side.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CloseableVisitor.html" title="interface in org.apache.hadoop.hbase">ClientMetaTableAccessor.CloseableVisitor</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CloseableVisitor.html" title="interface in org.apache.hadoop.hbase">ClientMetaTableAccessor.CloseableVisitor</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
 <div class="block">Implementations 'visit' a catalog table row but with close() at the end.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CollectAllVisitor.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor.CollectAllVisitor</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CollectAllVisitor.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor.CollectAllVisitor</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Collects all returned.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CollectingVisitor.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor.CollectingVisitor</a>&lt;<a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CollectingVisitor.html" title="type parameter in ClientMetaTableAccessor.CollectingVisitor">T</a>&gt;</div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CollectingVisitor.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor.CollectingVisitor</a>&lt;<a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CollectingVisitor.html" title="type parameter in ClientMetaTableAccessor.CollectingVisitor">T</a>&gt;</div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">A <a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.Visitor.html" title="interface in org.apache.hadoop.hbase"><code>ClientMetaTableAccessor.Visitor</code></a> that collects content out of passed <a href="org/apache/hadoop/hbase/client/Result.html" title="class in org.apache.hadoop.hbase.client"><code>Result</code></a>.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CollectRegionLocationsVisitor.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor.CollectRegionLocationsVisitor</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.MetaTableScanResultConsumer.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor.MetaTableScanResultConsumer</a></div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.CollectRegionLocationsVisitor.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor.CollectRegionLocationsVisitor</a></div>
 <div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab3"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.QueryType.html" title="enum class in org.apache.hadoop.hbase">ClientMetaTableAccessor.QueryType</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab3">&nbsp;</div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.Visitor.html" title="interface in org.apache.hadoop.hbase">ClientMetaTableAccessor.Visitor</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.MetaTableScanResultConsumer.html" title="class in org.apache.hadoop.hbase">ClientMetaTableAccessor.MetaTableScanResultConsumer</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab3"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.QueryType.html" title="enum class in org.apache.hadoop.hbase">ClientMetaTableAccessor.QueryType</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab3">&nbsp;</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/ClientMetaTableAccessor.Visitor.html" title="interface in org.apache.hadoop.hbase">ClientMetaTableAccessor.Visitor</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
 <div class="block">Implementations 'visit' a catalog table row.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html" title="class in org.apache.hadoop.hbase.hbtop.mode">ClientModeStrategy</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html" title="class in org.apache.hadoop.hbase.hbtop.mode">ClientModeStrategy</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Implementation for <a href="org/apache/hadoop/hbase/hbtop/mode/ModeStrategy.html" title="interface in org.apache.hadoop.hbase.hbtop.mode"><code>ModeStrategy</code></a> for client Mode.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClientSideRegionScanner.html" title="class in org.apache.hadoop.hbase.client">ClientSideRegionScanner</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClientSideRegionScanner.html" title="class in org.apache.hadoop.hbase.client">ClientSideRegionScanner</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">A client scanner for a region opened for read-only on the client side.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/snapshot/ClientSnapshotDescriptionUtils.html" title="class in org.apache.hadoop.hbase.snapshot">ClientSnapshotDescriptionUtils</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/snapshot/ClientSnapshotDescriptionUtils.html" title="class in org.apache.hadoop.hbase.snapshot">ClientSnapshotDescriptionUtils</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Class to help with dealing with a snapshot description on the client side.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/security/token/ClientTokenUtil.html" title="class in org.apache.hadoop.hbase.security.token">ClientTokenUtil</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/security/token/ClientTokenUtil.html" title="class in org.apache.hadoop.hbase.security.token">ClientTokenUtil</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Utility methods for obtaining authentication tokens, that do not require hbase-server.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClientUtil.html" title="class in org.apache.hadoop.hbase.client">ClientUtil</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/util/ClientUtils.html" title="class in org.apache.hadoop.hbase.util">ClientUtils</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClientUtil.html" title="class in org.apache.hadoop.hbase.client">ClientUtil</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/util/ClientUtils.html" title="class in org.apache.hadoop.hbase.util">ClientUtils</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Common Utility class for clients</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/zksyncer/ClientZKSyncer.html" title="class in org.apache.hadoop.hbase.master.zksyncer">ClientZKSyncer</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/zksyncer/ClientZKSyncer.html" title="class in org.apache.hadoop.hbase.master.zksyncer">ClientZKSyncer</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Tracks the target znode(s) on server ZK cluster and synchronize them to client ZK cluster if
  changed</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/zksyncer/ClientZKSyncer.ZKData.html" title="class in org.apache.hadoop.hbase.master.zksyncer">ClientZKSyncer.ZKData</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/zksyncer/ClientZKSyncer.ZKData.html" title="class in org.apache.hadoop.hbase.master.zksyncer">ClientZKSyncer.ZKData</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Used to store the newest data which we want to sync to client zk.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab5"><a href="org/apache/hadoop/hbase/ClockOutOfSyncException.html" title="class in org.apache.hadoop.hbase">ClockOutOfSyncException</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab5">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab5"><a href="org/apache/hadoop/hbase/ClockOutOfSyncException.html" title="class in org.apache.hadoop.hbase">ClockOutOfSyncException</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab5">
 <div class="block">This exception is thrown by the master when a region server clock skew is too high.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/procedure/CloneSnapshotProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">CloneSnapshotProcedure</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/compactions/CloseChecker.html" title="class in org.apache.hadoop.hbase.regionserver.compactions">CloseChecker</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/procedure/CloneSnapshotProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">CloneSnapshotProcedure</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/compactions/CloseChecker.html" title="class in org.apache.hadoop.hbase.regionserver.compactions">CloseChecker</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Check periodically to see if a system stop is requested</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/procedure/CloseExcessRegionReplicasProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">CloseExcessRegionReplicasProcedure</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/procedure/CloseExcessRegionReplicasProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">CloseExcessRegionReplicasProcedure</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Procedure for close excess region replicas.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/handler/CloseMetaHandler.html" title="class in org.apache.hadoop.hbase.regionserver.handler">CloseMetaHandler</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/handler/CloseMetaHandler.html" title="class in org.apache.hadoop.hbase.regionserver.handler">CloseMetaHandler</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Handles closing of the meta region on a region server.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/handler/CloseRegionHandler.html" title="class in org.apache.hadoop.hbase.regionserver.handler">CloseRegionHandler</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/handler/CloseRegionHandler.html" title="class in org.apache.hadoop.hbase.regionserver.handler">CloseRegionHandler</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Handles closing of a region on a region server.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/assignment/CloseRegionProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">CloseRegionProcedure</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/assignment/CloseRegionProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">CloseRegionProcedure</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">The remote procedure used to close a region.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/procedure/CloseTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">CloseTableRegionsProcedure</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/procedure/CloseTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">CloseTableRegionsProcedure</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Procedure for closing all regions for a table.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/rest/client/Cluster.html" title="class in org.apache.hadoop.hbase.rest.client">Cluster</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/rest/client/Cluster.html" title="class in org.apache.hadoop.hbase.rest.client">Cluster</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">A list of 'host:port' addresses of HTTP servers operating as a single entity, for example
  multiple redundant web service gateways.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/util/compaction/ClusterCompactionQueues.html" title="class in org.apache.hadoop.hbase.util.compaction">ClusterCompactionQueues</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClusterConnectionFactory.html" title="class in org.apache.hadoop.hbase.client">ClusterConnectionFactory</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/util/compaction/ClusterCompactionQueues.html" title="class in org.apache.hadoop.hbase.util.compaction">ClusterCompactionQueues</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClusterConnectionFactory.html" title="class in org.apache.hadoop.hbase.client">ClusterConnectionFactory</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">The factory for creating <a href="org/apache/hadoop/hbase/client/AsyncClusterConnection.html" title="interface in org.apache.hadoop.hbase.client"><code>AsyncClusterConnection</code></a>.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClusterId.html" title="class in org.apache.hadoop.hbase">ClusterId</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClusterId.html" title="class in org.apache.hadoop.hbase">ClusterId</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">The identifier for this cluster.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClusterIdFetcher.html" title="class in org.apache.hadoop.hbase.client">ClusterIdFetcher</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClusterIdFetcher.html" title="class in org.apache.hadoop.hbase.client">ClusterIdFetcher</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Fetch cluster id through special preamble header.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/master/balancer/ClusterInfoProvider.html" title="interface in org.apache.hadoop.hbase.master.balancer">ClusterInfoProvider</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/master/balancer/ClusterInfoProvider.html" title="interface in org.apache.hadoop.hbase.master.balancer">ClusterInfoProvider</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
 <div class="block">This is the cluster we want to balance.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/balancer/ClusterLoadState.html" title="class in org.apache.hadoop.hbase.master.balancer">ClusterLoadState</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/balancer/ClusterLoadState.html" title="class in org.apache.hadoop.hbase.master.balancer">ClusterLoadState</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Class used to hold the current state of the cluster and how balanced it is.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/replication/ClusterMarkingEntryFilter.html" title="class in org.apache.hadoop.hbase.replication">ClusterMarkingEntryFilter</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/replication/ClusterMarkingEntryFilter.html" title="class in org.apache.hadoop.hbase.replication">ClusterMarkingEntryFilter</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Filters out entries with our peerClusterId (i.e.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase">ClusterMetrics</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase">ClusterMetrics</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
 <div class="block">Metrics information on the HBase cluster.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/http/api_v1/cluster_metrics/model/ClusterMetrics.html" title="class in org.apache.hadoop.hbase.master.http.api_v1.cluster_metrics.model">ClusterMetrics</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/http/api_v1/cluster_metrics/model/ClusterMetrics.html" title="class in org.apache.hadoop.hbase.master.http.api_v1.cluster_metrics.model">ClusterMetrics</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Exposes a subset of fields from <a href="org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase"><code>ClusterMetrics</code></a>.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab3"><a href="org/apache/hadoop/hbase/ClusterMetrics.Option.html" title="enum class in org.apache.hadoop.hbase">ClusterMetrics.Option</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab3">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab3"><a href="org/apache/hadoop/hbase/ClusterMetrics.Option.html" title="enum class in org.apache.hadoop.hbase">ClusterMetrics.Option</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab3">
 <div class="block">Kinds of ClusterMetrics</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClusterMetricsBuilder.html" title="class in org.apache.hadoop.hbase">ClusterMetricsBuilder</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClusterMetricsBuilder.ClusterMetricsImpl.html" title="class in org.apache.hadoop.hbase">ClusterMetricsBuilder.ClusterMetricsImpl</a></div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClusterMetricsBuilder.html" title="class in org.apache.hadoop.hbase">ClusterMetricsBuilder</a></div>
 <div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/http/api_v1/cluster_metrics/resource/ClusterMetricsResource.html" title="class in org.apache.hadoop.hbase.master.http.api_v1.cluster_metrics.resource">ClusterMetricsResource</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/ClusterMetricsBuilder.ClusterMetricsImpl.html" title="class in org.apache.hadoop.hbase">ClusterMetricsBuilder.ClusterMetricsImpl</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/http/api_v1/cluster_metrics/resource/ClusterMetricsResource.html" title="class in org.apache.hadoop.hbase.master.http.api_v1.cluster_metrics.resource">ClusterMetricsResource</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">The root object exposing a subset of <a href="org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase"><code>ClusterMetrics</code></a>.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/master/ClusterSchema.html" title="interface in org.apache.hadoop.hbase.master">ClusterSchema</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/master/ClusterSchema.html" title="interface in org.apache.hadoop.hbase.master">ClusterSchema</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
 <div class="block">View and edit the current cluster schema.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/master/ClusterSchemaService.html" title="interface in org.apache.hadoop.hbase.master">ClusterSchemaService</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/master/ClusterSchemaService.html" title="interface in org.apache.hadoop.hbase.master">ClusterSchemaService</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
 <div class="block">Mixes in ClusterSchema and Service</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterSchemaServiceImpl.html" title="class in org.apache.hadoop.hbase.master">ClusterSchemaServiceImpl</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/balancer/ClusterStatusChore.html" title="class in org.apache.hadoop.hbase.master.balancer">ClusterStatusChore</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterSchemaServiceImpl.html" title="class in org.apache.hadoop.hbase.master">ClusterSchemaServiceImpl</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/balancer/ClusterStatusChore.html" title="class in org.apache.hadoop.hbase.master.balancer">ClusterStatusChore</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Chore that will feed the balancer the cluster status.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClusterStatusListener.html" title="class in org.apache.hadoop.hbase.client">ClusterStatusListener</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ClusterStatusListener.html" title="class in org.apache.hadoop.hbase.client">ClusterStatusListener</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">A class that receives the cluster status, and provide it as a set of service to the client.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/client/ClusterStatusListener.DeadServerHandler.html" title="interface in org.apache.hadoop.hbase.client">ClusterStatusListener.DeadServerHandler</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/client/ClusterStatusListener.DeadServerHandler.html" title="interface in org.apache.hadoop.hbase.client">ClusterStatusListener.DeadServerHandler</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
 <div class="block">Class to be extended to manage a new dead server.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/client/ClusterStatusListener.Listener.html" title="interface in org.apache.hadoop.hbase.client">ClusterStatusListener.Listener</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/client/ClusterStatusListener.Listener.html" title="interface in org.apache.hadoop.hbase.client">ClusterStatusListener.Listener</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
 <div class="block">The interface to be implemented by a listener of a cluster status event.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.html" title="class in org.apache.hadoop.hbase.master">ClusterStatusPublisher</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.html" title="class in org.apache.hadoop.hbase.master">ClusterStatusPublisher</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Class to publish the cluster status to the client.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.MulticastPublisher.html" title="class in org.apache.hadoop.hbase.master">ClusterStatusPublisher.MulticastPublisher</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.MulticastPublisher.ClusterMetricsEncoder.html" title="class in org.apache.hadoop.hbase.master">ClusterStatusPublisher.MulticastPublisher.ClusterMetricsEncoder</a></div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.MulticastPublisher.html" title="class in org.apache.hadoop.hbase.master">ClusterStatusPublisher.MulticastPublisher</a></div>
 <div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.MulticastPublisher.HBaseDatagramChannelFactory.html" title="class in org.apache.hadoop.hbase.master">ClusterStatusPublisher.MulticastPublisher.HBaseDatagramChannelFactory</a>&lt;<a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.MulticastPublisher.HBaseDatagramChannelFactory.html" title="type parameter in ClusterStatusPublisher.Multicas [...]
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.MulticastPublisher.ClusterMetricsEncoder.html" title="class in org.apache.hadoop.hbase.master">ClusterStatusPublisher.MulticastPublisher.ClusterMetricsEncoder</a></div>
 <div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.Publisher.html" title="interface in org.apache.hadoop.hbase.master">ClusterStatusPublisher.Publisher</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">&nbsp;</div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/zookeeper/ClusterStatusTracker.html" title="class in org.apache.hadoop.hbase.zookeeper">ClusterStatusTracker</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.MulticastPublisher.HBaseDatagramChannelFactory.html" title="class in org.apache.hadoop.hbase.master">ClusterStatusPublisher.MulticastPublisher.HBaseDatagramChannelFactory</a>&lt;<a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.MulticastPublisher.HBaseDatagramChannelFactory.html" title="type parameter in ClusterStatusPublisher.Multicast [...]
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/master/ClusterStatusPublisher.Publisher.html" title="interface in org.apache.hadoop.hbase.master">ClusterStatusPublisher.Publisher</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/zookeeper/ClusterStatusTracker.html" title="class in org.apache.hadoop.hbase.zookeeper">ClusterStatusTracker</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Tracker on cluster settings up in zookeeper.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/codec/Codec.html" title="interface in org.apache.hadoop.hbase.codec">Codec</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/codec/Codec.html" title="interface in org.apache.hadoop.hbase.codec">Codec</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
 <div class="block">Encoder/Decoder for Cell.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/codec/Codec.Decoder.html" title="interface in org.apache.hadoop.hbase.codec">Codec.Decoder</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/codec/Codec.Decoder.html" title="interface in org.apache.hadoop.hbase.codec">Codec.Decoder</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
 <div class="block">Implementations should implicitly clean up any resources allocated when the Decoder/CellScanner
  runs off the end of the cell block.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/codec/Codec.Encoder.html" title="interface in org.apache.hadoop.hbase.codec">Codec.Encoder</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/codec/Codec.Encoder.html" title="interface in org.apache.hadoop.hbase.codec">Codec.Encoder</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
 <div class="block">Call flush when done.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab5"><a href="org/apache/hadoop/hbase/codec/CodecException.html" title="class in org.apache.hadoop.hbase.codec">CodecException</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab5">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab5"><a href="org/apache/hadoop/hbase/codec/CodecException.html" title="class in org.apache.hadoop.hbase.codec">CodecException</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab5">
 <div class="block">Thrown when problems in the codec whether setup or context.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/io/compress/CodecPool.html" title="class in org.apache.hadoop.hbase.io.compress">CodecPool</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/io/compress/CodecPool.html" title="class in org.apache.hadoop.hbase.io.compress">CodecPool</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">A global compressor/decompressor pool used to save and reuse (possibly native)
  compression/decompression codecs.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/util/CollectionBackedScanner.html" title="class in org.apache.hadoop.hbase.util">CollectionBackedScanner</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/util/CollectionBackedScanner.html" title="class in org.apache.hadoop.hbase.util">CollectionBackedScanner</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Utility scanner that wraps a sortable collection and serves as a KeyValueScanner.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab3"><a href="org/apache/hadoop/hbase/hbtop/terminal/Color.html" title="enum class in org.apache.hadoop.hbase.hbtop.terminal">Color</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab3">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab3"><a href="org/apache/hadoop/hbase/hbtop/terminal/Color.html" title="enum class in org.apache.hadoop.hbase.hbtop.terminal">Color</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab3">
 <div class="block">Terminal color definitions.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/querymatcher/ColumnCount.html" title="class in org.apache.hadoop.hbase.regionserver.querymatcher">ColumnCount</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/querymatcher/ColumnCount.html" title="class in org.apache.hadoop.hbase.regionserver.querymatcher">ColumnCount</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Simple wrapper for a byte buffer and a counter.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnCountGetFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnCountGetFilter</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnCountGetFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnCountGetFilter</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Simple filter that returns first N columns on row only.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/client/ColumnFamilyDescriptor.html" title="interface in org.apache.hadoop.hbase.client">ColumnFamilyDescriptor</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/client/ColumnFamilyDescriptor.html" title="interface in org.apache.hadoop.hbase.client">ColumnFamilyDescriptor</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
 <div class="block">An ColumnFamilyDescriptor contains information about a column family such as the number of
  versions, compression settings, etc.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ColumnFamilyDescriptorBuilder.html" title="class in org.apache.hadoop.hbase.client">ColumnFamilyDescriptorBuilder</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor.html" title="class in org.apache.hadoop.hbase.client">ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ColumnFamilyDescriptorBuilder.html" title="class in org.apache.hadoop.hbase.client">ColumnFamilyDescriptorBuilder</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/client/ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor.html" title="class in org.apache.hadoop.hbase.client">ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">An ModifyableFamilyDescriptor contains information about a column family such as the number of
  versions, compression settings, etc.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab5"><a href="org/apache/hadoop/hbase/backup/impl/ColumnFamilyMismatchException.html" title="class in org.apache.hadoop.hbase.backup.impl">ColumnFamilyMismatchException</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab5">&nbsp;</div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/backup/impl/ColumnFamilyMismatchException.ColumnFamilyMismatchExceptionBuilder.html" title="class in org.apache.hadoop.hbase.backup.impl">ColumnFamilyMismatchException.ColumnFamilyMismatchExceptionBuilder</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/coprocessor/ColumnInterpreter.html" title="class in org.apache.hadoop.hbase.coprocessor">ColumnInterpreter</a>&lt;<a href="org/apache/hadoop/hbase/coprocessor/ColumnInterpreter.html" title="type parameter in ColumnInterpreter">T</a>,<wbr><a href="org/apache/hadoop/hbase/coprocessor/ColumnInterpreter.html" title="type parameter in ColumnInterpreter">S</a>,<wbr><a href="org/apache [...]
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab5"><a href="org/apache/hadoop/hbase/backup/impl/ColumnFamilyMismatchException.html" title="class in org.apache.hadoop.hbase.backup.impl">ColumnFamilyMismatchException</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab5">&nbsp;</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/backup/impl/ColumnFamilyMismatchException.ColumnFamilyMismatchExceptionBuilder.html" title="class in org.apache.hadoop.hbase.backup.impl">ColumnFamilyMismatchException.ColumnFamilyMismatchExceptionBuilder</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/coprocessor/ColumnInterpreter.html" title="class in org.apache.hadoop.hbase.coprocessor">ColumnInterpreter</a>&lt;<a href="org/apache/hadoop/hbase/coprocessor/ColumnInterpreter.html" title="type parameter in ColumnInterpreter">T</a>,<wbr><a href="org/apache/hadoop/hbase/coprocessor/ColumnInterpreter.html" title="type parameter in ColumnInterpreter">S</a>,<wbr><a href="org/apach [...]
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Defines how value for specific column is interpreted and provides utility methods like compare,
  add, multiply etc for them.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnPaginationFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnPaginationFilter</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnPaginationFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnPaginationFilter</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">A filter, based on the ColumnCountGetFilter, takes two arguments: limit and offset.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnPrefixFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnPrefixFilter</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnPrefixFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnPrefixFilter</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">This filter is used for selecting only those keys with columns that matches a particular prefix.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnRangeFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnRangeFilter</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnRangeFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnRangeFilter</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">This filter is used for selecting only those keys with columns that are between minColumn to
  maxColumn.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/rest/model/ColumnSchemaModel.html" title="class in org.apache.hadoop.hbase.rest.model">ColumnSchemaModel</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/rest/model/ColumnSchemaModel.html" title="class in org.apache.hadoop.hbase.rest.model">ColumnSchemaModel</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Representation of a column family schema.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/regionserver/querymatcher/ColumnTracker.html" title="interface in org.apache.hadoop.hbase.regionserver.querymatcher">ColumnTracker</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab1">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab1"><a href="org/apache/hadoop/hbase/regionserver/querymatcher/ColumnTracker.html" title="interface in org.apache.hadoop.hbase.regionserver.querymatcher">ColumnTracker</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab1">
 <div class="block">Implementing classes of this interface will be used for the tracking and enforcement of columns
  and numbers of versions and timeToLive during the course of a Get or Scan operation.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnValueFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnValueFilter</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/filter/ColumnValueFilter.html" title="class in org.apache.hadoop.hbase.filter">ColumnValueFilter</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Different from <a href="org/apache/hadoop/hbase/filter/SingleColumnValueFilter.html" title="class in org.apache.hadoop.hbase.filter"><code>SingleColumnValueFilter</code></a> which returns an <b>entire</b> row when specified
  condition is matched, <a href="org/apache/hadoop/hbase/filter/ColumnValueFilter.html" title="class in org.apache.hadoop.hbase.filter"><code>ColumnValueFilter</code></a> return the matched cell only.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/wal/CombinedAsyncWriter.html" title="class in org.apache.hadoop.hbase.regionserver.wal">CombinedAsyncWriter</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/wal/CombinedAsyncWriter.html" title="class in org.apache.hadoop.hbase.regionserver.wal">CombinedAsyncWriter</a></div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">An <a href="org/apache/hadoop/hbase/wal/WALProvider.AsyncWriter.html" title="interface in org.apache.hadoop.hbase.wal"><code>WALProvider.AsyncWriter</code></a> wrapper which writes data to a set of <a href="org/apache/hadoop/hbase/wal/WALProvider.AsyncWriter.html" title="interface in org.apache.hadoop.hbase.wal"><code>WALProvider.AsyncWriter</code></a> instances.</div>
 </div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/io/hfile/CombinedBlockCache.html" title="class in org.apache.hadoop.hbase.io.hfile">CombinedBlockCache</a></div>
-<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/io/hfile/CombinedBlockCache.html" title="class in org.apache.hadoop.hbase.io.hfile">CombinedBlockCache</a></div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">CombinedBlockCache is an abstraction layer that combines <a href="org/apache/hadoop/hbase/io/hfile/FirstLevelBlockCache.html" title="interface in org.apache.hadoop.hbase.io.hfile"><code>FirstLevelBlockCache</code></a> and
  <a href="org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket"><code>BucketCache</code></a>.</div>
 </div>
-<div class="col-first even-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/io/hfile/CombinedBlockCache.CombinedCacheStats.html" title="class in org.apache.hadoop.hbase.io.hfile">CombinedBlockCache.CombinedCacheStats</a></div>
-<div class="col-last even-row-color all-classes-table all-classes-table-tab2">&nbsp;</div>
-<div class="col-first odd-row-color all-classes-table all-classes-table-tab2"><a href="org/apache/hadoop/hbase/regionserver/wal/CombinedWriter.html" title="class in org.apache.hadoop.hbase.regionserver.wal">CombinedWriter</a></div>
... 35955 lines suppressed ...