Lazy init not honored for JmsTemplate - spring

We are developing a Spring-based application that utilizes JMSTemplate to send/receive JMS messages to/from the Tibco EMS Server.
With the current implementation, during the TomCat start up the project fails if the EMS Server is down. This is because in the Spring config file, we have JMS related beans that are trying to connect to the EMS server.
So, one solution is to make all JMS related beans initiate only when they are required (and not during the start up). For that we set all the JMS related beans' lazy-init attribute to true.
An excerpt:
<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager" lazy-init="true">
<property name="internalJmsQueueConnectionFactory"> <ref bean="jmsQueueConnectionFactory" />
</property>
</bean>
<bean id="jmsTemplateWithClientAcknowledge" class="org.springframework.jms.core.JmsTemplate" lazy-init="true">
<property name="internalJmsQueueConnectionFactory" ref="jmsQueueConnectionFactory"/>
</bean>
Here's the problem: if we set lazy-init="true" ONLY on jmsTransactionManager bean, the project loads fine without problems. However, as soon as we set lazy-init="true" on the jmsTemplateWithClientAcknowledge bean as well, the project fails. Same failure reason: couldn't connect to the EMS Server.
The error from the log:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsMsgSenderImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jms.core.JmsTemplate com.cv.pub.engine.service.impl.JmsMsgSenderImpl.jmsTemplate; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsTemplateWithClientAcknowledge' defined in ServletContext resource [/WEB-INF/spring/jms-context.xml]: Cannot resolve reference to bean 'internalJmsQueueConnectionFactory' while setting bean property 'connectionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'internalJmsQueueConnectionFactory' defined in ServletContext resource [/WEB-INF/spring/jms-context.xml]: Cannot resolve reference to bean 'targetJmsQueueConnectionFactory' while setting bean property 'targetConnectionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'targetJmsQueueConnectionFactory' defined in ServletContext resource [/WEB-INF/spring/jms-context.xml]: Invocation of init method failed; nested exception is javax.naming.ServiceUnavailableException: Failed to query JNDI: Failed to connect to the server at tcp://localhost:7222 [Root exception is javax.jms.JMSException: Failed to connect to the server at tcp://localhost:7222]
I will greatly appreciate your thoughts and help!

Is targetJmsQueueConnectionFactory being used by internalJmsQueueConnectionFactory? According to the log it appears to be like that. You will need to make internalJmsQueueConnectionFactory also lazy-init.

Related

Spring Boot application cannot join Coherence cluster on server: Join request was aborted

I have developed a small REST API application with Spring Boot after another sample application with classic Spring XML configuration. It imports context from a library with a Coherence cache set up.
When I developed it locally, running the Spring Boot app with Intellij Idea runner, there were no issues, the application worked fine and the endpoint worked connecting to that cache.
When I deployed the application to the Unix server, I am getting the following error during the application startup:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'coreSearchSync' defined in class path resource [core-search-core-context.xml]: Cannot resolve reference to bean 'corePersistenceManager' while setting bean property 'corePersistenceManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'corePersistenceManager': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ' coreSearchResultCache' defined in class path resource [core-search-coherence-context.xml]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.tangosol.net.NamedCache]: Factory method 'getCache' threw exception; nested exception is (Wrapped: Failed to start Service "Management" (ServiceState=SERVICE_STOPPED)) java.lang.RuntimeException: Join request was aborted
The application on the server is using the application.properties but they are the same as in the application.yaml locally.
I am not sure where to continue the investigation...
The problem was solved by passing JVM arguments to the script to start the application:
-Dtangosol.coherence.clusterport=<port> -Dtangosol.coherence.site=<site> -Dtangosol.coherence.clusteraddress=<cluster_ip_ddress> -Dtangosol.coherence.cluster=<cluster_name>
It appears that these properties are not applied from the application properties because starting the coherence cluster works on the system level and/or starts before the properties are initialized. Or those properties are not visible to the coherence.

Issue with spring cloud task mutiple datasources

