ошибка синтаксического анализа в spring-elasticsearch.xsd

#spring #spring-data

#spring #spring-данные

Вопрос:

Я пытаюсь использовать модуль spring data elasticsearch, но я получаю ошибку синтаксического анализа в spring-elasticsearch.xsd при определении моих компонентов.

объявление пространства имен выглядит следующим образом:

 <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd">
  

и я получаю эту ошибку синтаксического анализа:

 SEVERE: Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@795ee430] to prepare test instance [no.di.scheduler.ElasticSearchLoaderTest@44d74990]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:105)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:74)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.junit.runners.Suite.runChild(Suite.java:127)
    at org.junit.runners.Suite.runChild(Suite.java:26)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 40 in XML document from class path resource [dao-config.xml] is invalid; nested exception is org.xml.sax.SAXParseException; systemId: http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd; lineNumber: 40; columnNumber: 116; s4s-att-invalid-value: Invalid attribute value for 'source' in element 'documentation': cvc-datatype-valid.1.2.1.
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:243)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadBeanDefinitions(AbstractGenericContextLoader.java:233)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:117)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
    ... 36 more
Caused by: org.xml.sax.SAXParseException; systemId: http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd; lineNumber: 40; columnNumber: 116; s4s-att-invalid-value: Invalid attribute value for 'source' in element 'documentation': cvc-datatype-valid.1.2.1.
    at org.apache.xerces.parsers.DOMParser.parse(DOMParser.java:267)
    at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:201)
    at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
    ... 49 more
  

Если я загружу документ и удалю атрибут источника из тегов, он будет работать так, как ожидалось.

Связано ли это с тем, что я все еще использую spring 3.2, или есть какая-то другая ошибка, которую я делаю?

Ответ №1:

Недавно я сам наткнулся на эту проблему, и у меня есть обходной путь, который не выглядит красиво (и не использует пространство имен elasticsearch), но использует обернутый объект FactoryBean).

Сначала удалите ссылки xmlns и schemaLocation на elasticsearch xsd, а затем ссылайтесь на TransportClientFactoryBean как на компонент:

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!-- Elasticsearch client -->
  <bean id="esClient" class="org.springframework.data.elasticsearch.client.TransportClientFactoryBean">
    <property name="clusterNodes" value="localhost:9300" />
    <property name="clusterName" value="mycluster" />
  </bean>
  

Теперь вы можете использовать компонент esClient в качестве TransportClient

Комментарии:

1. Спасибо за ответ, мое решение состояло в том, чтобы исправить несоответствие в файле xsd и поместить его в каталог ресурсов и ссылаться на него с помощью classpath вместо http.

2. Не могли бы вы поделиться этим ответом? В частности, как вы «ссылаетесь на это с помощью classpath вместо http». Я уверен, что другие найдут это полезным

Ответ №2:

В ответ на @Chris White.

В моем случае я сохранил файл xsd в META-INF.

