Context
I'm developing a stand-alone application that reads input-data from a csv-file.
Until now I've used a self-written class to perform input validation,
and the method used for validating a single record from the input file was triggered
immediately after reading a single line. The method was called in the methode for reading the csv-file.
Since the input data will be retrieved by using RESTful Web Services in the future and we'll forfeit using csv-files, I want to decouple the validation from the csv-reading.
I stumpled upon Bean Validation (JSR 380) and used Hibernate Validator to refactor the validation procedure.
I tried both, adding validation-annotations directly to the Bean class, and using a validation.xml file for configuration.
Both ways work when I run the application from Eclipse.
Problem
The application will be deployed as an executable JAR.
I would like to keep the option to change the validation constraints without the need to repack and redeploy the JAR.
So I'm trying to figure out, if there is a way to exclude the validation.xml
(+ further configuration files) from the JAR and put it in some directory "close" to the JAR.
Something like this:
myApp/
|-- JAR
|-- conf/
|-- ValidationMessages.properties
|-- META-INF/
|-- validation.xml
|-- validation/
|-- constraints-myBean.xml
What I tried
Placing the
META-INF/
-folder in the same directory as the JARThe JAR runs, but the validation doesn't work.
Referencing the absolute path to
constraints-myBean.xml
invalidation.xml
, specifically changing
<constraint-mapping>META-INF/validation/constraints-pbpRecord.xml</constraint-mapping>
to
<constraint-mapping>C:/path/to/myApp/META-INF/validation/constraints-pbpRecord.xml</constraint-mapping>
and includingvalidation.xml
in my JAR.A
ValidationException
cancels the execution:
Exception in thread "main" javax.validation.ValidationException: HV000096: Unable to open input stream for mapping file C:/Users/wsteffler/Desktop/pbp_import_tool/pbp_orgunit_import/META-INF/validation/constraints-pbpRecord.xml.
at org.hibernate.validator.internal.xml.config.ValidationBootstrapParameters.setMappingStreams(ValidationBootstrapParameters.java:291)
at org.hibernate.validator.internal.xml.config.ValidationBootstrapParameters.<init>(ValidationBootstrapParameters.java:67)
at org.hibernate.validator.internal.engine.AbstractConfigurationImpl.parseValidationXml(AbstractConfigurationImpl.java:595)
at org.hibernate.validator.internal.engine.AbstractConfigurationImpl.buildValidatorFactory(AbstractConfigurationImpl.java:376)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:103)
at de.uniwuppertal.hisinone.orgunitimport.pbp.Main.main(Main.java:220)
- Adding the parent-directory of
META-INF/
to the classpath (with-classpath
argument)The JAR runs, but the validation doesn't work.
I've read the Bean Validation specification (6.5. Bootstrapping & 9. XML deployment descriptor) and the Hibernate Validator 6.1.0 Reference Guide (8. Configuring via XML), especially looking for solutions in the chapters in parentheses, and searched on StackOverflow and Google for solutions. Unfortunately I haven't found anything that would lead me to a solution so far.
Is it even possible to achieve bootstrapping an external validation.xml
when executing a JAR?
If it is, how can I achieve this?
If you'll need more information or parts from my code, I'll update the question with the required information.
Hibernate Validator clearly doesn't support that. For sure the
validation.xml
needs to be in the jar. We could maybe support having thefile:
prefix to point to external constraint mappings. I would accept a patch if you were willing to work on that.Not sure about the resource bundles though so that would be an half baked solution for you.
I wonder if you could just pass a carefully crafted class loader that can load resources from your external location (and delegate everything else to the standard class loader) and use
externalClassLoader(ClassLoader)
to pass it to HV when configuring theValidatorFactory
.