JNDI #Resource in Spring - java

I have a Java EE application with WildFly, and I use:
#Resource(lookup = "java:/jms/queue/MyQueue")
but now I am migrating part of this application to Spring one, and I have no idea how to look up for my JNDI resource.
In application.yaml I added:
spring:
datasource:
jndi-name: "java:jms/queue/MyQueue"
but it throws an error during startup:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myRoute': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'java:/jms/queue/MyQueue' defined in JNDI environment: JNDI lookup failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or in an application resource file: java.naming.factory.initial
MyRoute.java:
#Resource(lookup = "java:/jms/queue/MyQueue")
private Queue queue1;
Is it possible to easily inject the resource in Spring?
I wish it can work like #Autowired does. Inject the Queue with lookup into JNDI.

Related

Spring Boot & ActiveMQ Artemis: NoClassDefFoundError during start of application

When trying to create a Spring Boot Java application with ActiveMQ Artemis I get the following exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'artemisConfiguration' defined in class path resource [org/springframework/boot/autoconfigure/jms/artemis/ArtemisEmbeddedServerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.activemq.artemis.core.config.Configuration]: Factory method 'artemisConfiguration' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/activemq/artemis/api/core/QueueConfiguration
From the above exception I have difficult to understand what config might be missing or is it something else? I am using Spring Boot 2.7.3.
It is implemented to the letter as described in the this guide (native and embedded).
The fundamental problem is this:
java.lang.NoClassDefFoundError: org/apache/activemq/artemis/api/core/QueueConfiguration
This means that the JVM can't find this class. This class is in the artemis-commons module. You need to put this on your application's classpath.

Failed to look up JNDI DataSource

This problem may seems redundant but I can't find a suitable solution for my specific problem.
So, I have been using basic JDBC template to make connection to the DB tables in my spring boot application. I have few more features to add and I wanted to follow JPA route. I added spring.datasource.jndi-name and spring.jpa.database-platform to the application.properties file correctly(same as once that are working in my other applications).
Although I'm able to run the current application(with both JPA and JDBC connection) locally, I'm getting following error while building it on weblogic remote server.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'jdbc.myDataSource'; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
Can anyone help me with this ?

Spring boot cannot create datasource bean from cucumber test context

When running tests in a spring boot based application, spring is unable to create the datasource bean:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
Reading this error it is clear to me, I think, that spring did not read my application.properties file located at:
src/test/resources/application.properties
For clairity, I do not want to make use of an in memory database when running my integration tests, for application specific reasons.
This file contains:
spring.datasource.url=jdbc:mysql://127.0.2.1:3306/project-test
spring.datasource.username=foo
spring.datasource.password=bar
spring.datasource.driverClassName=org.mariadb.jdbc.Driver
While when starting the application using bootRun at does read out
src/main/resources/application.properties
and does create the datasource correctly.
My tests are based on cucumber and started using the following class:
#RunWith(Cucumber.class)
public class AcceptanceTests {
}
The test context is started using the following annotations on a BaseSteps class which each class defining cucumber tests inherits from
#WebAppConfiguration
#ContextConfiguration(classes = App.class)
The spring context is started successfuly but it was unable to find my application.properties file and/or use it.
I found the solution.
I added changed the ContextConfiguration like so:
#ContextConfiguration(classes = App.class, loader = SpringApplicationContextLoader.class)
Use #SpringApplicationConfiguration instead of ContextConfiguration. This is needed for Spring-boot application tests.

Spring Boot with REST & JPA, building WAR

I am attempting to this tutorial: http://spring.io/guides/tutorials/bookmarks/
I have successfully created a Rest Controller and run it through eclipse, and I'm able to get a JSON response in the browser. I have used an Apache Derby embedded database.
What I'd like to do now is run it on my separate Tomcat instance (not embedded), with a JNDI lookup to a MySQL database.
The tutorial mentioned above does not mention JNDI, so I looked here instead, which suggested adding
spring.datasource.jndi-name=java:comp/env/jdbc/mydb
to the application.properties file.
I'm pretty sure I have Tomcat set up correctly, as I've used the JNDI lookup before in another app, but attempting to build the WAR using Maven fails:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/JndiDataSourceAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'java:comp/env/jdbc/finance'; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
....
It seems the tutorials are not complete, or have I missed something? I'm at a loss as to how to proceed.

Spring singletons is instantiated before JNDI DataSourceBinding occured

I am a newbie to Java EE, I have some issue where spring singletons which have property of a JndiObjectFactoryBean is instantiated before the JNDI itself is bound. It cause an error on deployment and make the application deployment failed.
Is there anyway to configure the priority of the initialization? Such as make the JNDI DataSourceBinding instantiated first before the spring singletons?
I am using jboss-5.1.0.GA as my application server.
Here is the snippet of the server.log:
2015-05-25 16:47:14,410 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] (main) Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#1f873f7: defining beans [daoAuthenticationProvider,authenticationManager,settingbean,authenticationFailureHandler,authenticationSuccessHandler,sessionRegistry,sessionAuthenticationStrategy,authenticationFilter,sessionManageProcessingFilter,httpSessionContextIntegrationFilter,filterChainProxy,securityContextPersistenceFilter,filterSecurityInterceptor,httpRequestAccessDecisionManager,roleVoter,cxcdataDS,datasourceByJNDI,JTATransactionManager,jdbcTXManager,jdbcTemplate,jdbcTemplateext]; root of factory hierarchy
2015-05-25 16:47:14,593 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] (main) Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#1f873f7: defining beans [daoAuthenticationProvider,authenticationManager,settingbean,authenticationFailureHandler,authenticationSuccessHandler,sessionRegistry,sessionAuthenticationStrategy,authenticationFilter,sessionManageProcessingFilter,httpSessionContextIntegrationFilter,filterChainProxy,securityContextPersistenceFilter,filterSecurityInterceptor,httpRequestAccessDecisionManager,roleVoter,cxcdataDS,datasourceByJNDI,JTATransactionManager,jdbcTXManager,jdbcTemplate,jdbcTemplateext]; root of factory hierarchy
2015-05-25 16:47:14,593 ERROR [org.springframework.web.context.ContextLoader] (main) Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'daoAuthenticationProvider' defined in ServletContext resource [/WEB-INF/classes/CXC_Security.xml]: Cannot create inner bean 'org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl#1437781' of type [org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl] while setting bean property 'userDetailsService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl#1437781' defined in ServletContext resource [/WEB-INF/classes/CXC_Security.xml]: Cannot resolve reference to bean 'cxcdataDS' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cxcdataDS' defined in ServletContext resource [/WEB-INF/classes/CXC_DataSource.xml]: Cannot resolve reference to bean 'datasourceByJNDI' while setting bean property 'targetDataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'datasourceByJNDI' defined in ServletContext resource [/WEB-INF/classes/CXC_DataSource.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: cxcdataDS not bound
...
and only after long stack trace of error the required JNDI binding is instantiated
2015-05-25 16:47:16,759 INFO [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] (main) Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=cxcdataDS' to JNDI name 'java:cxcdataDS'
I would really appreciate if somebody could help me for this.
Thanks
In the end the singletons is instantiated before JNDI is bound due to issue during deployment, for some reason the application is deployed to inside of a .sar folder belong to the JBoss. Because of that the application is loaded before the JNDI is instantiated.
After I move my application to the correct folder, it is running okay as before.

Categories