问题描述
获取java.lang.NoSuchMethodError:使用休眠6.1.6时没有虚拟方法getAnnotatedInterfaces()异常。我正在使用Java 8,并希望使用休眠6.1.6来使用容器元素约束。
this post处的解决方案可以正常工作,但适用于5.1.3版最终版。
Dependencies
compile group: 'org.hibernate',name: 'hibernate-validator',version: '6.1.6.Final'
compile group: 'org.glassfish',name: 'jakarta.el',version: '3.0.3'
compile group: 'org.hibernate',name: 'hibernate-validator-cdi',version: '6.1.6.Final'
遇到错误
2020-10-11 09:52:13.515 20928-20928/com.applab.peermainactivity E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.applab.peermainactivity,PID: 20928
java.lang.NoSuchMethodError: No virtual method getAnnotatedInterfaces()[Ljava/lang/reflect/AnnotatedType; in class Ljava/lang/Class; or its super classes (declaration of 'java.lang.class' appears in /system/framework/core-oj.jar)
at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor.determineValueExtractorDeFinitions(ValueExtractorDescriptor.java:150)
at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor.getValueExtractorDeFinition(ValueExtractorDescriptor.java:123)
at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor.<init>(ValueExtractorDescriptor.java:45)
at org.hibernate.validator.internal.engine.valueextraction.ByteArrayValueExtractor.<clinit>(ByteArrayValueExtractor.java:16)
at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager.<clinit>(ValueExtractorManager.java:60)
at org.hibernate.validator.internal.engine.ValidatorFactoryImpl.<init>(ValidatorFactoryImpl.java:169)
at org.hibernate.validator.HibernateValidator.buildValidatorFactory(HibernateValidator.java:38)
at org.hibernate.validator.internal.engine.AbstractConfigurationImpl.buildValidatorFactory(AbstractConfigurationImpl.java:448)
at com.applab.peermainactivity.BaseActivity.<clinit>(BaseActivity.java:27)
at java.lang.class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:41)
at android.app.Instrumentation.newActivity(Instrumentation.java:1216)
at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:2864)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6826)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
基本活动
import android.annotation.SuppressLint;
import androidx.appcompat.app.AppCompatActivity;
import com.applab.peermainactivity.utilities.LogUtils;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
@SuppressLint("Registered")
public class BaseActivity extends AppCompatActivity {
public static final boolean DEBUG=true;
private static final Validator validator;
static {
validator=Validation
.byDefaultProvider()
.configure()
.ignoreXmlConfiguration()
.buildValidatorFactory().getValidator();
}
public <T> Set<ConstraintViolation<T>> validate(T object,Class<?>... groups){
Set<ConstraintViolation<T>> violations= validator.validate(object,groups);
if (DEBUG){
for (ConstraintViolation<T> constraintViolation:violations)
LogUtils.log(constraintViolation);
}
return violations;
}
public <T> boolean isValid(T object,Class<?>... groups){
return validate(object,groups).size()==0;
}
}
解决方法
有趣。
问题显然是Android JDK中缺少的方法,但是对于内置的值提取器,我们可以避免所有这些机制,并静态声明ValueExtractor
元数据,而不是进行反射调用,从而避免了在标准情况下使用此方法。