Uploaded image for project: 'Hibernate Validator'
  1. HV-1017

javafx detection uses TCCL but JavaFXPropertyValueUnwrapper does not

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5.2.1.Final
    • Fix Version/s: 5.2.2.Final
    • Component/s: engine
    • Labels:
      None

      Description

      When bootstrapping Hibernate Validator, ConfigurationImpl's constructor is called which contains:

      if ( isJavaFxInClasspath() ) {
      	validatedValueHandlers.add( new JavaFXPropertyValueUnwrapper( typeResolutionHelper ) );
      }
      

      The classloading mechanism used to implement method isJavaFxInClasspath() is inconsistent with that used in JavaFXPropertyValueUnwrapper constructor.

      isJavaFxInClasspath uses the LoadClass util to check if the class javafx.application.Application exists. When this util fails to load the class through Class.forName it falls back to the ThreadContext ClassLoader.

      JavaFXPropertyValueUnwrapper is a generic class parameterized with javafx.beans.value.ObservableValue. Its superclass constructor in TypeResolverBasedValueUnwrapper indirectly tries to load the ObservableValue class when resolving it's subclass type through classmate's TypeResolver. However, this does NOT fallback to the context class loader.

      I have an Eclipse-based OSGi application that worked fine with Hibernate Validator 5.0.2.Final but fails bootstrapping Hibernate Validator with 5.2.1.Final due to this. I am not using javafx which means that the normal classloader cannot load javafx classes. Somehow the TCCL that Eclipse uses can load them leading to

      ClassNotFoundException: javafx.beans.value.ObservableValue.
      

      A workaround for me is to temporarily set the TCCL to null or to the normal classloader.

      Expected behavior would be for Hibernate Validator to should either successfully create the JavaFXPropertyValueUnwrapper or skip it, but not throw an exception when the TCCL differs from the normal classloader.

      The exception I get:

      Caused by: javax.validation.ValidationException: Unable to instantiate Configuration.
      	at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:279)
      	at nl.hm.olga.validation.ValidatorFactoryFactory.create(ValidatorFactoryFactory.java:59)
      	at nl.hm.olga.validation.ValidationUtil.<clinit>(ValidationUtil.java:58)
      	... 86 more
      Caused by: java.lang.TypeNotPresentException: Type javafx.beans.value.ObservableValue not present
      	at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117)
      	at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
      	at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
      	at sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68)
      	at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138)
      	at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
      	at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:87)
      	at java.lang.Class.getGenericSuperclass(Class.java:777)
      	at com.fasterxml.classmate.TypeResolver._resolveSuperClass(TypeResolver.java:424)
      	at com.fasterxml.classmate.TypeResolver._constructType(TypeResolver.java:395)
      	at com.fasterxml.classmate.TypeResolver._fromClass(TypeResolver.java:351)
      	at com.fasterxml.classmate.TypeResolver.resolve(TypeResolver.java:111)
      	at org.hibernate.validator.internal.engine.valuehandling.TypeResolverBasedValueUnwrapper.resolveSingleTypeParameter(TypeResolverBasedValueUnwrapper.java:41)
      	at org.hibernate.validator.internal.engine.valuehandling.TypeResolverBasedValueUnwrapper.<init>(TypeResolverBasedValueUnwrapper.java:29)
      	at org.hibernate.validator.internal.engine.valuehandling.JavaFXPropertyValueUnwrapper.<init>(JavaFXPropertyValueUnwrapper.java:23)
      	at org.hibernate.validator.internal.engine.ConfigurationImpl.<init>(ConfigurationImpl.java:117)
      	at org.hibernate.validator.internal.engine.ConfigurationImpl.<init>(ConfigurationImpl.java:95)
      	at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:31)
      	at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:276)
      	... 88 more
      Caused by: java.lang.ClassNotFoundException: javafx.beans.value.ObservableValue
      	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513)
      	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
      	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
      	at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
      	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
      	at java.lang.Class.forName0(Native Method)
      	at java.lang.Class.forName(Class.java:348)
      	at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
      	... 106 more
      

        Attachments

          Issue links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: