spring data elasticsearch Invocation of init method failed; nested exception is java.lang.AbstractMethodError - spring-java-config

I have problem with Spring Data Elasticsearch. I configure elasticsearch like this:
#Configuration
#EnableJpaRepositories(basePackages = {"org.project.repositories"})
#EnableElasticsearchRepositories(basePackages = "org.project.repositorieselastic")
#EnableTransactionManagement
public class PersistenceContext {
#Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchTemplate(client());
}
#Bean
public Client client(){
Settings settings = ImmutableSettings.settingsBuilder()
// Setting "transport.type" enables this module:
.put("cluster.name", "elasticsearch")
.put("client.transport.ignore_cluster_name", false)
.build();
TransportClient client= new TransportClient(settings);
TransportAddress address = new InetSocketTransportAddress("127.0.0.1", 9300);
client.addTransportAddress(address);
return client;
}
}
My repo looks like.
#Repository()
public interface UserFavoriteElasticRepo extends ElasticsearchRepository<UserFavorite, Long> {
}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.project.repositorieselastic.UserFavoriteElasticRepo org.project.services.elastic.FavoriteIndexerService.elasticRepo; nested exception
is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userFavoriteElasticRepo': Invocation of init method failed; nested exception is java.lang.AbstractMethodError
It's look like the implementation is not generated. But I don't know where to investigate. I tried to use one package and use this - https://github.com/izeye/spring-boot-throwaway-branches/commit/874ccba09189d6ef897bc430c43b6e3705404399 but with no success.

I solved the problem adding this in pom file
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.12.2.RELEASE</version>
</dependency>

I've got same exception using spring-data-elasticsearch.
But exception was thrown when I declared new methods in repository:
ex.:
public interface UserFavoriteElasticRepo extends ElasticsearchRepository<UserFavorite, Long> {
Page<UserFavorite> findBySomeProperty(String propertyValue, Pageable pageable);
}
It was casued due to spring-data-elasticsearch, spring-data-commons versions. Function declarations have changed: org.springframework.data.repository.query.QueryLookupStrategy.resolveQuery - it caused the exception.
For spring-data-elasticsearch version 2.0.0.RELEASE you have to use spring-data-commons with version 1.12.0.
If you have spring-data-jpa in your project it also uses spring-data-commons. For spring-data-jpa v1.9.0.RELEASE, spring-data-commons is v1.11.0.RELEASE
Could you provide what frameworks and versions of spring you are using? Also If you could put whole stacktrace, it will be helpfull?

Related

spring attempt to inject #Autowired dependencies in a Mocked instance

I have the following classes:
com.foo.pkgx:
#Component public class A {}
#Component public class B {
#Autowired A a;
}
com.foo.pkgy:
#Component public class C {
#Autowired B b;
}
I.E. dependency-wise: C -> B -> A
When executing the following spock Specification:
#Configuration
#ComponentScan(basePackages = ["com.foo.pkgy"])
class Config {
def mockFactory = new DetachedMockFactory()
#Bean
B b() {mockFactory.Mock(B)};
}
#ContextConfiguration(classes = Config)
class CSpec extends Specification {
#Autowired
C c;
def "sanity"() {
expect: c
}
}
The test fails initialization:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'c':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.foo.pkgx.B com.foo.pkgy.C.b;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'b':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.foo.pkgx.A com.foo.pkgx.B.a;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.foo.pkgx.A] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I read this as "tried to wire A into B, but failed". I wasn't expecting B to undergo autowiring, as it is mocked.
Could someone shed some light?
Thanks!
Mock of a class is a subclass generated by code-generation library, byte-buddy or cglib-nodep to name a few. It's a regular bean from Spring perspective. And once any bean is instantiated then at some point, Spring starts "introspection" of the bean by means of various ...BeanPostProcessors. E.g. Autowiring is handled by AutowiredAnnotationBeanPostProcessor. This postprocessor works in such a way that each bean is inspected through the entire class hierarchy. So your class B is there with #Autowired field A and Spring tries to resolve this dependency with no luck.
The good news, however, is that there is a demand for such a feature of disabling autowiring on a per-bean basis. And looks like eventually, Spring team will introduce it soon.
Meanwhile you can just mock A so that B's dependency is resolved. Or you can just use interfaces for your components, instead of using just classes. I believe the latter is the best practice

