<h1 dir="auto">Weekly Report of Dubbo</h1>
<p dir="auto">This is a weekly report of Dubbo. It summarizes what have changed in the project during the passed week, including pr merged, new contributors, and more things in the future.<br>
It is all done by <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/dubbo-bot/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/dubbo-bot">@dubbo-bot</a> which is a collaborate robot.</p>
<h2 dir="auto">Repo Overview</h2>
<h3 dir="auto">Basic data</h3>
<p dir="auto">Baisc data shows how the watch, star, fork and contributors count changed in the passed week.</p>
<table role="table">
<thead>
<tr>
<th align="center">Watch</th>
<th align="center">Star</th>
<th align="center">Fork</th>
<th align="center">Contributors</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">3217</td>
<td align="center">27013 (↑191)</td>
<td align="center">15166 (↑97)</td>
<td align="center">201 (↑1)</td>
</tr>
</tbody>
</table>
<h3 dir="auto">Issues &amp; PRs</h3>
<p dir="auto">Issues &amp; PRs show the new/closed issues/pull requests count in the passed week.</p>
<table role="table">
<thead>
<tr>
<th align="center">New Issues</th>
<th align="center">Closed Issues</th>
<th align="center">New PR</th>
<th align="center">Merged PR</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">20</td>
<td align="center">16</td>
<td align="center">25</td>
<td align="center">24</td>
</tr>
</tbody>
</table>
<h2 dir="auto">PR Overview</h2>
<p dir="auto">Thanks to contributions from community, Dubbo team merged <strong>24</strong> pull requests in the repository last week. They are:</p>
<ul dir="auto">
<li>2.7.2 release (<a href="https://github.com/apache/dubbo/pull/4259" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4259/hovercard">#4259</a>)</li>
<li>Default future from jeff-lv (<a href="https://github.com/apache/dubbo/pull/4257" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4257/hovercard">#4257</a>)</li>
<li>performance tuning: cache service key (<a href="https://github.com/apache/dubbo/pull/4255" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4255/hovercard">#4255</a>)</li>
<li>performance tuning: channel connect status (<a href="https://github.com/apache/dubbo/pull/4254" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4254/hovercard">#4254</a>)</li>
<li>Performance tuning: keep heartbeat updated in io thread to avoid race condition. (<a href="https://github.com/apache/dubbo/pull/4246" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4246/hovercard">#4246</a>)</li>
<li>Applicationmodel revert (<a href="https://github.com/apache/dubbo/pull/4245" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4245/hovercard">#4245</a>)</li>
<li>getMethodparameter refactor (<a href="https://github.com/apache/dubbo/pull/4244" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4244/hovercard">#4244</a>)</li>
<li>delete useless code (<a href="https://github.com/apache/dubbo/pull/4242" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4242/hovercard">#4242</a>)</li>
<li>Perf reduce string allocation (<a href="https://github.com/apache/dubbo/pull/4240" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4240/hovercard">#4240</a>)</li>
<li>[Dubbo-4218] Fix NPE when the TagRouterRule addresses config is null (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="450633979" data-permission-text="Title is private" data-url="https://github.com/apache/dubbo/issues/4218" data-hovercard-type="issue" data-hovercard-url="/apache/dubbo/issues/4218/hovercard" href="https://github.com/apache/dubbo/issues/4218">#4218</a>) (<a href="https://github.com/apache/dubbo/pull/4236" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4236/hovercard">#4236</a>)</li>
<li>[Dubbo-4219] Remove DISCLAIMER (<a href="https://github.com/apache/dubbo/pull/4234" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4234/hovercard">#4234</a>)</li>
<li>[Dubbo-4219] Remove DISCLAIMER (<a href="https://github.com/apache/dubbo/pull/4233" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4233/hovercard">#4233</a>)</li>
<li>[Dubbo-4219] Remove DISCLAIMER (<a href="https://github.com/apache/dubbo/pull/4231" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4231/hovercard">#4231</a>)</li>
<li>fix <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="450700349" data-permission-text="Title is private" data-url="https://github.com/apache/dubbo/issues/4227" data-hovercard-type="issue" data-hovercard-url="/apache/dubbo/issues/4227/hovercard" href="https://github.com/apache/dubbo/issues/4227">#4227</a> : remove duplicate <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/OverRide/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/OverRide">@OverRide</a> (<a href="https://github.com/apache/dubbo/pull/4228" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4228/hovercard">#4228</a>)</li>
<li>[Dubbo-4183] Fix unstable tests in ConditionRouterTest  (<a href="https://github.com/apache/dubbo/pull/4226" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4226/hovercard">#4226</a>)</li>
<li>performance tuning: completely remove 'default.' prefix check. (<a href="https://github.com/apache/dubbo/pull/4222" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4222/hovercard">#4222</a>)</li>
<li>performance tuning: avoid repeated address resolving. (<a href="https://github.com/apache/dubbo/pull/4220" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4220/hovercard">#4220</a>)</li>
<li>performance tuning: save rpcinvocation allocation (<a href="https://github.com/apache/dubbo/pull/4215" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4215/hovercard">#4215</a>)</li>
<li>optimize junit Assert usage (<a href="https://github.com/apache/dubbo/pull/4214" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4214/hovercard">#4214</a>)</li>
<li>[Test] add test for common-config (<a href="https://github.com/apache/dubbo/pull/4208" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4208/hovercard">#4208</a>)</li>
<li>[CI] Add jenkinsfile for dubbo snapshot deployment (<a href="https://github.com/apache/dubbo/pull/4205" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4205/hovercard">#4205</a>)</li>
<li>Java doc for remote netty4 (<a href="https://github.com/apache/dubbo/pull/4180" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4180/hovercard">#4180</a>)</li>
<li>reverse url of python (<a href="https://github.com/apache/dubbo/pull/4162" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4162/hovercard">#4162</a>)</li>
<li>Reduce context switching cost by optimizing thread model on consumer side. (<a href="https://github.com/apache/dubbo/pull/4131" data-hovercard-type="pull_request" data-hovercard-url="/apache/dubbo/pull/4131/hovercard">#4131</a>)</li>
</ul>
<h2 dir="auto">Code Review Statistics</h2>
<p dir="auto">Dubbo encourages everyone to participant in code review, in order to improve software quality. Every week <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/dubbo-bot/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/dubbo-bot">@dubbo-bot</a> would automatically help to count pull request reviews of single github user as the following. So, try to help review code in this project.</p>
<table role="table">
<thead>
<tr>
<th align="center">Contributor ID</th>
<th align="center">Pull Request Reviews</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/slievrly/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/slievrly">@slievrly</a></td>
<td align="center">7</td>
</tr>
<tr>
<td align="center"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/lovepoem/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/lovepoem">@lovepoem</a></td>
<td align="center">6</td>
</tr>
<tr>
<td align="center"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/ralf0131/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/ralf0131">@ralf0131</a></td>
<td align="center">4</td>
</tr>
<tr>
<td align="center"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/htynkn/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/htynkn">@htynkn</a></td>
<td align="center">3</td>
</tr>
<tr>
<td align="center"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/moriadry/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/moriadry">@moriadry</a></td>
<td align="center">2</td>
</tr>
<tr>
<td align="center"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/chickenlj/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/chickenlj">@chickenlj</a></td>
<td align="center">2</td>
</tr>
<tr>
<td align="center"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/web1992/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/web1992">@web1992</a></td>
<td align="center">2</td>
</tr>
<tr>
<td align="center"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/CrazyHZM/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/CrazyHZM">@CrazyHZM</a></td>
<td align="center">1</td>
</tr>
<tr>
<td align="center"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/Leishunyu/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/Leishunyu">@Leishunyu</a></td>
<td align="center">1</td>
</tr>
</tbody>
</table>
<h2 dir="auto">Contributors Overview</h2>
<p dir="auto">It is Dubbo team's great honor to have new contributors from community. We really appreciate your contributions. Feel free to tell us if you have any opinion and please share this open source project with more people if you could. If you hope to be a contributor as well, please start from <a href="https://github.com/apache/incubator-dubbo/blob/master/CONTRIBUTING.md">https://github.com/apache/incubator-dubbo/blob/master/CONTRIBUTING.md</a> .<br>
Here is the list of new contributors:</p>
<p dir="auto">@P3trur0</p>
<p dir="auto">Thanks to you all.</p>
<p dir="auto"><em>Note: This robot is supported by <a href="https://github.com/AlibabaDR/Collabobot">Collabobot</a>.</em></p>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have searched the <a href="https://github.com/apache/dubbo/issues">issues</a> of this repository and believe that this is not a duplicate.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have checked the <a href="https://github.com/apache/dubbo/blob/master/FAQ.md">FAQ</a> of this repository and believe that this is not a duplicate.</li>
</ul>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>Dubbo version: 2.7.6</li>
<li>Operating System version: 10.14.6</li>
<li>Java version: 1.8</li>
</ul>
<h3 dir="auto">Steps to reproduce this issue</h3>
<p dir="auto">参数验证异常无法转换<br>
java.lang.ClassCastException: javax.validation.ValidationException cannot be cast to javax.validation.ConstraintViolationException<br>
想要获取参数的异常信息但是无法转换</p>
<p dir="auto">Pls. provide [GitHub address] to reproduce this issue.</p>
<p dir="auto">dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java</p>
<h3 dir="auto">Expected Result</h3>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="public Result invoke(Invoker&lt;?&gt; invoker, Invocation invocation) throws RpcException {
       if (validation != null &amp;&amp; !invocation.getMethodName().startsWith(&quot;$&quot;)
               &amp;&amp; ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), VALIDATION_KEY))) {
           try {
               Validator validator = validation.getValidator(invoker.getUrl());
               if (validator != null) {
                   validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
               }
           } catch (RpcException e) {
               throw e;
           }catch (ConstraintViolationException e) {
               // only use exception's message to avoid potential serialization issue
               return AsyncRpcResult.newDefaultAsyncResult(e, invocation);
           } catch (Throwable t) {
               return AsyncRpcResult.newDefaultAsyncResult(t, invocation);
           }
       }
       return invoker.invoke(invocation);
   }"><pre class="notranslate"><code class="notranslate">public Result invoke(Invoker&lt;?&gt; invoker, Invocation invocation) throws RpcException {
       if (validation != null &amp;&amp; !invocation.getMethodName().startsWith("$")
               &amp;&amp; ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), VALIDATION_KEY))) {
           try {
               Validator validator = validation.getValidator(invoker.getUrl());
               if (validator != null) {
                   validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
               }
           } catch (RpcException e) {
               throw e;
           }catch (ConstraintViolationException e) {
               // only use exception's message to avoid potential serialization issue
               return AsyncRpcResult.newDefaultAsyncResult(e, invocation);
           } catch (Throwable t) {
               return AsyncRpcResult.newDefaultAsyncResult(t, invocation);
           }
       }
       return invoker.invoke(invocation);
   }
</code></pre></div>
<p dir="auto">or</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="public Result invoke(Invoker&lt;?&gt; invoker, Invocation invocation) throws RpcException {
       if (validation != null &amp;&amp; !invocation.getMethodName().startsWith(&quot;$&quot;)
               &amp;&amp; ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), VALIDATION_KEY))) {
           try {
               Validator validator = validation.getValidator(invoker.getUrl());
               if (validator != null) {
                   validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
               }
           } catch (RpcException e) {
               throw e;
           } catch (ValidationException e) {
               // only use exception's message to avoid potential serialization issue
               return AsyncRpcResult.newDefaultAsyncResult(e, invocation);
           } catch (Throwable t) {
               return AsyncRpcResult.newDefaultAsyncResult(t, invocation);
           }
       }
       return invoker.invoke(invocation);
   }"><pre class="notranslate"><code class="notranslate">public Result invoke(Invoker&lt;?&gt; invoker, Invocation invocation) throws RpcException {
       if (validation != null &amp;&amp; !invocation.getMethodName().startsWith("$")
               &amp;&amp; ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), VALIDATION_KEY))) {
           try {
               Validator validator = validation.getValidator(invoker.getUrl());
               if (validator != null) {
                   validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
               }
           } catch (RpcException e) {
               throw e;
           } catch (ValidationException e) {
               // only use exception's message to avoid potential serialization issue
               return AsyncRpcResult.newDefaultAsyncResult(e, invocation);
           } catch (Throwable t) {
               return AsyncRpcResult.newDefaultAsyncResult(t, invocation);
           }
       }
       return invoker.invoke(invocation);
   }
</code></pre></div>
<p dir="auto">What do you expected from the above steps？</p>
<h3 dir="auto">Actual Result</h3>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  public void ConstraintViolationExceptionTest() {
      try{
           .......
      } catch (ConstraintViolationException e){
          System.out.println(e.getConstraintViolations().iterator().next());
      }
  }"><pre class="notranslate"><code class="notranslate">  public void ConstraintViolationExceptionTest() {
      try{
           .......
      } catch (ConstraintViolationException e){
          System.out.println(e.getConstraintViolations().iterator().next());
      }
  }
</code></pre></div>
<p dir="auto">or</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  public void ConstraintViolationExceptionTest() {
      try{
           .......
      } catch (ValidationException e){
          ConstraintViolationException constraint = (ConstraintViolationException) e;
          constraint.getConstraintViolations().iterator().next().getMessage();
      }
  }"><pre class="notranslate"><code class="notranslate">  public void ConstraintViolationExceptionTest() {
      try{
           .......
      } catch (ValidationException e){
          ConstraintViolationException constraint = (ConstraintViolationException) e;
          constraint.getConstraintViolations().iterator().next().getMessage();
      }
  }
</code></pre></div>
<p dir="auto">What actually happens?</p>
<p dir="auto">If there is an exception, please attach the exception trace:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Just put your stack trace here!"><pre class="notranslate"><code class="notranslate">Just put your stack trace here!
</code></pre></div>