Hibernate-validator weird IOException: stream closed

I am currently struggling with a very strange problem. Basically I want to use Bean Validation to validate some (non-JPA) entities. However, since object classes are generated, I am currently stuck with defining validation with xml. Since this is a reference implementation, I use hibernate-validator, add the required maven dependencies to the project, and compose a simple xml validation mapping and test.

When the test is done I get an exception

javax.validation.ValidationException: HV000123: Unable to parse META-INF/validation.xml.
at org.hibernate.validator.internal.xml.XmlParserHelper.getSchemaVersion(XmlParserHelper.java:112)
...
Caused by: java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:156)
    at java.io.BufferedInputStream.reset(BufferedInputStream.java:425)
    at org.hibernate.validator.internal.xml.XmlParserHelper.getSchemaVersion(XmlParserHelper.java:109)
    ... 29 more

      

Interestingly, an IOException is thrown in the finally block in XmlParserHelper.getSchemaVersion (...). What's going on here? What could be causing this error? Below are some information about the installation.

The validation files are located in src / main / resources / META-INF (validation.xml and constraints.xml) and look like this:

validation.xml:

<validation-config xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration">
    <default-provider>org.hibernate.validator.HibernateValidator</default-provider>
    <message-interpolator>org.hibernate.validator.engine.ResourceBundleMessageInterpolator</message-interpolator>
    <traversable-resolver>org.hibernate.validator.engine.resolver.DefaultTraversableResolver</traversable-resolver>
    <constraint-validator-factory>org.hibernate.validator.engine.ConstraintValidatorFactoryImpl</constraint-validator-factory>
    <constraint-mapping>/constraints.xml</constraint-mapping>
</validation-config>

      

constraints.xml:

<constraint-mappings xmlns="http://jboss.org/xml/ns/javax/validation/mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd">
    <default-package>com.nano</default-package>
    <bean class="Person">
        <field name="familyName">
            <constraint annotation="javax.validation.constraints.Size">
                <element name="min">4</element>
            </constraint>
        </field>
    </bean>
</constraint-mappings>

      

The corresponding maven dependencies in the project:

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.1.3.Final</version>
    </dependency>
    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>2.2.4</version>
    </dependency>

      

The test in which the exception occurs is a very simple Proof-of-Concept test that does the following:

Person p = new Person();
p.setFamilienName("x");
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Person>> violations = validator.validate(p);
assertEquals(1, violations);

      

+3


source to share


1 answer


Where does this error occur (on which computer setup)? I had the same problem using the hibernate validator in one of our projects. Everything works fine on local computers. For the stages we use IBM AIX servers. On an AIX server with IBM SDK version 6, I get the same exception:

Caused by: javax.validation.ValidationException: HV000123: Unable to parse META-INF/validation.xml.
at org.hibernate.validator.internal.xml.XmlParserHelper.getSchemaVersion(XmlParserHelper.java:108)
at org.hibernate.validator.internal.xml.ValidationXmlParser.parseValidationXml(ValidationXmlParser.java:76)
at org.hibernate.validator.internal.engine.ConfigurationImpl.getBootstrapConfiguration(ConfigurationImpl.java:287)
at org.hibernate.validator.internal.engine.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:361)
at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:214)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
at org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:459)
... 29 more
Caused by: java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:156)
at java.io.BufferedInputStream.reset(BufferedInputStream.java:425)
at org.hibernate.validator.internal.xml.XmlParserHelper.getSchemaVersion(XmlParserHelper.java:105)
... 35 more 

      

Looking at the code for XmlParserHelper

, the following happens:

  • The helper uses validation.xml javax.xml.stream.XmlInputFactory

    to generate the javax.xml.stream.XmlEventReader

    file.
  • The reader is used to get the version attribute of the xml file.
  • Somewhere in the process, the stream to the validation.xml file is closed, resulting in an exception during the call BufferedInputStream.reset()

Since IBM uses its own implementation of StAX 1.0 (XL XP-J 1.1 - see http://www-01.ibm.com/support/knowledgecenter/SSYKE2_6.0.0/com.ibm.java.doc.user.aix64.60/ user / xml / using_xml.html ), this should be something implementation specific.



Because of this, I tried to change the XmlInputFactory implementation to see if it works with a different one. I was able to reproduce the same exception locally using StAX 1.2 from Codehaus. This implementation uses com.bea.xml.stream.MXParserFactory

to create a reader. com.bea.xml.stream.reader.XmlReader.read()

-method closes the stream if nothing is more readable:

    /**
 * Reads the number of characters read into the buffer, or -1 on EOF.
 */
public int read(char buf [], int off, int len) throws IOException
{
int val;

if (closed)
    return -1;      // throw new IOException ("closed");
val = in.read (buf, off, len);
if (val == -1)
    close ();
return val;
}

      

It looks like the IBM SDK has a similar behavior, that it closes the stream when reading (and you probably have that in your environment too).

Solution . I ended up getting it working using a different StAX implementation (JAXP 1.4 reference implementation - see https://jaxp.java.net/ ). He also worked with Woodstox. To change the implementation of StAX in your application, you need to do the following:

  • Add required libraries to your classpath
  • Create META-INF / services directories in your application
  • In META-INF / services create javax.xml.stream.XMLInputFactory file
  • Enter the fully qualified class name of your chosen implementation into this file (for example com.sun.xml.internal.stream.XMLInputFactoryImpl

    )
  • When created XmlInputFactory

    in XmlParserHelper

    , the hibernaet validator uses the class defined in this file.
+3


source







All Articles