Java 8 reflection not working

We use the hibernate validator and the dynamic loading of classes in our project (using the load class in a separate class loader). After we realize that a class is not required, we remove all references to the class and the class loader, then GC collects this.

What we get: some time after launching the application, java reflection stops working.

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 

The error occurs at this place (method from 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)); } 

The class has a method, but the comparison m.getName () == internedName false. The comparison returns false because the method names are not interned.

If I call m.getName (). Intern () == internedName m.getName (). Intern () == internedName from debug, it returns true. But the 'searchMethods' method refers to 'java.lang.Class'.

This always happens some time after the application starts.

Has anyone encountered such a problem?

EDIT (12/25/2017):

Not only an unsuccessful sleep mode validator, also failed to parse xml!

XML example:

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

Matching Example:

 @XmlRootElement(name = "SELFCARE") @XmlAccessorType(XmlAccessType.FIELD) public class Session { @XmlElement(name = "SESSION_ID") private String sessionId; } 

Parsing exception:

 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) 

But the display is correct and works if the reflection works ...

+5
source share
1 answer

From stacktrace, I suspect you are using HV 5.x. I'm right?

The problem seems to be related to the fact that you have a proxy. I think this is probably due to the annotation being part of the key.

Could you try HV 6.0.7.Final? We got rid of the use of annotations in the cache here so that it can solve your problem.

Be careful, we changed groupId: now org.hibernate.validator (instead of org.hibernate) - be careful if the HV dependency is in transit from another artifact, add exceptions if necessary.

You also need the javax.el dependency:

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

(be careful, there may be other javax.el artifacts in your dependencies, so be sure to use only this - it might look like a representation of the Eclipse dependency hierarchy)

You also need validation-api 2.0.1.Final (it comes in transit from HV, but you may need to change the version if you explicitly declared it).

In addition, you should not have compatibility problems (except when you used experimental functions, such as processing values): this is a replacement. HV 6 is also significantly faster, so it should be a win-win situation.

Feel free to report any problems with the update here, I will help.

+1
source

Source: https://habr.com/ru/post/1274219/


All Articles