You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by GitBox <gi...@apache.org> on 2018/04/27 02:43:47 UTC

[GitHub] ningyu1 closed pull request #1658: [Dubbo-1637] Fix When using hibernate-validator, class 'org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl' is wrong with hessian deserialization.

ningyu1 closed pull request #1658: [Dubbo-1637] Fix When using hibernate-validator, class 'org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl' is wrong with hessian deserialization.
URL: https://github.com/apache/incubator-dubbo/pull/1658
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/LICENSE b/LICENSE
index 9e87f44c64..7b279f1611 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,4 @@
 
-
                                  Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
@@ -187,6 +186,7 @@
       file or class name and description of purpose be included on the
       same "printed page" as the copyright notice for easier
       identification within third-party archives.
+
    Copyright [yyyy] [name of copyright owner]
 
    Licensed under the Apache License, Version 2.0 (the "License");
@@ -200,3 +200,67 @@
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
+
+
+Apache Dubbo Submodules:
+
+Apache Dubbo includes a number of submodules with separate copyright notices
+and license terms. Your use of these submodules is subject to the terms and
+conditions of the following licenses.
+
+
+For the hessian-lite submodule:
+
+The Apache Software License, Version 1.1
+
+ Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ 3. The end-user documentation included with the redistribution, if
+    any, must include the following acknowlegement:
+       "This product includes software developed by the
+        Caucho Technology (http://www.caucho.com/)."
+    Alternately, this acknowlegement may appear in the software itself,
+    if and wherever such third-party acknowlegements normally appear.
+
+ 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+    endorse or promote products derived from this software without prior
+    written permission. For written permission, please contact
+    info@caucho.com.
+
+ 5. Products derived from this software may not be called "Resin"
+    nor may "Resin" appear in their names without prior written
+    permission of Caucho Technology.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+For the com.alibaba.dubbo.common.concurrent package:
+
+This product bundles and repackages the following code in Google Guava 16.0.1, which is available under a
+"Apache License 2.0" license. For details, see https://github.com/google/guava/blob/v16.0.1/COPYING.
+
+ * com.google.common.util.concurrent.ExecutionList
+ * com.google.common.util.concurrent.ListenableFuture
+ * com.google.common.util.concurrent.ListenableFutureTask
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
index cbff3d58be..84d3fe1388 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,269 +1,5 @@
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
+Apache Dubbo (incubating)
+Copyright 2018 The Apache Software Foundation
 
-     http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-================================================================
-Dependencies:
-
-Spring:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://www.springsource.org
-
-Javassist:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://www.jboss.org/javassist
-
-Netty:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://netty.io
-
-Mina:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://mina.apache.org
-
-Grizzly:
-
-  * LICENSE:
-    * https://opensource.org/licenses/cddl-1.0 (CDDL 1.1)
-  * HOMEPAGE:
-    * https://javaee.github.io/grizzly/
-
-HttpClient:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://hc.apache.org
-
-Hessian:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://hessian.caucho.com
-
-XStream:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://xstream.codehaus.org
-
-FastJson:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * https://github.com/alibaba/fastjson
-
-Zookeeper:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://zookeeper.apache.org
-
-Jedis:
-
-  * LICENSE:
-    * https://opensource.org/licenses/MIT (MIT)
-  * HOMEPAGE:
-    * https://github.com/xetorthio/jedis
-
-XMemcached:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://code.google.com/p/xmemcached
-
-Jetty:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://jetty.mortbay.org
-
-Thrift:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://thrift.apache.org
-
-CXF:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://cxf.apache.org
-
-ZKClient:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * https://github.com/sgroschupf/zkclient
-	
-Curator 
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * https://github.com/Netflix/curator
-
-JFreeChart:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://www.jfree.org
-
-validation-api:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    *  http://beanvalidation.org
-
-HibernateValidator:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://www.hibernate.org/subprojects/validator.html
-
-CommonsLogging:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://commons.apache.org/logging
-
-SLF4J:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://www.slf4j.org
-
-Log4j:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://log4j.apache.org
-
-Tomcat:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://tomcat.apache.org
-
-cache-api:
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * https://github.com/jsr107/jsr107spec
-
-easymock
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://easymock.org
-
-cglib-nodep
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * https://sourceforge.net/projects/cglib/
-
-resteasy
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://resteasy.jboss.org/
-
-fst
-
-  * LICENSE:
-    * http://www.apache.org/licenses/LICENSE-2.0 (Apache License 2.0)
-  * HOMEPAGE:
-    * http://ruedigermoeller.github.io/fast-serialization
-
-jmockit
-
-  * LICENSE:
-    * https://opensource.org/licenses/MIT (MIT)
-  * HOMEPAGE:
-    * http://www.jmockit.org
-
-jedis
-
-  * LICENSE:
-    * https://opensource.org/licenses/MIT (MIT)
-  * HOMEPAGE:
-    * http://www.jmockit.org
-
-javax.servlet-api:
-
-  * LICENSE:
-    * https://opensource.org/licenses/cddl-1.0 (CDDL 1.1)
-  * HOMEPAGE:
-    * http://servlet-spec.java.net
-
-javax.el:
-
-  * LICENSE:
-    * https://opensource.org/licenses/cddl-1.0 (CDDL 1.1)
-  * HOMEPAGE:
-    * https://javaee.github.io/uel-ri/
-
-logback-classic:
-
-  * LICENSE:
-    * http://www.eclipse.org/legal/epl-v10.html (EPL 1.0)
-  * HOMEPAGE:
-    * https://logback.qos.ch/
-
-junit:
-
-  * LICENSE:
-    * http://www.eclipse.org/legal/epl-v10.html (EPL 1.0)
-  * HOMEPAGE:
-    * http://www.junit.org
-
-kryo:
-
-  * LICENSE:
-    * https://opensource.org/licenses/BSD-3-Clause (BSD 3-clause)
-  * HOMEPAGE:
-    * https://github.com/EsotericSoftware/kryo
\ No newline at end of file
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java
index bca68aa28f..55e86d0382 100644
--- a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java
+++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java
@@ -633,6 +633,8 @@
 
     public static final boolean DEFAULT_HESSIAN_OVERLOAD_METHOD = false;
 
+    public static final String MULTICAST = "multicast";
+
     /*
      * private Constants(){ }
      */
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ProtocolConfig.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ProtocolConfig.java
index 13000a778a..0e7a52431c 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ProtocolConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ProtocolConfig.java
@@ -20,7 +20,6 @@
 import com.alibaba.dubbo.common.serialize.Serialization;
 import com.alibaba.dubbo.common.status.StatusChecker;
 import com.alibaba.dubbo.common.threadpool.ThreadPool;
-import com.alibaba.dubbo.common.utils.ConfigUtils;
 import com.alibaba.dubbo.config.support.Parameter;
 import com.alibaba.dubbo.registry.support.AbstractRegistryFactory;
 import com.alibaba.dubbo.remoting.Codec;
@@ -155,14 +154,8 @@ public static void destroyAll() {
         if (!destroyed.compareAndSet(false, true)) {
             return;
         }
-        AbstractRegistryFactory.destroyAll();
 
-        // Wait for registry notification
-        try {
-            Thread.sleep(ConfigUtils.getServerShutdownTimeout());
-        } catch (InterruptedException e) {
-            logger.warn("Interrupted unexpectedly when waiting for registry notification during shutdown process!");
-        }
+        AbstractRegistryFactory.destroyAll();
 
         ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
         for (String protocolName : loader.getLoadedExtensions()) {
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ServiceConfig.java
index daf8f162e4..e2101d52b0 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ServiceConfig.java
@@ -571,6 +571,10 @@ private String findConfigedHosts(ProtocolConfig protocolConfig, List<URL> regist
                 if (isInvalidLocalHost(hostToBind)) {
                     if (registryURLs != null && !registryURLs.isEmpty()) {
                         for (URL registryURL : registryURLs) {
+                            if (Constants.MULTICAST.equalsIgnoreCase(registryURL.getParameter("registry"))) {
+                                // skip multicast registry since we cannot connect to it via Socket
+                                continue;
+                            }
                             try {
                                 Socket socket = new Socket();
                                 try {
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java
index e14fc4b971..bbb75d9efd 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java
@@ -111,13 +111,18 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
 
     @Override
     public void destroy() throws Exception {
-        for (ServiceConfig<?> serviceConfig : serviceConfigs) {
-            try {
-                serviceConfig.unexport();
-            } catch (Throwable e) {
-                logger.error(e.getMessage(), e);
-            }
-        }
+
+        //  This will only be called for singleton scope bean, and expected to be called by spring shutdown hook when BeanFactory/ApplicationContext destroys.
+        //  We will guarantee dubbo related resources being released with dubbo shutdown hook.
+
+        //  for (ServiceConfig<?> serviceConfig : serviceConfigs) {
+        //      try {
+        //          serviceConfig.unexport();
+        //      } catch (Throwable e) {
+        //          logger.error(e.getMessage(), e);
+        //      }
+        //  }
+
         for (ReferenceConfig<?> referenceConfig : referenceConfigs.values()) {
             try {
                 referenceConfig.destroy();
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
index 6e7fe03b1a..3560465090 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
@@ -71,6 +71,8 @@
 public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,
         ResourceLoaderAware, BeanClassLoaderAware {
 
+    private static final String SEPARATOR = ":";
+
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
     private final Set<String> packagesToScan;
@@ -254,7 +256,7 @@ private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, Bean
                 buildServiceBeanDefinition(service, interfaceClass, annotatedServiceBeanName);
 
         // ServiceBean Bean name
-        String beanName = generateServiceBeanName(interfaceClass, annotatedServiceBeanName);
+        String beanName = generateServiceBeanName(service, interfaceClass, annotatedServiceBeanName);
 
         if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
             registry.registerBeanDefinition(beanName, serviceBeanDefinition);
@@ -279,14 +281,35 @@ private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, Bean
     /**
      * Generates the bean name of {@link ServiceBean}
      *
+     * @param service
      * @param interfaceClass           the class of interface annotated {@link Service}
      * @param annotatedServiceBeanName the bean name of annotated {@link Service}
      * @return ServiceBean@interfaceClassName#annotatedServiceBeanName
      * @since 2.5.9
      */
-    private String generateServiceBeanName(Class<?> interfaceClass, String annotatedServiceBeanName) {
+    private String generateServiceBeanName(Service service, Class<?> interfaceClass, String annotatedServiceBeanName) {
+
+        StringBuilder beanNameBuilder = new StringBuilder(ServiceBean.class.getSimpleName());
+
+        beanNameBuilder.append(SEPARATOR).append(annotatedServiceBeanName);
+
+        String interfaceClassName = interfaceClass.getName();
+
+        beanNameBuilder.append(SEPARATOR).append(interfaceClassName);
+
+        String version = service.version();
+
+        if (StringUtils.hasText(version)) {
+            beanNameBuilder.append(SEPARATOR).append(version);
+        }
+
+        String group = service.group();
+
+        if (StringUtils.hasText(group)) {
+            beanNameBuilder.append(SEPARATOR).append(group);
+        }
 
-        return "ServiceBean@" + interfaceClass.getName() + "#" + annotatedServiceBeanName;
+        return beanNameBuilder.toString();
 
     }
 
@@ -477,4 +500,4 @@ public void setBeanClassLoader(ClassLoader classLoader) {
         this.classLoader = classLoader;
     }
 
-}
+}
\ No newline at end of file
diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/filter/ValidationFilter.java b/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/filter/ValidationFilter.java
index 1fe717cf40..a61ba84fb1 100644
--- a/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/filter/ValidationFilter.java
+++ b/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/filter/ValidationFilter.java
@@ -27,6 +27,13 @@
 import com.alibaba.dubbo.rpc.RpcResult;
 import com.alibaba.dubbo.validation.Validation;
 import com.alibaba.dubbo.validation.Validator;
+import com.alibaba.dubbo.validation.support.jsr303.DubboConstraintViolation;
+import com.alibaba.dubbo.validation.support.jsr303.DubboConstraintViolationException;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * ValidationFilter
@@ -49,6 +56,12 @@ public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcExcept
                 if (validator != null) {
                     validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
                 }
+            } catch (ConstraintViolationException e) {
+                Set<ConstraintViolation<String>> set = new HashSet<ConstraintViolation<String>>();
+                for (ConstraintViolation<?> v : e.getConstraintViolations()) {
+                    set.add(new DubboConstraintViolation<String>(v.getMessage(), v.getPropertyPath()));
+                }
+                return new RpcResult(new RpcException(new DubboConstraintViolationException(set)));
             } catch (RpcException e) {
                 throw e;
             } catch (Throwable t) {
diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/support/jsr303/DubboConstraintViolation.java b/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/support/jsr303/DubboConstraintViolation.java
new file mode 100644
index 0000000000..d85cb93d47
--- /dev/null
+++ b/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/support/jsr303/DubboConstraintViolation.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.validation.support.jsr303;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Path;
+import javax.validation.metadata.ConstraintDescriptor;
+import java.io.Serializable;
+
+/**
+ * DubboConstraintViolation
+ */
+public class DubboConstraintViolation<T> implements ConstraintViolation<T>, Serializable {
+
+    private static final long serialVersionUID = 5219532001604429907L;
+    private String message;
+    private Path path;
+
+    public DubboConstraintViolation() {
+    }
+
+    public DubboConstraintViolation(String message, Path path) {
+        this.message = message;
+        this.path = path;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public Path getPath() {
+        return path;
+    }
+
+    public void setPath(Path path) {
+        this.path = path;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    @Override
+    public String getMessageTemplate() {
+        return message;
+    }
+
+    @Override
+    public T getRootBean() {
+        return null;
+    }
+
+    @Override
+    public Class<T> getRootBeanClass() {
+        return null;
+    }
+
+    @Override
+    public Object getLeafBean() {
+        return null;
+    }
+
+    @Override
+    public Object[] getExecutableParameters() {
+        return new Object[0];
+    }
+
+    @Override
+    public Object getExecutableReturnValue() {
+        return null;
+    }
+
+    @Override
+    public Path getPropertyPath() {
+        return null;
+    }
+
+    @Override
+    public Object getInvalidValue() {
+        return null;
+    }
+
+    @Override
+    public ConstraintDescriptor<?> getConstraintDescriptor() {
+        return null;
+    }
+
+    @Override
+    public <U> U unwrap(Class<U> type) {
+        return null;
+    }
+}
diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/support/jsr303/DubboConstraintViolationException.java b/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/support/jsr303/DubboConstraintViolationException.java
new file mode 100644
index 0000000000..8393d4bf49
--- /dev/null
+++ b/dubbo-filter/dubbo-filter-validation/src/main/java/com/alibaba/dubbo/validation/support/jsr303/DubboConstraintViolationException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.dubbo.validation.support.jsr303;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import java.util.Set;
+
+/**
+ * DubboConstraintViolationException
+ */
+public class DubboConstraintViolationException extends ConstraintViolationException {
+    private static final long serialVersionUID = -8570552769314565659L;
+    private Set<? extends ConstraintViolation<?>> constraintViolations;
+
+    public DubboConstraintViolationException() {
+        super(null);
+    }
+
+    public DubboConstraintViolationException(Set<? extends ConstraintViolation<?>> constraintViolations) {
+        super(constraintViolations);
+        this.constraintViolations = constraintViolations;
+    }
+
+    public Set<ConstraintViolation<?>> getConstraintViolations() {
+        return (Set<ConstraintViolation<?>>) constraintViolations;
+    }
+
+    public void setConstraintViolations(Set<? extends ConstraintViolation<?>> constraintViolations) {
+        this.constraintViolations = constraintViolations;
+    }
+}
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/com/alibaba/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/com/alibaba/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
index 2a09c5de1f..2ab32f008d 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/com/alibaba/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/com/alibaba/dubbo/remoting/exchange/support/header/HeaderExchangeServer.java
@@ -29,8 +29,6 @@
 import com.alibaba.dubbo.remoting.exchange.ExchangeChannel;
 import com.alibaba.dubbo.remoting.exchange.ExchangeServer;
 import com.alibaba.dubbo.remoting.exchange.Request;
-import com.alibaba.dubbo.remoting.exchange.support.DefaultFuture;
-
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -85,7 +83,13 @@ public boolean isClosed() {
     private boolean isRunning() {
         Collection<Channel> channels = getChannels();
         for (Channel channel : channels) {
-            if (DefaultFuture.hasFuture(channel)) {
+
+            /**
+             *  If there are any client connections,
+             *  our server should be running.
+             */
+
+            if (channel.isConnected()) {
                 return true;
             }
         }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java
index 363b0faf08..a542cd6488 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java
@@ -154,22 +154,7 @@ public void setResponse(Object response) {
      * @return provider side.
      */
     public boolean isProviderSide() {
-        URL url = getUrl();
-        if (url == null) {
-            return false;
-        }
-        InetSocketAddress address = getRemoteAddress();
-        if (address == null) {
-            return false;
-        }
-        String host;
-        if (address.getAddress() == null) {
-            host = address.getHostName();
-        } else {
-            host = address.getAddress().getHostAddress();
-        }
-        return url.getPort() != address.getPort() ||
-                !NetUtils.filterLocalHost(url.getIp()).equals(NetUtils.filterLocalHost(host));
+        return !isConsumerSide();
     }
 
     /**
@@ -178,22 +163,7 @@ public boolean isProviderSide() {
      * @return consumer side.
      */
     public boolean isConsumerSide() {
-        URL url = getUrl();
-        if (url == null) {
-            return false;
-        }
-        InetSocketAddress address = getRemoteAddress();
-        if (address == null) {
-            return false;
-        }
-        String host;
-        if (address.getAddress() == null) {
-            host = address.getHostName();
-        } else {
-            host = address.getAddress().getHostAddress();
-        }
-        return url.getPort() == address.getPort() &&
-                NetUtils.filterLocalHost(url.getIp()).equals(NetUtils.filterLocalHost(host));
+        return getUrl().getParameter(Constants.SIDE_KEY, Constants.PROVIDER_SIDE).equals(Constants.CONSUMER_SIDE);
     }
 
     /**
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
index 8b1d62a7a7..dcedfcf652 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
@@ -20,7 +20,10 @@
 import com.alibaba.dubbo.common.Constants;
 import com.alibaba.dubbo.common.URL;
 import com.alibaba.dubbo.common.extension.ExtensionLoader;
+import com.alibaba.dubbo.common.utils.ConfigUtils;
 import com.alibaba.dubbo.remoting.exchange.ExchangeClient;
+import com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeServer;
+import com.alibaba.dubbo.rpc.Exporter;
 import com.alibaba.dubbo.rpc.ProxyFactory;
 import com.alibaba.dubbo.rpc.protocol.dubbo.support.ProtocolUtils;
 
@@ -75,6 +78,30 @@ public void test_Normal_ChannelReadOnly() throws Exception {
         getClients(invoker)[0].removeAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY);
     }
 
+    @Test
+    public void test_normal_channel_close_wait_gracefully() throws Exception {
+
+        URL url = URL.valueOf("dubbo://127.0.0.1:20883/hi?scope=true&lazy=false");
+        Exporter<IDemoService> exporter = ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url);
+        Exporter<IDemoService> exporter0 = ProtocolUtils.export(new DemoServiceImpl0(), IDemoService.class, url);
+
+        DubboInvoker<?> invoker = (DubboInvoker<?>) protocol.refer(IDemoService.class, url);
+
+        long start = System.currentTimeMillis();
+
+        try{
+            System.setProperty(Constants.SHUTDOWN_WAIT_KEY, "2000");
+            protocol.destroy();
+        }finally {
+            System.getProperties().remove(Constants.SHUTDOWN_WAIT_KEY);
+        }
+
+        long waitTime = System.currentTimeMillis() - start;
+
+        Assert.assertTrue(waitTime >= 2000);
+        Assert.assertEquals(false, invoker.isAvailable());
+    }
+
     @Test
     public void test_NoInvokers() throws Exception {
         URL url = URL.valueOf("dubbo://127.0.0.1:20883/hi?connections=1");
@@ -129,4 +156,10 @@ public String get() {
             return "ok";
         }
     }
+
+    public class DemoServiceImpl0 implements IDemoService {
+        public String get() {
+            return "ok";
+        }
+    }
 }
\ No newline at end of file


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org