I'm developing a Spring Boot web application and want to create a MySql database if it's not already created. So I've done a dump of my current database in order to have an empty schema of it. Put it in /src/main/resources, so maven brings it to /WEB-INF/classes when building the war file. That's how my application.properties is configured (according to Spring docs, that should create the DB from the script):
# DataSource settings: set here configurations for the database connection
spring.datasource.url = jdbc:mysql://localhost:3306/working_zones
spring.datasource.username = root
spring.datasource.password = password
spring.datasource.driverClassName = com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Hibernate settings are prefixed with spring.jpa.hibernate.*
spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
And that's the error I get when I try to run the application (it complains about a non-existing DB):
2015-01-13 13:30:24.334 [main] ERROR o.s.boot.SpringApplication - Application startup failed
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/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.UncategorizedScriptException: Failed to execute database script; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'working_zones'
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:370) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1095) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:990) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) ~[spring-beans-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:975) ~[spring-context-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:752) ~[spring-context-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) ~[spring-context-4.0.8.RELEASE.jar:4.0.8.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109) ~[spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691) [spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) [spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952) [spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941) [spring-boot-1.1.9.RELEASE.jar:1.1.9.RELEASE]
So it seems that Spring tries to connect to the database even schema.sql, which contains the script to create the DB, not executed. There are some related questions in Stack Overflow about that, but still can't get it working, even if I try with spring.datasource.initialize=true...
Well, looks like you can't do that from the common JDBC connect: creating a database in mysql from java
Hence Spring Boot can't do that for you automatically.
Please, don't mix the DB creating with its creation for its content: tables, procedures, triggers etc.
UPDATE
Yes, you can do that on the application startup. You just a separate initializer, which has an order before dataSourceInitializer.
A listerner on the application startup can resolve it. Following is the code.
public class DatabaseCreationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
private AtomicBoolean received = new AtomicBoolean(false);
private ConfigurableEnvironment environment;
private Pattern JDBC_URL_PATTERN = Pattern.compile("jdbc:([a-zA-Z0-9_]+)://[0-9.:]+(?:/([a-zA-Z0-9_]+))?(\\?.*)?");
#Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
// Think about twice invoking this listener
if (!received.compareAndSet(false, true)) {
return;
}
environment = event.getEnvironment();
// ConditionalOnClass
ClassLoader classLoader = event.getSpringApplication().getClassLoader();
if (!isPresent("org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType", classLoader)) {
return;
}
// DatabaseProperties
val databaseProperties = bind(DatabaseProperties.PREFIX, new DatabaseProperties());
if (!databaseProperties.shouldCreate()) {
return;
}
// DataSourceProperties
val dataSourceProperties = bind(databaseProperties.getDatasourceConfigPrefix(), new DataSourceProperties());
// Check for connection url
String url = dataSourceProperties.getUrl();
if (url == null) return;
Matcher matcher = JDBC_URL_PATTERN.matcher(url);
if (!matcher.matches()) return;
// Extract database provider and schema name from connection url
String databaseProvider = matcher.group(1);
String schemaName = matcher.group(2);
if (isBlank(schemaName)) return;
// Reset connection url
dataSourceProperties.setUrl(url.replace("/" + schemaName, ""));
// Build a new datasource and do create schema
DataSource dataSource = buildDataSource(dataSourceProperties);
try (Connection connection = DataSourceUtils.getConnection(dataSource)) {
connection.createStatement().execute(createSchemaIfAbsent(databaseProvider, schemaName));
} catch (SQLException ignored) {
}
}
private <T> T bind(String prefix, T t) {
RelaxedDataBinder binder = new RelaxedDataBinder(t, prefix);
binder.bind(new PropertySourcesPropertyValues(environment.getPropertySources()));
return t;
}
private static DataSource buildDataSource(DataSourceProperties dataSourceProperties) {
String url = dataSourceProperties.getUrl();
String username = dataSourceProperties.getUsername();
String password = dataSourceProperties.getPassword();
return new SingleConnectionDataSource(url, username, password, false);
}
private static String createSchemaIfAbsent(String databaseProvider, String schemaName) {
DatabaseDialects dialects = DatabaseDialects.getDatabaseDialect(databaseProvider);
if (dialects == null) {
throw new IllegalArgumentException("Unknown schema:" + schemaName);
}
switch (dialects) {
case MYSQL:
return "CREATE DATABASE IF NOT EXISTS " + schemaName;
default:
throw new UnsupportedOperationException("Unsupported schema:" + dialects);
}
}
}
And Following is the DatabaseProperties.
#Data
#ConfigurationProperties(prefix = DatabaseProperties.PREFIX)
public class DatabaseProperties {
public final static String PREFIX = "spring.database";
private boolean autoCreate;
private String datasourceConfigPrefix = "spring.datasource";
public boolean shouldCreate() {
return isAutoCreate() && isNotBlank(getDatasourceConfigPrefix());
}
}
The listener should be actived by config in META-INF/spring.factories.
org.springframework.context.ApplicationListener=\
yourpackage.DatabaseCreationListener
If you want config syntax hint in an underlying IDE, add the optional depenedncy spring-boot-configuration-processor and file META-INF/additional-spring-configuration-metadata.json.
{
"groups": [
{
"sourceType": "yourpackage.DatabaseProperties",
"name": "spring.database",
"type": "yourpackage.DatabaseProperties"
}
],
"properties": [
{
"sourceType": "yourpackage.DatabaseProperties",
"defaultValue": false,
"name": "auto-create",
"type": "java.lang.Boolean"
},
{
"sourceType": "youpackage.DatabaseProperties",
"defaultValue": "spring.datasource",
"name": "datasource-config-prefix",
"type": "java.lang.String"
}
]
}
As mentioned in this github post, you can add:
spring.datasource.url=jdbc:mysql://localhost:3309/course_api_db?createDatabaseIfNotExist=true
To execute the schema.sql
Related
There is spring application deployed on websphere8.5.5.13
I try to use spring-quartz to schedule my jobs by cron, but they are start with error
My quartz configuration class
#Configuration
#Import(PersistenceConfig.class)
#PropertySource(value = {"classpath:application.properties"})
#EnableScheduling
public class ExportConfig {
private Logger logger = Logger.getLogger(getClass());
#Autowired
private DataSource dataSource;
#Autowired
private EntityManagerFactory entityManagerFactory;
#Getter
#Autowired
private MyService service;
private final String QRTZ_TRIGGER = "My_TRIGGER";
private final String QRTZ_GROUP = "My_GROUP";
private final String QRTZ_JOB = "MyJOB";
private final String TIME = "0 0-59 0-23 * * ?"; /* каждый час, каждые 0,15,30,45 минут */
#Bean
#DependsOn(value = {"entityManagerFactory", "dataSource"})
public JobDetail cronJobMy() {
JobKey jobKey = new JobKey(QRTZ_JOB, QRTZ_GROUP);
return JobBuilder
.newJob(MyJob.class)
.storeDurably(true)
.requestRecovery(true)
.withIdentity(jobKey).build();
}
#Bean
#DependsOn(value = {"entityManagerFactory", "dataSource"})
public Trigger cronTriggerMy() {
TriggerKey triggerKey = new TriggerKey(QRTZ_TRIGGER, QRTZ_GROUP);
return TriggerBuilder
.newTrigger()
.withIdentity(triggerKey)
.withSchedule(createSchedule(TIME)).build();
}
#Bean
#DependsOn(value = {"entityManagerFactory", "dataSource"})
public Scheduler cronSchedulerMy(JobDetail cronJobMy, Trigger cronTriggerMy) throws SchedulerException {
StdSchedulerFactory factory = new StdSchedulerFactory("quartzStandalone.properties");
Scheduler scheduler = factory.getScheduler();
boolean triggerExist = scheduler.checkExists(cronTriggerMy.getKey());
boolean jobExist = scheduler.checkExists(cronJobMy.getKey());
if (triggerExist || jobExist) {
scheduler.deleteJob(new JobKey(QRTZ_JOB, QRTZ_GROUP));
}
scheduler.start();
scheduler.getContext().put("SERVICE", service);
scheduler.scheduleJob(cronJobMy, cronTriggerMy);
return scheduler;
}
private static ScheduleBuilder createSchedule(String cronExpression) {
CronScheduleBuilder builder = CronScheduleBuilder.cronSchedule(cronExpression);
return builder;
}
}
Job looks like this:
#DisallowConcurrentExecution
#PersistJobDataAfterExecution
public class ExportJob implements Job {
private static final String MESSAGE = "===================================EXPORT QUARTZ TACT===================================";
private Logger logger = Logger.getLogger(getClass());
#Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
logger.log(Level.INFO, MESSAGE);
try {
ApplicationContext springContext =
WebApplicationContextUtils.getWebApplicationContext(ContextLoaderListener.getCurrentWebApplicationContext().getServletContext());
Object bean = springContext.getBean("exportService");
if (bean != null) {
ExportService exportService = (ExportService) bean;
exportService.export();
}
} catch (Exception e) {
e.printStackTrace();
logger.log(Level.ERROR, "EXPORT_SERVICE_BY_QUARTZ Failed..");
logger.log(Level.ERROR, Arrays.toString(e.getStackTrace()));
}
}
}
property-file
#============================================================================
# Configure Main Scheduler Properties
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = MYAPPStandaloneScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 1
org.quartz.threadPool.makeThreadsDaemons = true
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = MYAPP
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = false
org.quartz.jobStore.clusterCheckinInterval = 20000
org.quartz.dataSource.MYAPP.jndiURL = java:comp/env/jdbc/MYAPP
my pom.xml
<!-- Quartz for schedule -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-oracle</artifactId>
<version>1.8.5</version>
</dependency>
But, when try to start my application, there is error message
'MYAPPStandaloneScheduler' with instanceId 'NON_CLUSTERED' Scheduler
class: 'org.quartz.core.QuartzScheduler' - running locally. NOT
STARTED. Currently in standby mode. Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 1
threads. Using job-store 'org.quartz.impl.jdbcjobstore.JobStoreTX' -
which supports persistence. and is not clustered.
[11/29/19 9:05:21:513 MSK] 00000109 SystemOut O [2019-11-29
09:05:21.513] INFO org.quartz.impl.StdSchedulerFactory Quartz
scheduler 'MYAPPStandaloneScheduler' initialized from the specified
file : 'quartzStandalone.properties' from the class resource path.
[11/29/19 9:05:21:521 MSK] 00000109 SystemOut O [2019-11-29
09:05:21.521] WARN rt.AnnotationConfigWebApplicationContext Exception
encountered during context initialization - cancelling refresh
attempt: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'cronSchedulerExport' defined in class
path resource [quartz/ExportConfig.class]: Bean instantiation via
factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.quartz.Scheduler]: Factory method
'cronSchedulerExport' threw exception; nested exception is
org.quartz.impl.jdbcjobstore.NoSuchDelegateException: Couldn't create
delegate: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate [See
nested exception: pringframework.web.context.ContextLoader Context
initialization failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'cronSchedulerExport' defined in class path
resource [quartz/ExportConfig.class]: Bean instantiation via factory
method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.quartz.Scheduler]: Factory method
'cronSchedulerExport' threw exception; nested exception is
org.quartz.impl.jdbcjobstore.NoSuchDelegateException: Couldn't create
delegate: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate [See
nested exception: java.lang.InstantiationException:
org.quartz.impl.jdbcjobstore.oracle.OracleDelegate] at
org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
75) at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1892) Caused
by: org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.quartz.Scheduler]: Factory method
'cronSchedulerExport' threw exception; nested exception is
org.quartz.impl.jdbcjobstore.NoSuchDelegateException: Couldn't create
delegate: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate [See
nested exception: java.lang.InstantiationException:
org.quartz.impl.jdbcjobstore.oracle.OracleDelegate] at
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at
org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 76 more Caused by:
org.quartz.impl.jdbcjobstore.NoSuchDelegateException: Couldn't create
delegate: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate [See
nested exception: java.lang.InstantiationException:
org.quartz.impl.jdbcjobstore.oracle.OracleDelegate] at
org.quartz.impl.jdbcjobstore.JobStoreSupport.getDelegate(JobStoreSupport.java:3218)
... 77 more Caused by: java.lang.InstantiationException:
org.quartz.impl.jdbcjobstore.oracle.OracleDelegate at
java.lang.J9VMInternals.newInstanceImpl(Native Method) at
java.lang.Class.newInstance(Class.java:1762) at
org.quartz.impl.jdbcjobstore.JobStoreSupport.getDelegate(JobStoreSupport.java:3213)
... 96 more [11/29/19 9:05:21:537 MSK] 00000109 webapp E
com.ibm.ws.webcontainer.webapp.WebApp notifyServletContextCreated
SRVE0283E: Exception caught while initializing context: {0}
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'cronSchedulerExport' defined in class path
resource [quartz/ExportConfig.class]: Bean instantiation via factory
method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.quartz.Scheduler]: Factory method
'cronSchedulerExport' threw exception; nested exception is
org.quartz.impl.jdbcjobstore.NoSuchDelegateException: Couldn't create
delegate: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate [See
nested exception: java.lang.InstantiationException:
org.quartz.impl.jdbcjobstore.oracle.OracleDelegate] at
org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at
com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:813)
at
com.ibm.ws.management.AdminServiceImpl$1.run(AdminServiceImpl.java:1350)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905) at
com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1892) Caused by:
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.quartz.Scheduler]: Factory method
'cronSchedulerExport' threw exception; nested exception is
org.quartz.impl.jdbcjobstore.NoSuchDelegateException: Couldn't create
delegate: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate [See
nested exception: java.lang.InstantiationException:
org.quartz.impl.jdbcjobstore.oracle.OracleDelegate] at
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at
org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 76 more Caused by:
org.quartz.impl.jdbcjobstore.NoSuchDelegateException: Couldn't create
delegate: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate [See
nested exception: java.lang.InstantiationException:
org.quartz.impl.jdbcjobstore.oracle.OracleDelegate] at
org.quartz.impl.jdbcjobstore.JobStoreSupport.getDelegate(JobStoreSupport.java:3218)
at
org.quartz.impl.jdbcjobstore.JobStoreSupport.checkExists(JobStoreSupport.java:1988)
at
org.quartz.impl.jdbcjobstore.JobStoreSupport$23.execute(JobStoreSupport.java:1981)
at
org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3864)
at
org.quartz.impl.jdbcjobstore.JobStoreTX.executeInLock(JobStoreTX.java:93)
at
org.quartz.impl.jdbcjobstore.JobStoreSupport.executeWithoutLock(JobStoreSupport.java:3800)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.
org.quartz.impl.jdbcjobstore.NoSuchDelegateException: Couldn't create delegate:
The state of jobs is saved in _QRTZ - tables in database Oracle11g
why not using spring-quartz starter ? you can use spring datasource rather than a dedicated datasource:
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://127.0.0.1:5432/postgres
username: postgres
password: password
quartz:
scheduler-name: quartzSchedulernot work anymore
jobStore: jdbc
startup-delay: PT10S
wait-for-jobs-to-complete-on-shutdown: true
properties:
org.quartz.scheduler.instanceId: AUTO
org.quartz.scheduler.jmx.export: true
org.quartz.threadPool.threadCount: 15
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.tablePrefix: QRTZ_
org.quartz.jobStore.isClustered: true
org.quartz.jobStore.clusterCheckinInterval: 1000
you also have to remove your scheduler creation and let spring do it for you.
I know there are many examples over internet for the same problem. But what I am trying to get help is on architecture level.
I have a simple spring project where in I have one configuration class.I am trying to configure two datasources
(distDataSource, shipmentDataSource). I have two separate classes for two data sources (MyBatisDISTDataSource , MyBatisShipmentDataSource) mentioned below.
These two datasorces are working fine separately, but when I am trying to execute it together I get exception on console.
Console Exception Log
Exception in thread "main"
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'distDAOImpl': Unsatisfied dependency
expressed through field 'distMapper'; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'distMapper' defined in file
[D:\eclipse\ShippingModule\shipment-module-v2\CustEquip-CourierShipmentService-PickupSvc\target\classes\com\shipment\mapper\DistMapper.class]: Unsatisfied dependency expressed through bean property
'sqlSessionFactory'; nested exception is
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type 'org.apache.ibatis.session.SqlSessionFactory'
available: expected single matching bean but found 2:
distSqlSessionFactory,shipmentSqlSessionFactory at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at
org.springframework.context.annotation.AnnotationConfigApplicationContext.(AnnotationConfigApplicationContext.java:84)
at
com.telus.shipment.app.starter.SchedulePickup.main(SchedulePickup.java:11)
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'distMapper' defined in file
[D:\eclipse\ShippingModule\shipment-module-v2\CustEquip-CourierShipmentService-PickupSvc\target\classes\com\shipment\mapper\DistMapper.class]: Unsatisfied dependency expressed through bean property
'sqlSessionFactory'; nested exception is
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type 'org.apache.ibatis.session.SqlSessionFactory'
available: expected single matching bean but found 2:
distSqlSessionFactory,shipmentSqlSessionFactory at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1357)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1249)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at
org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 14 more Caused by:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type 'org.apache.ibatis.session.SqlSessionFactory'
available: expected single matching bean but found 2:
distSqlSessionFactory,shipmentSqlSessionFactory at
org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1342)
... 25 more
Configuration Class
#Component
#Configuration
#Profile("local")
public class EnvironmentConfigLocal implements EnvironmentConfig {
#Autowired #Qualifier("DISTDataSource") private MyBatisDISTDataSource distDataSource;
#Autowired #Qualifier("ShipmentDataSource") private MyBatisShipmentDataSource shipmentDataSource;
#PostConstruct
public void postConstruct() {
System.out.println("Selected Profile : Local");
}
#Bean
public static PropertySourcesPlaceholderConfigurer dataProperties(final Environment environment) {
final PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
final YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
final SpringProfileDocumentMatcher matcher = new SpringProfileDocumentMatcher();
matcher.addActiveProfiles(environment.getActiveProfiles());
yaml.setDocumentMatchers(matcher);
yaml.setResources(new ClassPathResource("application.yaml"));
propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());
return propertySourcesPlaceholderConfigurer;
}
#Bean
public DataSourceTransactionManager distTransactionManager() throws SQLException {
return new DataSourceTransactionManager(distDataSource);
}
#Bean
public DataSourceTransactionManager shipmentTransactionManager() throws SQLException {
return new DataSourceTransactionManager(shipmentDataSource);
}
#Bean
#Override
public SqlSessionFactory distSqlSessionFactory() throws Exception {
SqlSessionFactoryBean distSessionFactory = new SqlSessionFactoryBean();
distSessionFactory.setDataSource(distDataSource);
return distSessionFactory.getObject();
}
#Bean
#Override
public SqlSessionFactory shipmentSqlSessionFactory() throws Exception {
SqlSessionFactoryBean shipmentSessionFactory = new SqlSessionFactoryBean();
shipmentSessionFactory.setDataSource(shipmentDataSource);
return shipmentSessionFactory.getObject();
}
}
MyBatisDISTDataSource
#Component
#Qualifier("DISTDataSource")
public class MyBatisDISTDataSource extends PooledDataSource {
#Value("${dist.db.poolMaximumActiveConnections}") int poolMaximumActiveConnections;
#Value("${dist.db.poolMaximumIdleConnections}") int poolMaximumIdleConnections;
public MyBatisDISTDataSource(
#Value("${dist.db.driver-class}") String driver,
#Value("${dist.db.url}") String url,
#Value("${dist.db.user}") String username,
#Value("${dist.db.password}") String password) {
super(driver, url, username, password);
System.out.println("DIST DB Attr: \n\t"
+driver+"\n\t"
+url+"\n\t"
+username+"\n\t"
+password+"\n\t");
}
#PostConstruct
private void setDataSourceProperties() {
this.setPoolMaximumActiveConnections(poolMaximumActiveConnections);
this.setPoolMaximumIdleConnections(poolMaximumIdleConnections);
}
}
MyBatisShipmentDataSource
#Component
#Qualifier("ShipmentDataSource")
public class MyBatisShipmentDataSource extends PooledDataSource {
#Value("${shipment.db.poolMaximumActiveConnections}") int poolMaximumActiveConnections;
#Value("${shipment.db.poolMaximumIdleConnections}") int poolMaximumIdleConnections;
public MyBatisShipmentDataSource(
#Value("${shipment.db.driver-class}") String driver,
#Value("${shipment.db.url}") String url,
#Value("${shipment.db.user}") String username,
#Value("${shipment.db.password}") String password) {
super(driver, url, username, password);
System.out.println("Shipment DB Attr: \n\t"
+driver+"\n\t"
+url+"\n\t"
+username+"\n\t"
+password+"\n\t");
}
#PostConstruct
private void setDataSourceProperties() {
this.setPoolMaximumActiveConnections(poolMaximumActiveConnections);
this.setPoolMaximumIdleConnections(poolMaximumIdleConnections);
}
}
DistMapper
#Mapper
#Component
public interface DistMapper {
#Select({"select * "
+ "from CONTACT_ADDRESS CA, ADDRESS A"
+ "where CONTACTING_ID = '10001134' "
+ "and PROVINCE_CD ='ON' "
+ "and STREET_NUMBER = '15'"})
#Results({#Result(column = "CONTACTING_ID", property = "contactingId", jdbcType = JdbcType.DECIMAL)})
public List<OutletAddress> findAddressByOutletId();
}
ShipmentMapper
#Mapper
#Component
public interface ShipmentMapper {
#Select({"select C.CONTACT_ID "
+ "from SHIPMENT_EVENT_TRACKING SE, SHIPMENT S, CONTACT_ADDR CA, CONTACT C "
+ "where SE.EVENT_CD = 'PICKUP' "
+ "and SE.SHIPMENT_ID = s.shipment_id "
+ "and S.SENDER_ADDR_ID = CA.CONTACT_ADDR_ID "
+ "and CA.CONTACT_ID = c.contact_id "
+ "and C.GROUP_CD = 'OT' "
+ "and SE.EVENT_OCCURRED_IND = 'N' "
+ "and S.CREATION_TS >= (select CURRENT_TIMESTAMP - interval '30' day from dual)"
+ "and S.SCHEDULE_PICKUP_IND = 'Y'"})
#Results({
#Result(column = "CONTACT_ID", property = "contactId", jdbcType = JdbcType.DECIMAL)})
public CopyOnWriteArrayList<EligibleShipment> findShipmentsByOutlet();
}
#Primary on one of the SqlSessionFactory bean solved my problem.
#Bean
#Primary
#Override
public SqlSessionFactory sqlSessionFactory2() throws Exception {
SqlSessionFactoryBean sessionFactory2 = new SqlSessionFactoryBean();
sessionFactory2.setDataSource(dataSource2);
return sessionFactory2.getObject();
}
With spring-mybatis you either register mappers one by one or you use mappers scanning.
If you are registering mappers manually make sure you pass correct SqlSessionFactory to every mapper. If you don't do this spring will try to autowire SqlSessionFactory and because you have two of them you would get the error that no single bean found.
If you are using scanning for mappers specify parameters for it so that appropriate mappers are using correct SqlSessionFactory.
One way to do that is by placing mappers that should use different DataSources to different packages. In this case you need to create two MapperScannerConfigurer beans like this (assuming that mappers are in com.mycompany.myapp.distMappersPackage and com.mycompany.myapp.shipmentMappersPackage):
#Bean
public MapperScannerConfigurer distMapperScannerConfigurer() throws Exception {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage("com.mycompany.myapp.distMappersPackage");
configurer.setSqlSessionFactoryBeanName("distSqlSessionFactory");
return configurer;
}
#Bean
public MapperScannerConfigurer shipmentMapperScannerConfigurer() throws Exception {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage("com.mycompany.myapp.shipmentMappersPackage");
configurer.setSqlSessionFactoryBeanName("shipmentSqlSessionFactory");
return configurer;
}
Alternatively, you can create two different annotation and use them on mappers like this:
#DistMapperMarker
public interface DistMapper {
...
}
#ShipmentMapperMarker
public interface ShipmentMapper {
...
}
In this case mappers can be in one package but you specify annotationClass on MapperScannerConfigurer:
#Bean
public MapperScannerConfigurer distMapperScannerConfigurer() throws Exception {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setAnnotationClass(DistMapperMarker.class);
configurer.setSqlSessionFactoryBeanName("distSqlSessionFactory");
return configurer;
}
#Bean
public MapperScannerConfigurer shipmentMapperScannerConfigurer() throws Exception {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setAnnotationClass(ShipmentMapperMarker.class);
configurer.setSqlSessionFactoryBeanName("shipmentSqlSessionFactory");
return configurer;
}
For java base spring configuration you can also try to use MapperScan and specify parameters as attributes to it. This would require you to split spring configuration into at least two classes. I haven't used this approach so I'm not sure if it work fine.
there are few answers to the question already. But none of them works for me.
I can't figure it out for the life of me why the error is coming.
Following are the approaches I tried:
using AbstractMongoConfiguration
Manually registering the mongoTemplate bean with ApplicationContext
Whenever I try to run my test during maven build or while deploying on tomcat error below comes up
Here is the configuration.
package com.fordit.project.config;
#Configuration
#EnableMongoRepositories(basePackages = "com.company.project")
#ComponentScan(basePackages = "com.company.project")
public class ProjectConfiguration {
#Value("${project.db.driver_class}")
private String driverClassname;
#Value("${project.db.connection_string}")
private String connectionString;
#Bean
public DataSource dataSource() throws PropertyVetoException {
Properties mysqlProperties = new Properties();
mysqlProperties.setProperty("characterEncoding", "UTF-8");
mysqlProperties.setProperty("useUnicode", "true");
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setProperties(mysqlProperties);
cpds.setDriverClass(driverClassname);
cpds.setJdbcUrl(connectionString);
cpds.setAcquireIncrement(2);
return cpds;
}
#Bean
public static PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() throws IOException {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ResourceLoader resourceLoader = new PathMatchingResourcePatternResolver();
ppc.setLocations(
resourceLoader.getResource(System.getProperty("PROJECT_CONFIGURATION_FILE")));
return ppc;
}
#Bean
public static RoleHierarchy roleHierarchy() {
String roleHierarchyStringRepresentation
= Role.ROLE_ADMIN + " > " + Role.ROLE_FIRM + "\n"
+ Role.ROLE_FIRM + " = " + Role.ROLE_LAWYER+ "= "+Role.ROLE_USER;
//logger.info("Registered Role Hierarchy: \n{}", roleHierarchyStringRepresentation);
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy(roleHierarchyStringRepresentation);
return roleHierarchy;
}
}
Mongo Configuration:
#Configuration
#ComponentScan(basePackages = "com.company.project")
#Profile("container")
public class MongoDBConfiguration extends AbstractMongoConfiguration {
#Value("${project.mongodb.hostname}")
private String host;
#Value("${project.mongodb.port}")
private Integer port;
#Value("${project.mongodb.name}")
private String db;
#Value("${project.mongodb.username}")
private String username;
#Value("${project.mongodb.password}")
private String password;
#Value("${project.mongodb.authenticationDB}")
private String authDB;
#Bean
public MongoTemplate mongoTemplate()
throws UnknownHostException, java.net.UnknownHostException {
return new MongoTemplate(
new SimpleMongoDbFactory(
mongoClient(),
getDatabaseName()
)
);
}
#Override
#Bean
public MongoClient mongoClient() {
MongoClient mongoClient = null;
try {
mongoClient = new MongoClient(
new ServerAddress(host, port),
Collections.singletonList(
MongoCredential.createMongoCRCredential(
username,
authDB,
password.toCharArray()
)
)
);
} catch (java.net.UnknownHostException ex) {
Logger.getLogger(MongoDBConfiguration.class.getName()).log(Level.SEVERE, null, ex);
}
return mongoClient;
}
#Override
protected String getDatabaseName() {
return db;
}
}
Error log:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'forumDAL' defined in file [/home/ashay/projects/kuber/target/classes/com/fordit/kuber/forum/ForumDAL.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'forumRepository': Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mongoTemplate' available
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:729)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:192)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1270)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:107)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:243)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 26 more
Get rid of the Profile("container") in MongoDBConfiguration.
Explanation: Because the #Profile is there, that means that that class will not be instantiated by Spring unless you are running Spring with that profile. My guess is that you are not setting spring.profiles.active property to "container" when you run your application via Tomcat or during your integration testing.
If you want to leave the #Profile("container") there then just make sure you set the profile to "container". There are multiple ways to do this. One quick easy way is to use Java system properties, e.g. -Dspring.profiles.active=container, when you execute your integration tests or run your application in Tomcat.
This is my code which I use to send a html email using java spring and thymeleaf template engine.
#Service
public class EmailServiceImpl implements EmailService {
private static final String EMAIL_SIMPLE_TEMPLATE_NAME = "html/html";
#Value("${email.user.register.body}")
private String USER_REGISTER_MESSAGE_BODY;
#Value("${email.user.register.subject}")
private String USER_REGISTER_MESSAGE_SUBJECT;
#Value("${mailSender.address}")
private String SENDER_EMAIL_ADDRESS;
#Autowired
private JavaMailSender mailSender;
#Autowired
private TemplateEngine templateEngine;
#Override
public void sendEmail(MimeMessagePreparator preparator) {
mailSender.send(preparator);
}
#Async
#Override
public void sendUserRegisterEmail(String receiver, String receiverEmailAddress){
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
message.setSubject(USER_REGISTER_MESSAGE_SUBJECT);
message.setTo(receiverEmailAddress);
message.setFrom(SENDER_EMAIL_ADDRESS);
message.setText(String.format(USER_REGISTER_MESSAGE_BODY, receiver));
}
};
sendEmail(preparator);
}
public void sendMailWithInline(
final String recipientName, final String recipientEmail, final String imageResourceName,
final byte[] imageBytes, final String imageContentType, final Locale locale)
throws MessagingException {
// Prepare the evaluation context
final Context ctx = new Context(locale);
ctx.setVariable("name", recipientName);
ctx.setVariable("subscriptionDate", new Date());
ctx.setVariable("hobbies", Arrays.asList("Cinema", "Sports", "Music"));
ctx.setVariable("imageResourceName", imageResourceName); // so that we can reference it from HTML
// Prepare message using a Spring helper
final MimeMessage mimeMessage = this.mailSender.createMimeMessage();
final MimeMessageHelper message =
new MimeMessageHelper(mimeMessage, true, "UTF-8"); // true = multipart
message.setSubject("Example HTML email with inline image");
message.setFrom("adbuylk#gmail.com");
message.setTo(recipientEmail);
// Create the HTML body using Thymeleaf
final String htmlContent = this.templateEngine.process(EMAIL_SIMPLE_TEMPLATE_NAME, ctx);
message.setText(htmlContent, true); // true = isHtml
// Add the inline image, referenced from the HTML code as "cid:${imageResourceName}"
final InputStreamSource imageSource = new ByteArrayResource(imageBytes);
message.addInline(imageResourceName, imageSource, imageContentType);
// Send mail
this.mailSender.send(mimeMessage);
}
I am getting the following error while trying to run it using Jetty and Intellij idea.
[WARNING] Failed startup of context o.e.j.m.p.JettyWebAppContext#23321be7{/adsops,file:///E:/Projects/ADpost/ops/dev/src/main/webapp/,STARTING}{file:///E:/Projects/ADpost/ops/dev/src/main/webapp/}
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfiguration': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'applicationUserServiceImpl': Unsatisfied dependency expressed through field 'emailService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'emailServiceImpl': Unsatisfied dependency expressed through field 'templateEngine'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'templateEngine' defined in com.vlclabs.adsops.configuration.WebApplicationConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.thymeleaf.spring4.SpringTemplateEngine]: Factory method 'templateEngine' threw exception; nested exception is java.lang.NoClassDefFoundError: org/thymeleaf/dialect/IExpressionEnhancingDialect
These are the dependencies
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>${thymeleaf.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-conditionalcomments</artifactId>
<version>${thymeleaf-extras-conditionalcomments.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>${thymeleaf-extras-java8time.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>${thymeleaf-extras-springsecurity4.version}</version>
</dependency>
While trying to go through the error message I understand the error may occur due to mistake I did while adding template engine. However I couldn't fix it trying for days. Please help
The problem is likely that you mix versions that are not compatible. You can check your versions by running:
mvn dependency:tree
(If you have Eclipse, you can open the pom file and switch to "Dependency Hierarchy" tab for the same thing.)
Especially check for these:
org.thymeleaf:thymeleaf-spring4:jar
org.thymeleaf:thymeleaf:jar
These two should have the same version. If they don't, adjust your dependencies.
I have the follwoing aspect:
#Component
#Aspect
public class LoggingAspect {
Logger logger = Logger.getLogger(LoggingAspect.class);
#AfterReturning(pointcut = "execution(* com.example..*.*(..))", returning = "retVal")
public void logAfterMethod(JoinPoint joinPoint, Object retVal) {
StringBuffer logMessage = new StringBuffer();
logMessage.append(joinPoint.getTarget().getClass().getName());
logMessage.append(".");
logMessage.append(joinPoint.getSignature().getName());
logMessage.append("(");
// append args
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
logMessage.append(args[i]).append(",");
}
if (args.length > 0) {
logMessage.deleteCharAt(logMessage.length() - 1);
}
logMessage.append(")");
if (retVal != null) {
logMessage.append(" with return value " + retVal + " of type "
+ retVal.getClass());
} else {
logMessage.append(" with return value null");
}
logger.info(logMessage);
}
}
and then the following bean:
#Bean
public LoggingAspect logger(){
return new LoggingAspect();
}
but whenever I want to run my application it gives me the errors, I have google it but could not find any related problem to this one, maybe I am missing something ://
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embeddedServletContainerCustomizerBeanPostProcessor': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': BeanPostProcessor before instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': BeanPostProcessor before instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
Caused by: java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
The main reason is: nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld.
This means you have to add the aspectjweaver.jar to your classpath.
If you use maven, add the dependency to your pom.xml:
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>