2

I'm having an issue using bean validation with Android. I've included the validation api and hibernate validator 4.0.1 to the libs and assets folder. The code for validating the input is the following

/* This doesn't work either
 * 
 * ValidatorFactory factory = Validation
 *      .byProvider(HibernateValidator.class).configure()
 *      .buildValidatorFactory();
 */

    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

    Validator validator = factory.getValidator();
    Set<ConstraintViolation<Class<Department>>> violations = validator
            .validate(Department.class);

    for (ConstraintViolation<Class<Department>> v : violations) {
        // do something useful
    }

I get a ValidationException, which states that no default provider is found. The commented part doesn't work either. It also throws a ValidationException stating it is unable to find the provider org.hibernate.validator.HibernateValidator.

02-04 07:44:22.388: E/AndroidRuntime(946): Caused by: javax.validation.ValidationException: Unable to find provider: class org.hibernate.validator.HibernateValidator
02-04 07:44:22.388: E/AndroidRuntime(946):  at javax.validation.Validation$ProviderSpecificBootstrapImpl.configure(Validation.java:223)
02-04 07:44:22.388: E/AndroidRuntime(946):  at com.example.testapp.MainActivity.validate(MainActivity.java:51)
02-04 07:44:22.388: E/AndroidRuntime(946):  at com.example.testapp.MainActivity.anlegen(MainActivity.java:46)
02-04 07:44:22.388: E/AndroidRuntime(946):  ... 14 more

Did I miss something while configuring? Or is hibernate not applicable for android?

UPDATE

I tried to implement ValidatorProviderResolver as @Gunnar suggested. The code changed to:

HibernateValidatorConfiguration config = Validation
            .byProvider(HibernateValidator.class)
            .providerResolver(new MyAndroidValidationProviderResolver())
            .configure();
ValidatorFactory factory = config.buildValidatorFactory();
Validator v = factory.getValidator();

Now I get Exceptions like:

02-05 20:21:36.642: E/AndroidRuntime(792): Caused by: java.lang.IllegalArgumentException: Invalid logger interface org.hibernate.validator.internal.util.logging.Log (implementation not found)
02-05 20:21:36.642: E/AndroidRuntime(792):  at org.jboss.logging.Logger.getMessageLogger(Logger.java:2250)
02-05 20:21:36.642: E/AndroidRuntime(792):  at org.jboss.logging.Logger.getMessageLogger(Logger.java:2214)
02-05 20:21:36.642: E/AndroidRuntime(792):  at org.hibernate.validator.internal.util.logging.LoggerFactory.make(LoggerFactory.java:29)
02-05 20:21:36.642: E/AndroidRuntime(792):  at org.hibernate.validator.internal.util.Version.<clinit>(Version.java:27)
02-05 20:21:36.642: E/AndroidRuntime(792):  ... 21 more

I also switched to Hibernate 5.0.3 final including ALL libraries (required as well as optional).

  • Which version of Bean Validation are you adding? I am no Android specialist, but I am wondering whether the Java ServiceLoader approach works on Android at all (via META-INF/services). This is how Validation tries to bootstrap the _ValidationProvider_. Are there no restrictions regarding META-INF on Android? – Hardy Feb 05 '14 at 10:34
  • I am using validation API Version 1.1 [This topic](http://stackoverflow.com/questions/19551882/jsr-303-compatible-bean-validator-for-android) seems to address the same issue, but I don't get how the problem is solved yet. – Matthias Hanske Feb 05 '14 at 13:05
  • 1
    The idea is to write your own `ValidationProviderResolver` which just returns `HibernateValidator` so you don't need to rely on the service loader mechanism used by default (as Hardy is saying that's not working on Android). – Gunnar Feb 05 '14 at 15:48
  • > I also switched to Hibernate 5.0.3 final including ALL libraries (required as well as optional). Can you list the artfacts you are adding? According to the message the JBoss logger cannot find the Log interface of Hibernate Validator. That seems odd though. – Hardy Feb 06 '14 at 10:14
  • It seems that when placing the jars to /libs Android SDK removes classes which don't fit a given name pattern. The required impl of the Log interface `Log_$logger` is missing afterwards. Stripping it out of the jar and adding it manually to /bin causes the dex loader to crash with the message: Unable to execute dex: Multiple dex files define Lorg/hibernate/validator/internal/util/logging/Log_$logger; – Matthias Hanske Feb 06 '14 at 12:02
  • These are all the libraries I'm including in the libs folder: `classmate-1.0.0.jar, hibernate-jpa-2.1-api-1.0.0.Draft-16.jar, hibernate-validator-5.0.3.Final.jar, hibernate-validator-annotation-processor.5.0.3.Final.jar, hibernate-validator-cdi-5.0.3.Final.jar, javax.el-2.2.4.jar, javax.el-api.2.2.4.jar, jboss-logging-3.1.1.GA.jar, joda-time-2.1.jar, jsoup-1.7.1.jar, log4j-1.2.17.jar, validation-api-1.1.0.Final.jar` – Matthias Hanske Feb 06 '14 at 12:04
  • If the logger class is indeed filtered out, you have indeed a problem. I wonder where the allowed class names for Android are defined!? – Hardy Feb 10 '14 at 11:04

1 Answers1

1

The org.hibernate.validator.internal.util.logging.Log interface uses 2 classes not supported by Android: javax.xml.bind.JAXBException and javax.xml.stream.XMLStreamException. That's why the class is not loaded.