Runtime Error in SprinBoot project : unable to find SqlSessionFactory - spring-boot

I have a simple SpringBoot project in IntelliJ that I generated at http://start.spring.io. I added a dependency from the local repository and it was successfully imported. This library depends on the different local library.
I am able to Build my project successfully, however when I am trying to Run it I am getting runtime error. I added new dependency to my project that contains the class which was not found during the startup but it didn't resolve my issue and I am still having problems on the startup.
Here is the original dependency I added to my project :
<dependency>
<groupId>connect_mgr</groupId>
<artifactId>connect-mgr</artifactId>
<version>1</version>
Inside this "connect_mgr" project there is a dependency on the different library :
<dependency>
<groupId>services_core</groupId>
<artifactId>services-core</artifactId>
<version>1</version>
</dependency>
There is also an implementation in the "services_core" project :
#Bean
#DependsOn("sqlSessionFactory")
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
In my Project I also added a dependency to IBatis-Core that contains "SqlSessionFactory" class.
And still, on the startup of my project I am getting this error :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [com/config/MyBatisMapperConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is java.io.FileNotFoundException: class path resource [null] cannot be opened because it does not exist
Main class in my projec resides in "services_core" project.

Related

Spring Migration to 5.3.19 from 4.3.29 issue with .binding files

I have started my migration of spring version from 4.3.29.RELEASE to 5.3.29 I have fixed some of the issues with servlet and AbstractClientHttpRequest files but I was facing some issue with .binding files, I see they were loading as part of application context after migrating the spring version to 5.3.19 , with the older version of Spring 4.3.29.RELEASE I was able to bring up my application with out any issues. Now with 5.3.19 when I start my application I am getting below issue.
03-May-2022 10:11:00.537 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [org.springframework.web.context.ContextLoaderListener]
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'TestMgmtDAO': Unsatisfied dependency expressed through field 'editorService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'editorService': Unsatisfied dependency expressed through field 'trentonMessagePublisher'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'trentonMessagePublisher' defined in class path resource [config/queue-config.xml]: Cannot resolve reference to bean 'jmsTemplate' while setting bean property 'jmsTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsTemplate' defined in class path resource [config/queue-config.xml]: Cannot resolve reference to bean 'connectionFactory' while setting bean property 'connectionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connectionFactory' defined in class path resource [config/queue-config.xml]: Cannot resolve reference to bean 'testConnectionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testConnectionFactory' defined in class path resource [config/queue-config.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [TEST_QMGR_QCF] is not bound in this Context. Unable to find [TEST_QMGR_QCF].
Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testConnectionFactory' defined in class path resource [config/queue-config.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [TEST_QMGR_QCF] is not bound in this Context. Unable to find [TEST_QMGR_QCF].
Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myTestQueue' defined in class path resource [config/queue-config.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [Q_OUTBOUND_TEST.CHECK_TO_QUEUETON] is not bound in this Context. Unable to find [Q_OUTBOUND_TEST.CHECK_TO_QUEUETON].
My Sample .binding file is below , I am using IBM MQ.
TEST_QMGR_QCF/RefAddr/1/Type=XXX
TEST_QMGR_QCF/RefAddr/2/Content=XXXX
TEST_QMGR_QCF/RefAddr/3/Content=TEST.TEST.TLS
TEST_QMGR_QCF/RefAddr/4/Content=true
TEST_QMGR_QCF/RefAddr/5/Content=0
TEST_QMGR_QCF/RefAddr/9/Type=TCM
TEST_QMGR_QCF/RefAddr/91/Type=TM
Version of the the IBM Mq jar files used are.
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-amqp</artifactId>
<version>1.7.10.RELEASE</version>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.2.2.0</version>
</dependency>
I have com.sun.jndi.fscontext.RefFSContextFactory entry to to load my .binding files in my beans.xml like below.
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">com.sun.jndi.fscontext.RefFSContextFactory</prop>
<prop key="java.naming.provider.url">file:///C:/Local</prop>
</props>
</property>
</bean>
<bean id="umConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate" />
<property name="jndiName" value="TEST_QMGR_QCF"/>
</bean>
This is where I see with older version of Spring I was able to load the .bindings but with upgrade unable to load.
The best that I can do is to try to point you in the right direction. The .bindings file uses the com.sun.jndi.fscontext.RefFSContextFactory to provide a JNDI like lookup that is initialized from your .bindings file.
You can find some references here IBM and Sun.
Note that the jar files fscontext.jar and providerutil.jar are provided with the IBM MQ distribution in the /opt/mqm/java/lib directory. These are the Sun jars needed for the file system context. These files are not, however, provided by the com.ibm.mq.allclient maven artifact.
These jars must have been provided in your older version. You can find them in Maven Central:
<groupId>com.sun.messaging.mq</groupId>
<artifactId>fscontext</artifactId>
<packaging>jar</packaging>
<version>4.6-b01</version>
Note that the two jars seem to have been merged into the one jar in this artifact. Ensure that these Sun classes are in your current project.
Then, you'll need to find where you are doing something like (from the Sun link):
// Create the environment for constructing the initial JNDI
// naming context.
Hashtable env = new Hashtable();
// Store the environment attributes that tell JNDI which initial context
// factory to use and where to find the provider.//
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file:///C:/imq_admin_objects");
// Create the initial context.
Context ctx = new InitialContext(env);
// Look up the connection factory object in the JNDI object store.
String CF_LOOKUP_NAME = "MyConnectionFactory";
ConnectionFactory myFactory = (ConnectionFactory) ctx.lookup
(CF_LOOKUP_NAME);
in your code. Note that the .bindings file name is expected, and that the location specified is a directory where the .bindings file is located.

setting up path for a library jar for different environments to make compatible with CI-CD

I've a jar library that needs to be read as an argument to my class MyProject and a respective app property in application.properties my.customJar=/WEB-INF/lib/myJar.jar to use the jar in my local app run and it works well locally but it fail on the pcf cloud. I did some changes & respective to this property, I've tried adding an override in cloud environment application-dev.properties i.e. my.customJar=${project.basedir}/src/main/webapp/WEB-INF/lib/myJar.jar
I've also tried with relative path my.customJar=./src/main/webapp/WEB-INF/lib/myJar.jar but neither of them appear to have worked.
The problem arises specifically when I send this code to the pcf cloud I am getting FileNotFoundException. And it fails there with error mentioned below. Can anyone please guide me with how can I set the path for the other profiles. Also, please let me know if there is any more convenient way to do this as well?
Note: I am using multiple spring profiles.
Error I am getting
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myController' defined in file [/home/abc/app/BOOT-INF/classes/com/example/myController.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jarUserBean' defined in class path resource [com/example/configuration/CommonConfigs.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.myJar.api.MyProject]: Factory method 'jarUserBean' threw exception; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/lib/myJar.jar]
2021-08-27T07:53:53.647+01:00 [APP/PROC/WEB/0] [OUT]
Here, the jarUserBean is a bean created using the jar's insputStream i.e.
#Value("${my.customJar}")
private String pathToJar;
#Bean
#ConditionalOnProperty(prefix = "my", name = "customJar")
public MyProject jarUserBean() throws IOException, ProjectInvalidException, InterruptedException {
Resource resource = loader.getResource(pathToJar);
InputStream is = resource.getInputStream();
return new MyProject(is);
}
Adding this plugin in the pom helped me reading it from the classpath itself.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>jar</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>