How to configure CXF servlet in Springboot 2.1.1 Final?

PLease find the error I am facing :
In springboot 2.1.1 I am getting below error :
APPLICATION FAILED TO START
Description: Parameter 1 of constructor in
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
required a bean of type
'org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath'
that could not be found.
The following candidates were found but could not be injected:
- Bean method 'dispatcherServletRegistration' in 'DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration'
not loaded because DispatcherServlet Registration found non dispatcher
servlet dispatcherServlet
Action:
Consider revisiting the entries above or defining a bean of type
'org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath'
in your configuration.
My configuration:
#Configuration
public class CXFConfig {
#Bean
public ServletRegistrationBean dispatcherServlet() {
final ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new CXFCdiServlet(), "/services/*");
servletRegistrationBean.setLoadOnStartup(1);
return servletRegistrationBean;
}
#Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
SpringBus springBus = new SpringBus();
springBus.getInInterceptors().add(new AppInboundInterceptor());
springBus.getOutInterceptors().add(new AppOutboundInterceptor());
return springBus;
}
}
Please confirm how to do the configuration?
dispatcherServlet() method doesn't work in Springboot 2.1.1
I solved this problem by change the method name from dispatcherServlet to disServlet.
Maybe you can try.

Java EE - dependency injection into batchlet

I am having issues with dependency injection in a batchlet.
#Named
public class SimpleBatchlet extends AbstractBatchlet {
#Inject
protected StorageService storageService;
...
public String process() throws Exception {
storageService.doSomething(); // this throws a null pointer exception
}
}
#Named
public class LocalFileStorageService implements StorageService {
public void doSomething() {
}
}
I have tried putting beans.xml in both META-INF and WEB-INF and removing it, all to no avail. I also tried changing the scopes of the beans to singletons, etc. I am invoking / starting the batch job through the use of an #Schedule annotation on a method that uses BatchRuntime to start the job.
I must be missing something simple as I know this should work. The actual scope of the beans I will use may need to vary, but the point I am trying to make is that I don't believe bean scope is a problem, but some other configuration issue.
I should also note that I only have 1 implementation of StorageService.
Not clear what really is your problem (NPE on injected CDI bean?), but annotating your Batchlet #Dependent should solve the problem :
#Named
#Dependent
public class SimpleBatchlet extends AbstractBatchlet {
#Inject
protected StorageService storageService;
}
Batchlet need to be #Named and #Dependent for integration with CDI.

Spring boot JNDI datasource lookup failure - Name comp/env/jdbc not found in context "java:"

