admin管理员组文章数量:1433506
I have three projects:
1- common-lib, Written with Java 11. It doesn't use Spring, but contains shared classes, error codes, models, DTOs, etc., including custom validation annotations (see below).
2- x service, Written with Java 11, using Spring 2.6.
3- y service, Written with Java 17, using Spring 3.2.
Problem: My Java 11 services (x service) can use common-lib easily, including the validation annotations. However, my Java 17 service (y service) can use the models, error codes, and other common classes from common-lib, but cannot use the validation annotations.
The issue appears to be related to the transition from javax.validation to jakarta.validation and other potential bytecode issues.
@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = IsValidSms.SmsValidator.class)
public @interface IsValidSms {
String message() default "INVALID_REQUEST_BODY";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
class SmsValidator implements ConstraintValidator<IsValidSms, SmsRequest> {
public boolean isValid(SmsRequest smsRequest, ConstraintValidatorContext constraintContext) {
final String smsType = smsRequest.getSmsType();
if (Objects.isNull(smsType) || smsType.isBlank()) {
return Objects.nonNull(smsRequest.getContent());
}
return isValidPlaceholders(smsRequest.getPlaceholders());
}
private boolean isValidPlaceholders(Map<String, String> placeholders) {
if (Objects.isNull(placeholders) || placeholders.isEmpty()) {
return true;
}
return placeholders.keySet().stream().allMatch(key -> key.startsWith("{{") && key.endsWith("}}"));
}
}
}
Context: common-lib is in Java 11 and uses javax.validation annotations. y service is in Java 17 and uses Spring 3.2, which is built on jakarta.validation. The Java 17 service can’t resolve the javax.validation annotations from the common-lib due to changes in the bytecode and the switch from javax to jakarta.
Question: How can I resolve this issue and make the common-lib (Java 11, javax.validation) work with the Java 17 service (which uses Spring 3.2 and jakarta.validation)?
What I've tried: Including jakarta.validation dependencies in the y service, but that doesn't resolve the issue. Adding javax.validation dependency manually to the y service. I'm looking for a solution that allows me to use the validation annotations in the y service without changing the common-lib project.
common-lib ->
dependencies {
testImplementation '.mockito:mockito-core:3.5.9'
testImplementation '.mockito:mockito-junit-jupiter:3.5.9'
compileOnly '.projectlombok:lombok'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.11.3'
implementation group: '.hibernate.validator', name: 'hibernate-validator', version: '6.1.6.Final'
implementation 'commons-validator:commons-validator:1.7'
testImplementation group: '.glassfish', name: 'javax.el', version: '3.0.0'
annotationProcessor '.projectlombok:lombok'
testImplementation '.junit.jupiter:junit-jupiter-api:5.5.2'
testRuntimeOnly '.junit.jupiter:junit-jupiter-engine:5.5.2'
testRuntimeOnly '.junit.vintage:junit-vintage-engine:5.5.2'
implementation '.springframework:spring-beans:5.3.20'
}
solution suggestion.
I have three projects:
1- common-lib, Written with Java 11. It doesn't use Spring, but contains shared classes, error codes, models, DTOs, etc., including custom validation annotations (see below).
2- x service, Written with Java 11, using Spring 2.6.
3- y service, Written with Java 17, using Spring 3.2.
Problem: My Java 11 services (x service) can use common-lib easily, including the validation annotations. However, my Java 17 service (y service) can use the models, error codes, and other common classes from common-lib, but cannot use the validation annotations.
The issue appears to be related to the transition from javax.validation to jakarta.validation and other potential bytecode issues.
@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = IsValidSms.SmsValidator.class)
public @interface IsValidSms {
String message() default "INVALID_REQUEST_BODY";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
class SmsValidator implements ConstraintValidator<IsValidSms, SmsRequest> {
public boolean isValid(SmsRequest smsRequest, ConstraintValidatorContext constraintContext) {
final String smsType = smsRequest.getSmsType();
if (Objects.isNull(smsType) || smsType.isBlank()) {
return Objects.nonNull(smsRequest.getContent());
}
return isValidPlaceholders(smsRequest.getPlaceholders());
}
private boolean isValidPlaceholders(Map<String, String> placeholders) {
if (Objects.isNull(placeholders) || placeholders.isEmpty()) {
return true;
}
return placeholders.keySet().stream().allMatch(key -> key.startsWith("{{") && key.endsWith("}}"));
}
}
}
Context: common-lib is in Java 11 and uses javax.validation annotations. y service is in Java 17 and uses Spring 3.2, which is built on jakarta.validation. The Java 17 service can’t resolve the javax.validation annotations from the common-lib due to changes in the bytecode and the switch from javax to jakarta.
Question: How can I resolve this issue and make the common-lib (Java 11, javax.validation) work with the Java 17 service (which uses Spring 3.2 and jakarta.validation)?
What I've tried: Including jakarta.validation dependencies in the y service, but that doesn't resolve the issue. Adding javax.validation dependency manually to the y service. I'm looking for a solution that allows me to use the validation annotations in the y service without changing the common-lib project.
common-lib ->
dependencies {
testImplementation '.mockito:mockito-core:3.5.9'
testImplementation '.mockito:mockito-junit-jupiter:3.5.9'
compileOnly '.projectlombok:lombok'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.11.3'
implementation group: '.hibernate.validator', name: 'hibernate-validator', version: '6.1.6.Final'
implementation 'commons-validator:commons-validator:1.7'
testImplementation group: '.glassfish', name: 'javax.el', version: '3.0.0'
annotationProcessor '.projectlombok:lombok'
testImplementation '.junit.jupiter:junit-jupiter-api:5.5.2'
testRuntimeOnly '.junit.jupiter:junit-jupiter-engine:5.5.2'
testRuntimeOnly '.junit.vintage:junit-vintage-engine:5.5.2'
implementation '.springframework:spring-beans:5.3.20'
}
solution suggestion.
Share Improve this question edited Nov 19, 2024 at 12:44 Mert Karaman asked Nov 18, 2024 at 13:10 Mert KaramanMert Karaman 112 bronze badges 1 |1 Answer
Reset to default 1You have to make two annotation types, which will be identical except for their import
statements. The good news is, they can coexist without any problems:
import java.util.Map;
import java.util.Objects;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = IsValidSmsLegacy.SmsValidator.class)
public @interface IsValidSmsLegacy {
// ...
}
And:
import java.util.Map;
import java.util.Objects;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = IsValidSms.SmsValidator.class)
public @interface IsValidSms {
// ...
}
And of course, in your code, you’ll have things like:
@IsValidSms
@IsValidSmsLegacy
public class Message {
// ...
}
Side note: Objects.isNull is not meant to be a universal replacement for the != null
check. Objects.isNull is intended for cases where code needs a method reference; for example:
public void process(Collection<String> values) {
Objects.requireNonNull(values, "Value set cannot be null.");
if (values.stream().anyMatch(Objects::isNull)) {
throw new IllegalArgumentException(
"Value set cannot contain null elements.");
}
// ...
}
本文标签:
版权声明:本文标题:How can I use a common Java 11 library with validation annotations in a Java 17 Spring Boot service? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745615943a2666401.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
javax.validation
andjakarta.validation
) on your classes incommon-lib
and based on what is being used it will use the proper one and ignore the other. – M. Deinum Commented Nov 18, 2024 at 13:29