关键字:org.xml.sax.SAXParseException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'class'. No
child element is expected at this point.
这段时间做的一个项目,部署环境是GlassFish,但始终部署失败,但在tomcat下一切正常。错误如下:
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'class'. No child element is
expected at this point.
at com.sun.enterprise.deployment.io.DeploymentDescriptorFile.read(DeploymentDescriptorFile.java:304)
at com.sun.enterprise.deployment.archivist.ExtensionsArchivist.open(ExtensionsArchivist.java:115)
at com.sun.enterprise.deployment.archivist.PersistenceArchivist.readPersistenceDeploymentDescriptor(PersistenceArchivist.java:125)
at com.sun.enterprise.deployment.archivist.WarPersistenceArchivist.open(WarPersistenceArchivist.java:88)
at com.sun.enterprise.deployment.archivist.Archivist.readRestDeploymentDescriptors(Archivist.java:383)
at com.sun.enterprise.deployment.archivist.Archivist.readDeploymentDescriptors(Archivist.java:373)
at com.sun.enterprise.deployment.archivist.Archivist.open(Archivist.java:238)
at com.sun.enterprise.deployment.archivist.Archivist.open(Archivist.java:247)
at com.sun.enterprise.deployment.archivist.Archivist.open(Archivist.java:208)
at com.sun.enterprise.deployment.archivist.ApplicationFactory.openArchive(ApplicationFactory.java:161)
at org.glassfish.javaee.core.deployment.DolProvider.load(DolProvider.java:162)
... 31 more
引起的原因是在persistence.xml文件中:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="MyProject" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.generate_statistics" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.provider_configuration_file_resource_path" value="ehcache/ehcache-hibernate-local.xml"/>
<property name="hibernate.jdbc.fetch_size" value="50"/>
<property name="hibernate.jdbc.batch_size" value="30"/>
</properties>
<!--报错说此行无效-->
<class>org.workin.trace.domain.BehaviorPerformance</class>
</persistence-unit>
</persistence>
这样配置的原因是项目中有部分实体类是放在Jar包中的,需要显示配置才能扫描得到。在网上找了N久,始终未能解决。 昨天将
eclipse工作区下的.metadata文件夹删掉,重新建立一个工作区,发现该项目persistence.xml文件中<class>com.xxx</class>这一行报错。起初还以为是XSD引用错误,但是比对了一下,这个和官网上的一模一样。
在多次失败之后,我将<class>...</class> 放到<properties>...</properties>之前定义,发现eclipse验证居然通过了。再将其发布到GlassFish下,问题不再出现。
更改之后的代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="MyProject" transaction-type="RESOURCE_LOCAL">
<class>org.workin.trace.domain.BehaviorPerformance</class>
<properties>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.generate_statistics" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.provider_configuration_file_resource_path" value="ehcache/ehcache-hibernate-local.xml"/>
<property name="hibernate.jdbc.fetch_size" value="50"/>
<property name="hibernate.jdbc.batch_size" value="30"/>
</properties>
</persistence-unit>
</persistence>
错误发生原因: W3C XML架构xsd规范中<xsd:sequence>要求组中的元素以指定的顺序出现在包含元素中,Glassfish在部署时会根据xsd对文件进行验证。而Tomcat中未出现类似问题,原因可能是GlassFish的验证比Tomcat更加严谨。
总结: 在用Eclipse开发时,validation这一项尽量不要禁用,虽然开启它会使得Eclipse速度很慢,但是却能及时提醒你错误信息。