You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2022/01/23 09:04:10 UTC
[dubbo] branch 3.0 updated: feature: support jsr-303 jakarta namespace (#9552)
This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.0 by this push:
new c589064 feature: support jsr-303 jakarta namespace (#9552)
c589064 is described below
commit c589064e2056ce257f51f9905d236ef8e2159d4d
Author: 桔子 <ju...@qq.com>
AuthorDate: Sun Jan 23 17:03:57 2022 +0800
feature: support jsr-303 jakarta namespace (#9552)
Java EE has been renamed from javax to jakarta, including the jsr-303 api.
To support Hibernate Validator 7.x, a new JValidatorNew file has been added for compatibility with version 7.x
close #9544
---
dubbo-dependencies-bom/pom.xml | 11 +++
dubbo-filter/dubbo-filter-validation/pom.xml | 4 +
.../dubbo/validation/filter/ValidationFilter.java | 9 +--
.../support/jvalidation/JValidationNew.java | 40 ++++++++++
.../validation/support/jvalidation/JValidator.java | 61 ++++++++-------
.../{JValidator.java => JValidatorNew.java} | 87 ++++++++++++----------
.../org.apache.dubbo.validation.Validation | 3 +-
.../support/jvalidation/JValidatorTest.java | 6 +-
.../java/org/apache/dubbo/rpc/RpcException.java | 9 ++-
9 files changed, 152 insertions(+), 78 deletions(-)
diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index b0236bd..f89b1b8 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -114,6 +114,7 @@
<javax_annotation-api_version>1.3.2</javax_annotation-api_version>
<servlet_version>3.1.0</servlet_version>
<jetty_version>9.4.43.v20210629</jetty_version>
+ <validation_new_version>3.0.1</validation_new_version>
<validation_version>1.1.0.Final</validation_version>
<hibernate_validator_version>5.4.1.Final</hibernate_validator_version>
<jel_version>3.0.1-b08</jel_version>
@@ -395,6 +396,16 @@
<version>${jel_version}</version>
</dependency>
<dependency>
+ <groupId>jakarta.validation</groupId>
+ <artifactId>jakarta.validation-api</artifactId>
+ <version>${validation_new_version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate.validator</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <version>${hibernate_validator_new_version}</version>
+ </dependency>
+ <dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>${jcache_version}</version>
diff --git a/dubbo-filter/dubbo-filter-validation/pom.xml b/dubbo-filter/dubbo-filter-validation/pom.xml
index 51d70ae..e302706 100644
--- a/dubbo-filter/dubbo-filter-validation/pom.xml
+++ b/dubbo-filter/dubbo-filter-validation/pom.xml
@@ -35,6 +35,10 @@
<version>${project.parent.version}</version>
</dependency>
<dependency>
+ <groupId>jakarta.validation</groupId>
+ <artifactId>jakarta.validation-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java
index 0df2752..50699b5 100644
--- a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java
+++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java
@@ -27,8 +27,6 @@ import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.validation.Validation;
import org.apache.dubbo.validation.Validator;
-import javax.validation.ValidationException;
-
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
import static org.apache.dubbo.common.constants.FilterConstants.VALIDATION_KEY;
@@ -90,10 +88,11 @@ public class ValidationFilter implements Filter {
validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
}
} catch (RpcException e) {
+ if(e.isValidation()){
+
+ return AsyncRpcResult.newDefaultAsyncResult(e, invocation);
+ }
throw e;
- } catch (ValidationException e) {
- // only use exception's message to avoid potential serialization issue
- return AsyncRpcResult.newDefaultAsyncResult(new ValidationException(e.getMessage()), invocation);
} catch (Throwable t) {
return AsyncRpcResult.newDefaultAsyncResult(t, invocation);
}
diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidationNew.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidationNew.java
new file mode 100644
index 0000000..32cec16
--- /dev/null
+++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidationNew.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.validation.support.jvalidation;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.validation.Validator;
+import org.apache.dubbo.validation.support.AbstractValidation;
+
+/**
+ * Creates a new instance of {@link Validator} using input argument url.
+ * @see AbstractValidation
+ * @see Validator
+ */
+public class JValidationNew extends AbstractValidation {
+
+ /**
+ * Return new instance of {@link JValidator}
+ * @param url Valid URL instance
+ * @return Instance of JValidator
+ */
+ @Override
+ protected Validator createValidator(URL url) {
+ return new JValidatorNew(url);
+ }
+
+}
diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java
index cc4da05..b6797f6 100644
--- a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java
+++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.common.bytecode.ClassGenerator;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ReflectUtils;
+import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.validation.MethodValidated;
import org.apache.dubbo.validation.Validator;
@@ -51,6 +52,7 @@ import javax.validation.Constraint;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
+import javax.validation.ValidationException;
import javax.validation.ValidatorFactory;
import javax.validation.groups.Default;
import java.lang.annotation.Annotation;
@@ -256,37 +258,42 @@ public class JValidator implements Validator {
@Override
public void validate(String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Exception {
- List<Class<?>> groups = new ArrayList<>();
- Class<?> methodClass = methodClass(methodName);
- if (methodClass != null) {
- groups.add(methodClass);
- }
- Set<ConstraintViolation<?>> violations = new HashSet<>();
- Method method = clazz.getMethod(methodName, parameterTypes);
- Class<?>[] methodClasses;
- if (method.isAnnotationPresent(MethodValidated.class)){
- methodClasses = method.getAnnotation(MethodValidated.class).value();
- groups.addAll(Arrays.asList(methodClasses));
- }
- // add into default group
- groups.add(0, Default.class);
- groups.add(1, clazz);
+ try {
+ List<Class<?>> groups = new ArrayList<>();
+ Class<?> methodClass = methodClass(methodName);
+ if (methodClass != null) {
+ groups.add(methodClass);
+ }
+ Set<ConstraintViolation<?>> violations = new HashSet<>();
+ Method method = clazz.getMethod(methodName, parameterTypes);
+ Class<?>[] methodClasses;
+ if (method.isAnnotationPresent(MethodValidated.class)){
+ methodClasses = method.getAnnotation(MethodValidated.class).value();
+ groups.addAll(Arrays.asList(methodClasses));
+ }
+ // add into default group
+ groups.add(0, Default.class);
+ groups.add(1, clazz);
- // convert list to array
- Class<?>[] classgroups = groups.toArray(new Class[groups.size()]);
+ // convert list to array
+ Class<?>[] classgroups = groups.toArray(new Class[groups.size()]);
- Object parameterBean = getMethodParameterBean(clazz, method, arguments);
- if (parameterBean != null) {
- violations.addAll(validator.validate(parameterBean, classgroups ));
- }
+ Object parameterBean = getMethodParameterBean(clazz, method, arguments);
+ if (parameterBean != null) {
+ violations.addAll(validator.validate(parameterBean, classgroups ));
+ }
- for (Object arg : arguments) {
- validate(violations, arg, classgroups);
- }
+ for (Object arg : arguments) {
+ validate(violations, arg, classgroups);
+ }
- if (!violations.isEmpty()) {
- logger.error("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations);
- throw new ConstraintViolationException("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations, violations);
+ if (!violations.isEmpty()) {
+ logger.error("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations);
+ throw new ConstraintViolationException("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations, violations);
+ }
+ } catch (ValidationException e) {
+ // only use exception's message to avoid potential serialization issue
+ throw new RpcException(RpcException.VALIDATION_EXCEPTION, e.getMessage(), e);
}
}
diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java
similarity index 84%
copy from dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java
copy to dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java
index cc4da05..a23b32f 100644
--- a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java
+++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidatorNew.java
@@ -21,9 +21,17 @@ import org.apache.dubbo.common.bytecode.ClassGenerator;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ReflectUtils;
+import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.validation.MethodValidated;
import org.apache.dubbo.validation.Validator;
+import jakarta.validation.Constraint;
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import jakarta.validation.Validation;
+import jakarta.validation.ValidationException;
+import jakarta.validation.ValidatorFactory;
+import jakarta.validation.groups.Default;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
@@ -47,12 +55,6 @@ import javassist.bytecode.annotation.MemberValue;
import javassist.bytecode.annotation.ShortMemberValue;
import javassist.bytecode.annotation.StringMemberValue;
-import javax.validation.Constraint;
-import javax.validation.ConstraintViolation;
-import javax.validation.ConstraintViolationException;
-import javax.validation.Validation;
-import javax.validation.ValidatorFactory;
-import javax.validation.groups.Default;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
@@ -67,25 +69,25 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
- * Implementation of JValidation. JValidation is invoked if configuration validation attribute value is 'jvalidation'.
+ * Implementation of JValidationNew. JValidationNew is invoked if configuration validation attribute value is 'jvalidationNew'.
* <pre>
- * e.g. <dubbo:method name="save" validation="jvalidation" />
+ * e.g. <dubbo:method name="save" validation="jvalidationNew" />
* </pre>
*/
-public class JValidator implements Validator {
+public class JValidatorNew implements Validator {
- private static final Logger logger = LoggerFactory.getLogger(JValidator.class);
+ private static final Logger logger = LoggerFactory.getLogger(JValidatorNew.class);
private final Class<?> clazz;
private final Map<String, Class> methodClassMap;
- private final javax.validation.Validator validator;
+ private final jakarta.validation.Validator validator;
@SuppressWarnings({"unchecked", "rawtypes"})
- public JValidator(URL url) {
+ public JValidatorNew(URL url) {
this.clazz = ReflectUtils.forName(url.getServiceInterface());
- String jvalidation = url.getParameter("jvalidation");
+ String jvalidation = url.getParameter("jvalidationNew");
ValidatorFactory factory;
if (jvalidation != null && jvalidation.length() > 0) {
factory = Validation.byProvider((Class) ReflectUtils.forName(jvalidation)).configure().buildValidatorFactory();
@@ -256,37 +258,42 @@ public class JValidator implements Validator {
@Override
public void validate(String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Exception {
- List<Class<?>> groups = new ArrayList<>();
- Class<?> methodClass = methodClass(methodName);
- if (methodClass != null) {
- groups.add(methodClass);
- }
- Set<ConstraintViolation<?>> violations = new HashSet<>();
- Method method = clazz.getMethod(methodName, parameterTypes);
- Class<?>[] methodClasses;
- if (method.isAnnotationPresent(MethodValidated.class)){
- methodClasses = method.getAnnotation(MethodValidated.class).value();
- groups.addAll(Arrays.asList(methodClasses));
- }
- // add into default group
- groups.add(0, Default.class);
- groups.add(1, clazz);
+ try {
+ List<Class<?>> groups = new ArrayList<>();
+ Class<?> methodClass = methodClass(methodName);
+ if (methodClass != null) {
+ groups.add(methodClass);
+ }
+ Set<ConstraintViolation<?>> violations = new HashSet<>();
+ Method method = clazz.getMethod(methodName, parameterTypes);
+ Class<?>[] methodClasses;
+ if (method.isAnnotationPresent(MethodValidated.class)){
+ methodClasses = method.getAnnotation(MethodValidated.class).value();
+ groups.addAll(Arrays.asList(methodClasses));
+ }
+ // add into default group
+ groups.add(0, Default.class);
+ groups.add(1, clazz);
- // convert list to array
- Class<?>[] classgroups = groups.toArray(new Class[groups.size()]);
+ // convert list to array
+ Class<?>[] classgroups = groups.toArray(new Class[groups.size()]);
- Object parameterBean = getMethodParameterBean(clazz, method, arguments);
- if (parameterBean != null) {
- violations.addAll(validator.validate(parameterBean, classgroups ));
- }
+ Object parameterBean = getMethodParameterBean(clazz, method, arguments);
+ if (parameterBean != null) {
+ violations.addAll(validator.validate(parameterBean, classgroups ));
+ }
- for (Object arg : arguments) {
- validate(violations, arg, classgroups);
- }
+ for (Object arg : arguments) {
+ validate(violations, arg, classgroups);
+ }
- if (!violations.isEmpty()) {
- logger.error("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations);
- throw new ConstraintViolationException("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations, violations);
+ if (!violations.isEmpty()) {
+ logger.error("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations);
+ throw new ConstraintViolationException("Failed to validate service: " + clazz.getName() + ", method: " + methodName + ", cause: " + violations, violations);
+ }
+ } catch (ValidationException e) {
+ // only use exception's message to avoid potential serialization issue
+ throw new RpcException(RpcException.VALIDATION_EXCEPTION, e.getMessage(), e);
}
}
diff --git a/dubbo-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation b/dubbo-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation
index ae3dc96..98ee4f5 100644
--- a/dubbo-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation
+++ b/dubbo-filter/dubbo-filter-validation/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.validation.Validation
@@ -1 +1,2 @@
-jvalidation=org.apache.dubbo.validation.support.jvalidation.JValidation
\ No newline at end of file
+jvalidation=org.apache.dubbo.validation.support.jvalidation.JValidation
+jvalidationNew=org.apache.dubbo.validation.support.jvalidation.JValidationNew
\ No newline at end of file
diff --git a/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java b/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java
index 01db4b9..acfb7c7 100644
--- a/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java
+++ b/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/support/jvalidation/JValidatorTest.java
@@ -17,12 +17,12 @@
package org.apache.dubbo.validation.support.jvalidation;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.validation.support.jvalidation.mock.ValidationParameter;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-import javax.validation.ConstraintViolationException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -47,11 +47,13 @@ public class JValidatorTest {
@Test
public void testItWhenItViolatedConstraint() throws Exception {
- Assertions.assertThrows(ConstraintViolationException.class, () -> {
+ RpcException rpcException = Assertions.assertThrows(RpcException.class, () -> {
URL url = URL.valueOf("test://test:11/org.apache.dubbo.validation.support.jvalidation.mock.JValidatorTestTarget");
JValidator jValidator = new JValidator(url);
jValidator.validate("someMethod2", new Class<?>[]{ValidationParameter.class}, new Object[]{new ValidationParameter()});
});
+
+ Assertions.assertTrue(rpcException.isValidation());
}
@Test
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcException.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcException.java
index 11bfe82..9ab6afa 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcException.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcException.java
@@ -22,12 +22,10 @@ import javax.naming.LimitExceededException;
* RPC Exception. (API, Prototype, ThreadSafe)
*
* @serial Don't change the class name and properties.
- * @export
* @see org.apache.dubbo.rpc.Invoker#invoke(Invocation)
* @since 1.0
*/
-public /**final**/
-class RpcException extends RuntimeException {
+public class RpcException extends RuntimeException {
public static final int UNKNOWN_EXCEPTION = 0;
public static final int NETWORK_EXCEPTION = 1;
@@ -41,6 +39,7 @@ class RpcException extends RuntimeException {
public static final int REGISTRY_EXCEPTION = 9;
public static final int ROUTER_CACHE_NOT_BUILD = 10;
public static final int METHOD_NOT_FOUND = 11;
+ public static final int VALIDATION_EXCEPTION = 12;
private static final long serialVersionUID = 7815426752583648734L;
/**
* RpcException cannot be extended, use error code for exception type to keep compatibility
@@ -118,4 +117,8 @@ class RpcException extends RuntimeException {
public boolean isLimitExceed() {
return code == LIMIT_EXCEEDED_EXCEPTION || getCause() instanceof LimitExceededException;
}
+
+ public boolean isValidation() {
+ return code == VALIDATION_EXCEPTION;
+ }
}