java 8反射不起作用

标签 java reflection hibernate-validator dynamic-class-loaders string-interning

我们在项目中使用 hibernate validator 和动态类加载(通过将类加载到单独的类加载器中)。在我们意识到不需要该类后,我们删除了对该类和类加载器的所有引用,然后 GC 收集它。

我们得到的结果:应用程序启动一段时间后,java 反射停止工作。

java.lang.reflect.UndeclaredThrowableException: null
    at com.sun.proxy.$Proxy253.equals(Unknown Source)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager$CacheKey.equals(ConstraintValidatorManager.java:287)
    at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:940)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.getInitializedValidator(ConstraintValidatorManager.java:104)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorNoUnwrapping(ConstraintTree.java:301)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorInstanceForAutomaticUnwrapping(ConstraintTree.java:242)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:163)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:116)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateComposingConstraints(ConstraintTree.java:396)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:98)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:87)
    at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:73)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:616)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:581)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:527)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:495)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:460)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:410)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:207)
    at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:281)
    ... Many spring filters calls ...
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:122)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at *someAwesomePackage*.microservice.rest.spring.webapp.CabinetRequestFilter.doFilterInternal(CabinetRequestFilter.java:98)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException: null
    at sun.reflect.GeneratedMethodAccessor268.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.hibernate.validator.internal.util.annotationfactory.AnnotationProxy.invoke(AnnotationProxy.java:69)
    ... 260 common frames omitted
Caused by: java.lang.NullPointerException: null
    at org.hibernate.validator.internal.util.annotationfactory.AnnotationProxy.getAnnotationMemberValue(AnnotationProxy.java:248)
    at org.hibernate.validator.internal.util.annotationfactory.AnnotationProxy.equals(AnnotationProxy.java:104)
    ... 264 common frames omitted

错误发生在这个地方(来自java.lang.Class.java的方法):

 private static Method searchMethods(Method[] methods,
                                    String name,
                                    Class<?>[] parameterTypes) {
    Method res = null;
    String internedName = name.intern();
    for (int i = 0; i < methods.length; i++) {
        Method m = methods[i];
        if (m.getName() == internedName
            && arrayContentsEq(parameterTypes, m.getParameterTypes())
            && (res == null
                || res.getReturnType().isAssignableFrom(m.getReturnType())))
            res = m;
    }
    return (res == null ? res : getReflectionFactory().copyMethod(res));
}

类有方法,但是比较m.getName() == internedName为false。 比较返回 false,因为方法的名称未被保留。

如果我调用m.getName()。 Intern () == internedName 从调试,它返回 true。但是方法“searchMethods”来自“java.lang.Class”。

这总是在应用程序启动一段时间后发生。

有人遇到过这样的问题吗?

编辑(25/12/2017):

不仅hibernate验证失败,xml解析也失败!

XML 示例:

<SELFCARE>
    <SESSION_ID>***</SESSION_ID>
</SELFCARE>

映射示例:

@XmlRootElement(name = "SELFCARE")
@XmlAccessorType(XmlAccessType.FIELD)
public class Session {

    @XmlElement(name = "SESSION_ID")
    private String sessionId;
}

解析异常:

WARN  2017.12.25 20:00:05.991 +0300 org.apache.cxf.jaxrs.provider.AbstractJAXBProvider             javax.xml.bind.UnmarshalException
- with linked exception:
[com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 1; unexpected element (uri:"", local:"SELFCARE"). Expected elements are <{}SELFCARE>]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:483)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:417)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:386)
    at org.apache.cxf.jaxrs.provider.JAXBElementProvider.unmarshalFromInputStream(JAXBElementProvider.java:294)
    at org.apache.cxf.jaxrs.provider.JAXBElementProvider.doUnmarshal(JAXBElementProvider.java:245)

但是映射是正确的并且有效,如果反射有效...

最佳答案

根据堆栈跟踪,我怀疑您使用的是 HV 5.x。我说得对吗?

这个问题似乎与您有代理有关。我认为这可能与注释是 key 的一部分有关。

你能试试 HV 6.0.7.Final 吗?我们在这里不再使用缓存键中的注释,因此它可能会解决您的问题。

注意,我们更改了 groupId:它现在是 org.hibernate.validator(而不是 org.hibernate)- 如果 HV 依赖项是从另一个工件传递过来的,请小心,如果需要,请添加排除项。

您还需要 javax.el 依赖项:

<dependency>
   <groupId>org.glassfish</groupId>
   <artifactId>javax.el</artifactId>
   <version>3.0.1-b08</version>
</dependency>

(小心,您的依赖项中可能还有其他 javax.el 工件,因此请确保只有这个 - Eclipse 的依赖项层次结构 View 可能会有所帮助)

您还需要 validation-api 2.0.1.Final(它随 HV 传递,但如果您明确声明它,则可能必须更改版本)。

除此之外,您不应该有任何兼容性问题(除非您使用的是实验性功能,例如值处理):它是替代品的下降。 HV 6 的速度也明显更快,因此这应该是一个双赢的局面。

如有任何升级问题,请随时在这里报告,我会提供帮助。

关于java 8反射不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47904726/

相关文章:

java - 大 pdf 文件 OutOfMemoryError

java - 派生类构造函数采用基类对象

java - 如何使用 jax-rs 子资源定位器处理持久性上下文 (EntityManager)?

c++是否有类似typeof(Foo)的东西

c# - 在程序集中搜索类型

Java 语法数组 {1,2,3} 与 new int[] {1,2,3}

grails - 如何从自定义验证器Grails中的另一个Domain类引用属性?

hibernate - 使用 Hibernate 验证,我可以查询正在验证的实体吗?

java - 读取以 utf-8 编码的 ValidationMessages

将实现的类分配给接口(interface)时出现Java Reflection NoSuchMethod异常