I configured two data sources in my app following the guide of spring example:https://github.com/spring-cloud/spring-cloud-task/blob/master/spring-cloud-task-samples/multiple-datasources.
The spring boot version I use is :2.0.0.RELEASE
The spring.cloud.task.version I use is :1.2.2.RELEASE.
This application works fine in my local computer, But when deploy to the to AWS, I got the following error with the defination of class:CustomTaskConfigurer.java.
which defined the same as here:https://github.com/spring-cloud/spring-cloud-task/blob/master/spring-cloud-task-samples/multiple-datasources/src/main/java/io/spring/configuration/CustomTaskConfigurer.java
The error message is like below:
exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cloud.task.configuration.SimpleTaskConfiguration': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customTaskConfigurer' defined in file [/home/vcap/app/BOOT-INF/classes/com/xxx/configuration/CustomTaskConfigurer.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.xxx.configuration.CustomTaskConfigurer$$EnhancerBySpringCGLIB$$bc80cd46]: Constructor threw exception; nested exception is java.lang.IllegalStateException: Unable to create a TaskExecutionDao.
The root cause for this error is that when I developed the application locally I configure a local datasource bean for postgresql like below:
#Bean
#Primary
#ConfigurationProperties("spring.datasource")
public HikariDataSource sourceDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
This bean read the properties in the application.properties file which identify the username and password url for the local postgres.
When This application deloyed to cloud,It will connect to the cloud data base instead of the local databases, which means the url,username,and password are no longer correct.
After add the configuration for cloud, this error disppeared.
But this exception stack trace only tell you that it is unable to create taskExecutionDao, It is really hard for the user to fix the issue when see such a error message
If it is a multiple datasource issue, you can try marking it as #Primary. Providing a better stack trace is helpful.

Spring Boot + HikariCP - non-deterministic failure to auto-configure a DataSource

On my local machine, when I run one of my Spring Boot 2.0.0 applications from IntelliJ, the application periodically fails to start and the following message is displayed in the console:
Application Failed to Start
Description:
Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified and no embedded datasource could be auto-configured.
Reason: Failed to determine a suitable drive class
When I get this error, if I try to run the application again it will (sometimes) start. The behavior seems non-deterministic. Sometimes the application starts on the first try, sometimes it takes a few consecutive attempts.
Edit ----------------------------------------------------------------------------
The error appears to be caused by the application failing to determine what profile is active. When the application fails to start, the Spring logging output states "No active profile set, falling back to default profiles: default". When the application starts successfully, the logging output states "The following profiles are active: local,permitall", which are the profiles I set to active in application.properties.
Unfortunately, whether or not Spring determines what profile is active when starting is a roll of the dice for me.
----------------------------------------------------------------------------------
My application is configured to use spring-boot-starter-data-jpa and connect to a Postgres database. For connection pooling I use HikariCP 2.7.8.
The console error (see below) implies that Hikari is failing to load a data source. Since this error is non-deterministic, maybe it depends on the order that Spring creates beans during startup?
The spring.datasource.url property is defined in my local application properties file. The application properties file sets the spring active profile property to local.
This is my application.properties file
spring.profiles.active=local,permitall
management.endpoints.web.base-path=/
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
This is my application-local.properties
spring.datasource.url=jdbc:postgresql://localhost/vms?currentSchema=vms
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
I haven't found a pattern to the failures or the successes. Any ideas on solving or troubleshooting this problem are appreciated.
Console error message
2018-05-18 13:53:49.667 ERROR 16228 --- [ost-startStop-1] o.s.b.web.embedded.tomcat.TomcatStarter : Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'servletEndpointRegistrar' defined in class path resource
[org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.class]: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar]: Factory method 'servletEndpointRegistrar' threw exception;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'healthEndpoint' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.health.HealthEndpoint]: Factory method 'healthEndpoint' threw exception;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthIndicatorAutoConfiguration': Bean instantiation via constructor failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthIndicatorAutoConfiguration$$EnhancerBySpringCGLIB$$61a24aeb]: Constructor threw exception;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception;
nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class

Autowiring fails IllegalArgument un-safe operation exception