I have setup a spring boot (v 1.1.9) application to deploy as a WAR file. And I'm trying to integrate this web application with an existing data service module (added as a maven dependency).
Environment trying to deploy: WebSphere Application Server 8.5.5.4
The issue I'm facing is an application start-up failure when try to look-up a JNDI dataSource (jdbc/fileUploadDS) as below within the dependent data service module.
#Configuration
#Profile("prod")
public class JndiDataConfig implements DataConfig {
#Bean
public DataSource dataSource() throws NamingException {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/fileUploadDS");
}
}
My Spring Boot configuration:
#Configuration
#ComponentScan(basePackages = { "au.com.aiaa.fileupload.data.*", "demo" })
#EnableAutoConfiguration(exclude = { HibernateJpaAutoConfiguration.class, DataSourceAutoConfiguration.class })
public class SampleApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(applicationClass, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<SampleApplication> applicationClass = SampleApplication.class;
#Bean
public static Properties fileUploadJndiProperties() throws NamingException {
JndiObjectFactoryBean jndiFactoryBean = new JndiObjectFactoryBean();
jndiFactoryBean.setJndiName("props/FileUploadProperties");
jndiFactoryBean.setExpectedType(Properties.class);
jndiFactoryBean.setLookupOnStartup(true);
jndiFactoryBean.afterPropertiesSet();
return (Properties) jndiFactoryBean.getObject();
}
}
Note that I'm able to lookup props/FileUploadProperties successfully. But failing to do the same for a datasource.
My doubt is it is trying to load a EmbeddedWebApplicationContext which is not what I want.
The stack trace is:
Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig.dataSource() throws javax.naming.NamingException] threw exception; nested exception is **javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".**
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at **org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)**
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:142)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:89)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:51)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
..................
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig.dataSource() throws javax.naming.NamingException] threw exception; nested exception is **javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".**
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586)
... 132 common frames omitted
Caused by: javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".
at com.ibm.ws.naming.ipbase.NameSpace.getParentCtxInternal(NameSpace.java:1970)
at com.ibm.ws.naming.ipbase.NameSpace.retrieveBinding(NameSpace.java:1377)
at com.ibm.ws.naming.ipbase.NameSpace.lookupInternal(NameSpace.java:1220)
at com.ibm.ws.naming.ipbase.NameSpace.lookup(NameSpace.java:1142)
at com.ibm.ws.naming.urlbase.UrlContextImpl.lookupExt(UrlContextImpl.java:1436)
at com.ibm.ws.naming.java.javaURLContextImpl.lookupExt(javaURLContextImpl.java:477)
at com.ibm.ws.naming.java.javaURLContextRoot.lookupExt(javaURLContextRoot.java:485)
at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:370)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
at javax.naming.InitialContext.lookup(InitialContext.java:436)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig.dataSource(JndiDataConfig.java:41)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig$$EnhancerBySpringCGLIB$$8001dbbe.CGLIB$dataSource$0(<generated>)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig$$EnhancerBySpringCGLIB$$8001dbbe$$FastClassBySpringCGLIB$$3c9e0518.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
at au.com.aiaa.fileupload.data.dao.configuration.JndiDataConfig$$EnhancerBySpringCGLIB$$8001dbbe.dataSource(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
What am I missing here? Even when I try to explicitly define the dataSource bean method in SampleApplication.java like below it fails with the same error.
#Bean
public static DataSource dataSource() throws NamingException {
JndiObjectFactoryBean jndiFactoryBean = new JndiObjectFactoryBean();
jndiFactoryBean.setJndiName("java:comp/env/jdbc/fileUploadDS");
jndiFactoryBean.setExpectedType(DataSource.class);
jndiFactoryBean.setLookupOnStartup(true);
jndiFactoryBean.setResourceRef(true);
jndiFactoryBean.afterPropertiesSet();
return (DataSource) jndiFactoryBean.getObject();
}
I referred this and it says we need to set enableNaming() on servlet container? Can I do something similar for non-embedded web application context? Or is it purely a WAS 8.5 issue??
You need to have resource reference with jdbc/fileUploadDS name in your web.xml. And make sure it is bound to actual datasource name during installation or via ibm-web-bnd.xml file.
Definition in web.xml:
<resource-ref>
<description />
<res-ref-name>jdbc/fileUploadDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
If you dont want to use web.xml, then in normal Java EE app you could just add in web component (servlet, filter) the following class annotation:
#Resource(name="jdbc/fileUploadDS", type=javax.sql.DataSource.class, lookup="jdbc/fileUploadDS")
but I'm not Spring-boot expert, so don't know, if it will work or is possible there.
I am able to connect my Spring-Boot application (deployed in Websphere Application Server 9) to WAS datasource.
The following code worked for me, for connecting to DataSource:
#Bean(name = "WASDataSource")
public DataSource WASDataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource("DSNAME");
}
#Bean(name = "WASDataSourceJdbcTemplate")
public JdbcTemplate jdbcTemplate_WASDS(#Qualifier("WASDataSource")
DataSource dsDB2) {
return new JdbcTemplate(dsDB2);
}
Note: The name of Datasource "DSNAME" is the name which appears on the UI of Websphere console.
You can see that via -> Select Resources > JDBC > Data Sources.
Then I created jdbc template:
#Autowired
#Qualifier("WASDataSourceJdbcTemplate")
private JdbcTemplate db2WASTemplate;`
And running query using the query method works fine :
db2WASTemplate.query()
I did not create any Web.xml or ibm-web-bnd.xml files
I just configured spring boot with my custom datasource as follows:
#Bean
#ConfigurationProperties("spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
and inside the application.properties file I defined all datasource settings as usual
spring.datasource.driver-class-name= ***
spring.datasource.url= ***
spring.datasource.username= ***
spring.datasource.password= ***
spring.datasource.jndi-name=jdbc/myDB
It works nicely with #SpringBootApplication with all other default settings
I am facing the same problem. I don't know how to define tag in spring boot since there is no web.xml file in the spring boot.
So far what I came to know that we have to define it in the application file from where we start our spring application. I think we need to use this method to set the Datasource:
#Bean(destroyMethod="")
#ConfigurationProperties(prefix="datasource.mine")
public DataSource dataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource("java:jdbc/configurationFile");
}

Remote interface lookup-problem in Glassfish3

I have deployed a war-file, with actionclasses and a facade, and a jar-file with ejb-components (a stateless bean, a couple of entities and a persistence.xml) on glassfish3. My problem is that i cant find my remote interface to the stateless bean from my facade.
My bean and interface looks like:
#Remote
public interface RecordService {...
#Stateless(name="RecordServiceBean", mappedName="ejb/RecordServiceJNDI")
public class RecordServiceImpl implements RecordService {
#PersistenceContext(unitName="record_persistence_ctx")
private EntityManager em;...
and if i look in the server.log the portable jndi looks like:
Portable JNDI names for EJB RecordServiceBean : [java:global/recordEjb/RecordServiceBean, java:global/recordEjb/RecordServiceBean!domain.service.RecordService]|#]
and my facade:
...InitialContext ctx= new InitialContext();
try{
recordService = (RecordService) ctx.lookup("java:global/recordEjb/RecordServiceBean!domain.service.RecordService");
}
catch(Throwable t){
System.out.println("ooops");
try{
recordService = (RecordService)ctx.lookup("java:global/recordEjb/RecordServiceImpl");
}
catch(Throwable t2){
System.out.println("noooo!");
}...
}
and when the facade makes the first call this exception occur:
javax.naming.NamingException: Lookup failed for 'java:global/recordEjb/RecordServiceBean!domain.service.RecordService' in SerialContext [Root exception is javax.naming.NamingException: ejb ref resolution error for remote business interfacedomain.service.RecordService [Root exception is java.lang.ClassNotFoundException: domain.service.RecordService]]
and the second call:
javax.naming.NamingException: Lookup failed for 'java:global/recordEjb/RecordServiceBean' in SerialContext [Root exception is javax.naming.NamingException: ejb ref resolution error for remote business interfacedomain.service.RecordService [Root exception is java.lang.ClassNotFoundException: domain.service.RecordService]]
I have also tested to inject the bean with the #EJB-annotation:
#EJB(name="RecordServiceBean")
private RecordService recordService;
But that doesnt work either. What have i missed? I tried with an ejb-jar.xml but that shouldnt be nessesary. Is there anyone who can tell me how to fix this problem?
I found a sollution to this problem. If i pack the interfacefile in a jarfile and drop that jar in to WEB-INF/lib in the warfile the problem is solved.
When server gets started, the global jndi names of the interfaces are displayed in console.
Use those to lookup interfaces instead of trying to call them by giving names explicitly.
Have you tried commenting out all the ejb related sections of your xml files and then using just
#Stateless
public class RecordServiceImpl implements RecordService {
and then
#EJB
private RecordService recordService;
They've tried to make the process fairly brain dead in EJB 3.1
Also, while JNDI browsing didn't make it into gf 3.0 you can dig up some info with
asadmin list-jndi-entries --context java:global/yourAppName