1) Загрузите de elasticsearch-1.0.xsd и исправьте ее должным образом.

 <xsd:schema xmlns="http://www.springframework.org/schema/data/elasticsearch" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:tool="http://www.springframework.org/schema/tool" xmlns:repository="http://www.springframework.org/schema/data/repository" targetNamespace="http://www.springframework.org/schema/data/elasticsearch" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xsd:import namespace="http://www.springframework.org/schema/beans"/>
    <xsd:import namespace="http://www.springframework.org/schema/tool"/>
    <xsd:import namespace="http://www.springframework.org/schema/data/repository" schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd"/>
    <xsd:element name="repositories">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="repository:repositories">
                    <xsd:attributeGroup ref="repository:repository-attributes"/>
                    <xsd:attribute name="elasticsearch-template-ref" type="elasticsearchTemplateRef" default="elasticsearchTemplate"/>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>
    <xsd:simpleType name="elasticsearchTemplateRef">
        <xsd:annotation>
            <xsd:appinfo>
                <tool:annotation kind="ref">
                    <tool:assignable-to type="org.springframework.data.elasticsearch.core.ElasticsearchTemplate"/>
                </tool:annotation>
            </xsd:appinfo>
        </xsd:annotation>
        <xsd:union memberTypes="xsd:string"/>
    </xsd:simpleType>
    <xsd:element name="node-client">
        <xsd:annotation>
            <xsd:documentation />
            <xsd:appinfo>
                <tool:assignable-to type="org.elasticsearch.client.Client"/>
            </xsd:appinfo>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="beans:identifiedType">
                    <xsd:attribute name="local" type="xsd:boolean" default="false">
                        <xsd:annotation>
                            <xsd:documentation>
                                <![CDATA[local here means local on the JVM (well, actually class loader) level, meaning that two local servers started within the same JVM will discover themselves and form a cluster]]>
                            </xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="cluster-name" type="xsd:string" default="elasticsearch">
                        <xsd:annotation>
                            <xsd:documentation>
                                <![CDATA[Name of the cluster in which this instance of node client will connect to]]>
                            </xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="http-enabled" type="xsd:boolean" default="true">
                        <xsd:annotation>
                            <xsd:documentation>
                                <![CDATA[ to enable or desable http port ]]>
                            </xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="transport-client">
        <xsd:annotation>
            <xsd:documentation />
            <xsd:appinfo>
                <tool:assignable-to type="org.elasticsearch.client.Client"/>
            </xsd:appinfo>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="beans:identifiedType">
                    <xsd:attribute name="cluster-nodes" type="xsd:string" default="127.0.0.1:9300">
                        <xsd:annotation>
                            <xsd:documentation>
                                <![CDATA[The comma delimited list of host:port entries to use for elasticsearch cluster.]]>
                            </xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="cluster-name" type="xsd:string" default="elasticsearch">
                        <xsd:annotation>
                            <xsd:documentation>
                                <![CDATA[Name of the cluster in which this instance of node client will connect to]]>
                            </xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="client-transport-sniff" type="xsd:boolean" default="true">
                        <xsd:annotation>
                            <xsd:documentation>
                                <![CDATA[The client allows to sniff the rest of the cluster, and add those into its list of machines to use.]]>
                            </xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="client-transport-ignore-cluster-name" type="xsd:boolean" default="false">
                        <xsd:annotation>
                            <xsd:documentation>
                                <![CDATA[Set to true to ignore cluster name validation of connected nodes. (since 0.19.4)]]>
                            </xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="client-transport-ping-timeout" type="xsd:string" default="5s">
                        <xsd:annotation>
                            <xsd:documentation>
                                <![CDATA[The time to wait for a ping response from a node. Defaults to 5s.]]>
                            </xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="client-transport-nodes-sampler-interval" type="xsd:string" default="5s">
                        <xsd:annotation>
                            <xsd:documentation>
                                <![CDATA[How often to sample / ping the nodes listed and connected. Defaults to 5s.]]>
                            </xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>
  

2) Сохраните ее в /webapp/META-INF/

3) Ссылайтесь на нее в schemaLocation и работайте с его определениями в обычном режиме.

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:es="http://www.springframework.org/schema/data/elasticsearch"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/data/elasticsearch
                            META-INF/elasticsearch-1.0.xsd">

    <es:repositories base-package="com.project.repositories" />

    <es:transport-client id="searchClient" cluster-nodes="localhost:9300" />

    <bean name="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
        <constructor-arg name="client" ref="searchClient"/>
    </bean>

</beans>
  

Ответ №3:

Спасибо, Дэни, это работает. Недавно исправление было применено Артуром.

См.:https://jira.spring.io/browse/DATAES-103.

Итак, пока не выйдет следующая версия, вы могли бы использовать, как показано ниже:

 xsi:schemaLocation="http://www.springframework.org/schema/data/elasticsearch https://jira.spring.io/secure/attachment/22773/spring-elasticsearch-1.0-fixed.xsd
                    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">