I am getting the following exception after upgrading my Spring jars.
org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.transformer.HeaderEnricher#4': Cannot create inner bean '(inner bean)' of type [org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor] while setting constructor argument with key [#{partnerHeaderKey}]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#19': Injection of resource dependencies failed; nested exception is java.lang.IllegalArgumentException: Can not set com.follett.fheg.coursemateriallookup.coursematerial.data.dao.PartnerDAO field com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher.partnerDAO to org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor
at org.springframework.beans.factory.support.BeanDefinitionValue Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#19': Injection of resource dependencies failed; nested exception is java.lang.IllegalArgumentException: Can not set com.follett.fheg.coursemateriallookup.coursematerial.data.dao.PartnerDAO field com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher.partnerDAO to org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:271)
... 40 more
Caused by: java.lang.IllegalArgumentException: Can not set com.follett.fheg.coursemateriallookup.coursematerial.data.dao.PartnerDAO field com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher.partnerDAO to org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:57)
at java.lang.reflect.Field.set(Field.java:657)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
... 44 more
From what I have read I needed to add #Component annotation to my bean and/or create the in my application context - neither of these approaches have worked. The DAO it is referring to is declared like so <bean id="partnerDAO" class="com.follett.fheg.coursemateriallookup.coursematerial.data.dao.impl.PartnerDAOImpl"/>. If I remove the #Component annotation I get a red line under #Autowired and a message that says "Autowired members must be defined in the valid spring bean (#Component/#Service etc..)", but after doing that i still get the errors.
I am using Spring integration so the bean to auto-wire is defined there.
<integration:header-enricher>
<integration:header name="#{partnerHeaderKey}" method="getPartner">
<bean class="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher"/>
</integration:header>
</integration:header-enricher>
Any thoughts or help is appreciated! Thank you.
Note: the application runs fine if I drop back down to Spring 2.1.4.RELEASE even without declaring the #Component or <bean> in the application context.
UPDATE
As blackpanther mentions below I need a element in the application context. I failed to mention that I DO Have this <context:component-scan base-package="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher" /> There is another for the DAO's as well <context:component-scan base-package="com.follett.fheg.coursemateriallookup.coursematerial.data.dao" />
Not exactly, just putting the annotation #Component does not mean that that Java class will have it's properties autowired. In order to use the #Component annotation effectively, you must tell Spring where to look for these classes. This is done by the <context:component-scan base-package="package.name" /> tag in your Spring configuration.
I would have a look at this article as it may help you.
You can specify #Qualifier on top of the bean declaration inside the component like below.
#Autowired
#Qualifier("loginService")
private ILoginService loginService;
loginService is the name of the bean in the .xml context file.
I was able to resolve this issue by using #Component annotation as well as modifying the way the beans were created in the context.
For some reason when I moved the <bean class=""> out of the <integration:header> and added a ref-"" attribute it started working just fine. I am getting a different error, but I was able to get the application running.
old way
<integration:header-enricher>
<integration:header name="#{partnerHeaderKey}" method="getPartner">
<bean class="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.Partner HeaderEnricher"/>
</integration:header>
</integration:header-enricher>
new way
<integration:header-enricher>
<integration:header name="#{partnerHeaderKey}" method="getPartner" ref="myBean">
</integration:header>
</integration:header-enricher>
</integration:chain>
<bean id="myBean" class="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher"/>

Separate Hibernate library for multiple web applications

I want to have two web applications that use Hibernate, Spring, and JSF 2.0. One would be the website which is available to the public and the other a content management system available on the company intranet.
I don't want to have duplicate code that accesses the database. I want to create a JAR file that contains all the database manipulation using hibernate.
I can't find any examples on the we of how this is done.
Does anyone have any helpful tips? I've managed to create the hibernate JAR file and put a test main in it and that can retrieve the data from the database. I think my main problem is how do I go about configuring all this in the web application?
thanks
After playing around with things a bit. I'm almost there
I'm getting this error when deploying to glassfish now
Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BrandService' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Cannot resolve reference to bean 'BrandDao' while setting bean property 'brandDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BrandDao' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Cannot resolve reference to bean 'SessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'SessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Cannot resolve reference to bean 'DataSource' while setting bean property 'dataSource'; nested .... msg.seeServerLog
I think there is not difference between JAR was used by java console application(your test main) and JAR was used by java web application .

Resources