#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">