Closed vondacho closed 6 months ago
@gsmet @yrodiere is this something that needs to be improved in the Hibernate Validator extension?
Here is the full stacktrace for record purposes (running in Quarkus 3.8.3):
2024-03-20 10:45:57,594 ERROR [io.qua.run.boo.StartupActionImpl] (Quarkus Main Thread) Error running Quarkus: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:113)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.lang.ExceptionInInitializerError
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1160)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(MethodHandleAccessorFactory.java:300)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newConstructorAccessor(MethodHandleAccessorFactory.java:103)
at java.base/jdk.internal.reflect.ReflectionFactory.newConstructorAccessor(ReflectionFactory.java:200)
at java.base/java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:549)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:70)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
at io.quarkus.runner.GeneratedMain.main(Unknown Source)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
... 3 more
Caused by: java.lang.RuntimeException: Failed to start quarkus
at io.quarkus.runner.ApplicationImpl.<clinit>(Unknown Source)
... 16 more
Caused by: java.lang.NoClassDefFoundError: org/apache/tools/ant/taskdefs/MatchingTask
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)
at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:508)
at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:468)
at java.base/java.lang.Class.getDeclaredFields0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredFields(Class.java:3473)
at java.base/java.lang.Class.getDeclaredFields(Class.java:2542)
at org.hibernate.validator.internal.util.privilegedactions.GetDeclaredFields.run(GetDeclaredFields.java:30)
at org.hibernate.validator.internal.util.privilegedactions.GetDeclaredFields.run(GetDeclaredFields.java:17)
at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.run(AnnotationMetaDataProvider.java:602)
at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getFieldMetaData(AnnotationMetaDataProvider.java:217)
at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.retrieveBeanConfiguration(AnnotationMetaDataProvider.java:130)
at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getBeanConfiguration(AnnotationMetaDataProvider.java:121)
at org.hibernate.validator.internal.metadata.PredefinedScopeBeanMetaDataManager.getBeanConfigurationForHierarchy(PredefinedScopeBeanMetaDataManager.java:183)
at org.hibernate.validator.internal.metadata.PredefinedScopeBeanMetaDataManager.createBeanMetaData(PredefinedScopeBeanMetaDataManager.java:150)
at org.hibernate.validator.internal.metadata.PredefinedScopeBeanMetaDataManager.<init>(PredefinedScopeBeanMetaDataManager.java:100)
at org.hibernate.validator.internal.engine.PredefinedScopeValidatorFactoryImpl.<init>(PredefinedScopeValidatorFactoryImpl.java:206)
at org.hibernate.validator.PredefinedScopeHibernateValidator.buildValidatorFactory(PredefinedScopeHibernateValidator.java:42)
at org.hibernate.validator.internal.engine.AbstractConfigurationImpl.buildValidatorFactory(AbstractConfigurationImpl.java:435)
at io.quarkus.hibernate.validator.runtime.HibernateValidatorRecorder$2.created(HibernateValidatorRecorder.java:180)
at io.quarkus.arc.runtime.ArcRecorder.initBeanContainer(ArcRecorder.java:79)
at io.quarkus.deployment.steps.ArcProcessor$notifyBeanContainerListeners1304312071.deploy_0(Unknown Source)
at io.quarkus.deployment.steps.ArcProcessor$notifyBeanContainerListeners1304312071.deploy(Unknown Source)
... 17 more
Caused by: java.lang.ClassNotFoundException: org.apache.tools.ant.taskdefs.MatchingTask
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:518)
at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:468)
... 40 more
note @aloubyansky that this issue is part of the bigger story of us trying to chase the different problems associated with dev mode. apart from this one, and a few difficult to reproduce classloading issues, everything has been solved to date. we will continue testing our apps with dev mode, as we are convinced this is a major strength point for quarkus.
Wow, thanks for the info!
Hey @melloware , can you please explain why this was closed as "not planned" -- for the record?
and what would be the proposed solution? thanks
I thought this was resolved as NOT a POI issue. I am using POI with Hibernate Validator without issue so this is strange. I have re-opened it.
have you tried the reproducer? does it match your situation?
@vsevel yep i think the difference is I am not using @Valid
on a collection
I've created a PR fixing this in https://github.com/quarkusio/quarkus/pull/40383, can someone please give it a try?
I've merged the fix in Quarkus core: https://github.com/quarkusio/quarkus/commit/09685855ecc27e0537cac71c0f46c3384b7770a4
It is marked to be backported, so let's close this issue when the next release containing the fix is available
Quarkus 3.10.1 containing the fix is now available. Closing this issue now
Nice!
Concern
The
quarkus-poi
extension transitively relies onorg.apache.xmlbeans:xmlbeans
dependency which exposes runtime and build-time classes. This can cause failures at build-time, or in devmode when reloading, with an application that uses thequarkus-poi
extension and does bean validation using thehibernate-validation
extension.More generally, this problem can happen with any constellation which includes the
hibernate-validation
extension, one Quarkus extension that depends on theorg.apache.xmlbeans:xmlbeans
dependency, and one DTO class to be validated that has a connection with theAbstractCollection
class.More details
The
HibernateValidatorProcessor
class recursively scans every class to be validated including their fields to be validated, their subclasses and superclass. Once it recursively meets theAbstractCollection
class, it scans every specialization, consequently, it can recursively meets classes fromorg.apache.xmlbeans
, for example theXMLBean$ErrorLogger
one, which parent, theXMLBean
class, extends theorg.apache.tools.ant.taskdefs.MatchingTask
build-time class. This latter is not per default on the classpath and then, the Quarkus application fails at build-time and on reload in devmode.Reproducer
quarkus-poi
andhibernate-validation
extensions in thepom.xml
.AbstractCollection
.@Valid
annotation.Variants
quarkus-poi
extensions in thepom.xml
, and to check that it builds and restart without failure; it works because theorg.apache.xmlbeans
dependency is no more transitively present on the classpath.@Valid
annotation from the field; it works because no recursion is done on the field anymore.org.apache.ant:ant
dependency in thepom.xml
; it works because theMatchingTask
class is present on the classpath. This is not an acceptable and sustainable solution.