Omitting Spring Data JPA autowiring during tests

I have a Spring Boot application that uses a library (my own), that has Spring Data JPA dependencies.
Within the library, I'm using JPA repository interfaces and a custom repository fragment that uses a JpaSpecificationExecutor interface.
I have a configuration inside the library to #EnableJpaRepositories, as below:
#EnableJpaRepositories(basePackages = "my.package.domain.jpa.repo", bootstrapMode= BootstrapMode.LAZY)
#EntityScan(basePackageClasses = {LookupConfig.class, LookupMapping.class})
#Configuration
public class LookupJpaConfiguration {}
I have also declared (not generated) the meta-models (with _ appended to the class name) for the entity classes in the same package as the entity classes.
The main application is also a #SpringBootApplication, with spring-boot-starter-parent:2.1.0 as parent. This application uses the library as a dependency, and #Autowire a class from the Library. The application itself does not have direct dependencies on Spring Data.
The problem is, I am unable to run Unit tests without adding properties for the datasource.
This is what the test class's declaration looks like:
#ExtendWith({SpringExtension.class, MockitoExtension.class})
public class OrderStatusProcessorTest {
// Uses the library with JPA dependency
#MockBean private LookupService lookupService;
// The class being tested; uses LookupService
private final OrderStatusProcessor orderStatusProcessor;
public OrderStatusProcessorTest() {
orderStatusProcessor = new OrderStatusProcessor(lookupService);
}
...
I have already tried #Mocking DataSource and EntityManagerFactory, but none of those worked either.
Library's pom file
<properties>
<spring-data-releasetrain.version>Lovelace-SR5</spring-data-releasetrain.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
With the current setup, the error I'm seeing is as below --
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
...
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactory' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactoryBuilder' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactoryBuilder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.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
It does work if I provide the datasource properties correctly. But what I want is for the Tests to run without actually connecting to the database.
Let me know if I need to provide more information. Thanks in advance!

Problem running project from s4sdk archtypes with artifact id: scp-cf-spring

I'm getting issues in running hello world project when I created it from below command:
mvn archetype:generate -DarchetypeGroupId=com.sap.cloud.s4hana.archetypes -DarchetypeArtifactId=scp-cf-spring -DarchetypeVersion=LATEST
The project gets created fine but when I'm running the application I get an error in creating beans, the error looks something like this:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name
'com.sap.cloud.sdk.cloudplatform.cache.CacheMonitor': Cannot create
inner bean '(inner bean)#630d4350' of type
[com.sap.cloud.sdk.cloudplatform.cache.CacheMonitor] while setting
bean property 'listener'; nested exception is
org.springframework.beans.factory.CannotLoadBeanClassException: Error
loading class [com.sap.cloud.sdk.cloudplatform.cache.CacheMonitor] for
bean with name '(inner bean)#630d4350' defined in URL
[jar:file:/Users/setup/.m2/repository/com/sap/cloud/s4hana/cloudplatform/caching/2.4.2-SNAPSHOT/caching-2.4.2-SNAPSHOT.jar!/com/sap/cloud/sdk/cloudplatform/cache/CacheMonitor.class]:
problem with class file or dependent class; nested exception is
java.lang.NoClassDefFoundError:
com/sap/cloud/sdk/cloudplatform/monitoring/JmxMonitor . . .
Caused by:
org.springframework.beans.factory.CannotLoadBeanClassException: Error
loading class [com.sap.cloud.sdk.cloudplatform.cache.CacheMonitor] for
bean with name '(inner bean)#630d4350' defined in URL
[jar:file:/Users/setup/.m2/repository/com/sap/cloud/s4hana/cloudplatform/caching/2.4.2-SNAPSHOT/caching-2.4.2-SNAPSHOT.jar!/com/sap/cloud/sdk/cloudplatform/cache/CacheMonitor.class]:
problem with class file or dependent class; nested exception is
java.lang.NoClassDefFoundError:
com/sap/cloud/sdk/cloudplatform/monitoring/JmxMonitor . . .
Caused by: java.lang.ClassNotFoundException:
com.sap.cloud.sdk.cloudplatform.monitoring.JmxMonitor
Please let me know if I should furnish more details.
The fix is: I generated project with version: 2.3.1, it is working fine now.:
mvn archetype:generate -DarchetypeGroupId=com.sap.cloud.s4hana.archetypes -DarchetypeArtifactId=scp-cf-spring -DarchetypeVersion=2.3.1

Spring boot oracle driver at runtime

I have a spring boot app that I am trying to add an oracle connection to. I have already added an #Entity class and Repository.
I have added the oracle ojdbc8.jar to my local maven repo and have this in gradle
dependencies {
...
compile group: 'com.oracle', name: 'ojdbc8', version:'12.2.0'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.3.RELEASE'
...
}
my application.properties contains
spring.datasource.url="jdbc:oracle:thin:#//hostname.whatever:1521/blah"
spring.datasource.username="username"
spring.datasource.password="password"
spring.datasource.driver-class-name="oracle.jdbc.OracleDriver"
This all compiles fine. But when I deploy (under tomcat) I get
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': 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/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: "oracle.jdbc.OracleDriver"
Looks like it's having trouble finding the driver. Is there something else I need to do to make it know where to find it? Or to build it as part of the archive?
I also built a similar test app and pointed it at a local mysql just to make sure I wasn't crazy and that works fine... Not sure what's so special about oracle.

Resources