0

I am trying to inject Spring data repository (Elasticsearch in this instance) in SE application, using Weld SE.

Repository

public interface EmployeeRepository extends ElasticsearchRepository<Employee, String> {
List<Employee> findEmployeesByAge(int age);
List<Employee> findEmployeesByName(String name);
List<Employee> findEmployeesBySkillsIn(List skills);
}

Defining ElasticsearchTemplate:

@ApplicationScoped
public class ElasticsearchTemplateProducer {

@Produces
public ElasticsearchOperations createElasticsearchTemplate() {

    Client client = null;

    try {
        client = TransportClient.builder().build()
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }

    return new ElasticsearchTemplate(client);
}

}

Main (application is executed with org.jboss.weld.environment.se.StartMain) is as simple as:

public class Main {

@Inject
private Service repository;

public static void main(@Observes ContainerInitialized event){
}
}

Dependencies are:

<dependencies>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-elasticsearch</artifactId>
        <version>2.0.2.RELEASE</version>
        <exclusions>
            <exclusion>
                <artifactId>spring-context</artifactId>
                <groupId>org.springframework</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.jboss.weld.se</groupId>
        <artifactId>weld-se-core</artifactId>
        <version>2.3.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss</groupId>
        <artifactId>jandex</artifactId>
        <version>1.2.2.Final</version>
    </dependency>
</dependencies>

I've excluded spring context, but I get same exception whether or not I exclude context.

In resources\META_INF\beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
   <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                       http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
   version="1.1" bean-discovery-mode="all"
   xmlns:weld="http://jboss.org/schema/weld/beans">
<weld:scan>
    <weld:exclude name="org.jboss.weld.**" />
</weld:scan>

And exception being thrown is:

javax.enterprise.inject.UnsatisfiedResolutionException: Unable to resolve a bean for 'org.springframework.data.elasticsearch.core.ElasticsearchOperations' with qualifiers [@javax.enterprise.inject.Default(), @javax.enterprise.inject.Any()].
at org.springframework.data.elasticsearch.repository.cdi.ElasticsearchRepositoryExtension.createRepositoryBean(ElasticsearchRepositoryExtension.java:75)
at org.springframework.data.elasticsearch.repository.cdi.ElasticsearchRepositoryExtension.afterBeanDiscovery(ElasticsearchRepositoryExtension.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:88)
at org.jboss.weld.injection.MethodInvocationStrategy$SpecialParamPlusBeanManagerStrategy.invoke(MethodInvocationStrategy.java:144)
at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:309)
at org.jboss.weld.event.ExtensionObserverMethodImpl.sendEvent(ExtensionObserverMethodImpl.java:124)
at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:287)
at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:265)
at org.jboss.weld.event.ObserverNotifier.notifySyncObservers(ObserverNotifier.java:271)
at org.jboss.weld.event.ObserverNotifier.notify(ObserverNotifier.java:260)
at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:154)
at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:148)
at org.jboss.weld.bootstrap.events.AbstractContainerEvent.fire(AbstractContainerEvent.java:53)
at org.jboss.weld.bootstrap.events.AbstractDefinitionContainerEvent.fire(AbstractDefinitionContainerEvent.java:42)
at org.jboss.weld.bootstrap.events.AfterBeanDiscoveryImpl.fire(AfterBeanDiscoveryImpl.java:61)
at org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:423)
at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:83)
at org.jboss.weld.environment.se.Weld.initialize(Weld.java:557)
at org.jboss.weld.environment.se.StartMain.go(StartMain.java:44)
at org.jboss.weld.environment.se.StartMain.main(StartMain.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

at org.jboss.weld.bootstrap.events.AbstractDefinitionContainerEvent.fire(AbstractDefinitionContainerEvent.java:44)
at org.jboss.weld.bootstrap.events.AfterBeanDiscoveryImpl.fire(AfterBeanDiscoveryImpl.java:61)
at org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:423)
at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:83)
at org.jboss.weld.environment.se.Weld.initialize(Weld.java:557)
at org.jboss.weld.environment.se.StartMain.go(StartMain.java:44)
at org.jboss.weld.environment.se.StartMain.main(StartMain.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

What is the cause of this problem?

Sarpy
  • 265
  • 1
  • 7
  • 18
  • It looks like, spring uses CDI extension here. Are you sure, that extension was registered? i.e mentioned in META-INF/services/javax.enterprise.inject.spi.Extension – temaleva Sep 02 '16 at 09:22
  • I am certain that extension was registered, Spring Elasticsearch registers extension in source code. If I also register it as you specified, I can see in console output that extension has been registered twice. Nevertheless, I found a workaround for this issue – Sarpy Sep 02 '16 at 13:26

1 Answers1

0

After a bit of debugging, I've noticed that no beans are being stored in elasticsearchOperationsMap in CDI extension ElasticsearchRepositoryExtension during processing beans phase, which causes an exception to be thrown later.

For now, I am using a workaround. I add annotation @NoRepositoryBean to interface:

@NoRepositoryBean
public interface EmployeeRepository extends ElasticsearchRepository<Employee, String>

And then use the following @Produces method:

@Produces
public EmployeeRepository getEmployeeRepository() {

    Client client = null;

    try {
        client = TransportClient.builder().build()
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }


    ElasticsearchRepositoryFactory elasticsearchRepositoryFactory = new ElasticsearchRepositoryFactory(new ElasticsearchTemplate(client));

    return elasticsearchRepositoryFactory.getRepository(EmployeeRepository.class);
}
Sarpy
  • 265
  • 1
  • 7
  • 18