Spring Boot with Apache CXF and CDI - spring

When using Apache's CXF JAX-RS Spring Boot starter with the CXF CDI dependency (cxf-integration-cdi), Spring fails trying to do the autowiring because it only supports JSR 330 and not CDI. Is there a way to get CDI to work with Spring Boot?
Code:
package com.ibm.test.webservices;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
#ApplicationPath("/")
#Path("/")
public class TestWebServices extends Application {
public static void main(String[] args) {
SpringApplication.run(
TestWebServices.class,
"--cxf.path=/",
"--cxf.jaxrs.classes-scan=true",
"--cxf.jaxrs.classes-scan-packages=" +
TestWebServices.class.getPackage().getName()
);
}
#Inject
#Any
private Instance<InvokerInterface> impl;
#GET
#Produces("text/plain")
#Path("/")
public String helloWorld() {
return impl.get().invoke();
}
public interface InvokerInterface {
String invoke();
}
#Named
#Default
public static class Implementation1 implements InvokerInterface {
public String invoke() {
return "Hello World 1\n";
}
}
#Named
public static class Implementation2 implements InvokerInterface {
public String invoke() {
return "Hello World 2\n";
}
}
}
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ibm.test</groupId>
<artifactId>test-spring-boot-with-cdi</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test Spring Boot with Apache CXF and CDI</name>
<!-- We need to use cxf-spring-boot-starter-jaxrs 3.2.0 because of https://issues.apache.org/jira/browse/CXF-7237
At the time of writing this code, the latest available version in Maven central
is 3.1.7 so we need to use the Apache snapshot repository. -->
<repositories>
<repository>
<id>apache.snapshots</id>
<name>Apache Development Snapshot Repository</name>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
<version>3.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-integration-cdi</artifactId>
<version>3.1.11</version>
</dependency>
</dependencies>
<!-- Required for a standalone JAR: -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Exception:
2017-07-28 16:32:59.527 ERROR 9630 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field impl in com.ibm.test.webservices.TestWebServices required a bean of type 'javax.enterprise.inject.Instance' that could not be found.
Action:
Consider defining a bean of type 'javax.enterprise.inject.Instance' in your configuration.
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:527)
at java.lang.Thread.run(Thread.java:785)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testWebServices': Unsatisfied dependency expressed through field 'impl'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.enterprise.inject.Instance<com.ibm.test.webservices.TestWebServices$InvokerInterface>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#javax.inject.Inject(), #javax.enterprise.inject.Any()}
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.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
at com.ibm.test.webservices.TestWebServices.main(TestWebServices.java:22)
... 6 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.enterprise.inject.Instance<com.ibm.test.webservices.TestWebServices$InvokerInterface>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#javax.inject.Inject(), #javax.enterprise.inject.Any()}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 25 more

The key insight is that Spring autowiring (e.g. scanBasePackages on #SpringBootApplication, #ComponentScan, etc.) must be avoided. The following worked:
TestSpringBootApplication.java:
package com.test.webservices;
import org.apache.cxf.cdi.CXFCdiServlet;
import org.jboss.weld.environment.se.Weld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
// #ServletComponentScan only occurs with an embedded web server, and this is
// needed for Tomcat:
// https://docs.jboss.org/weld/reference/latest/en-US/html/environments.html#_tomcat
#ServletComponentScan(basePackageClasses = { org.jboss.weld.environment.servlet.Listener.class })
public class TestSpringBootApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(TestSpringBootApplication.class);
app.addInitializers(new ApplicationContextInitializer<ConfigurableApplicationContext>() {
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
new Weld().initialize();
}
});
app.run(args);
}
#Bean
public ServletRegistrationBean cxfServletRegistration() {
// http://cxf.apache.org/docs/using-cxf-and-cdi-11-jsr-346.html
ServletRegistrationBean registration = new ServletRegistrationBean(new CXFCdiServlet(), "/*");
registration.setLoadOnStartup(1);
return registration;
}
}
TestWebServicesApplication.java:
package com.test.webservices;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("/")
public class TestWebServicesApplication extends Application {
}
TestWebServices.java:
package com.test.webservices;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.Vetoed;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Path("/")
public class TestWebServices {
#Inject
#Any
private Instance<InvokerInterface> impl;
#GET
#Produces("text/plain")
#Path("/")
public String helloWorld() {
return impl.get().invoke();
}
public interface InvokerInterface {
String invoke();
}
public static class Implementation1 implements InvokerInterface {
public String invoke() {
return "Hello World 1\n";
}
}
#Vetoed
public static class Implementation2 implements InvokerInterface {
public String invoke() {
return "Hello World 2\n";
}
}
}
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>test-spring-boot-with-cdi</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Test Spring Boot with Apache CXF and CDI</name>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!-- We need to use cxf-spring-boot-starter-jaxrs 3.2.0 because of https://issues.apache.org/jira/browse/CXF-7237
At the time of writing this code, the latest available version in Maven central
is 3.1.7 so we need to use the Apache snapshot repository. -->
<repositories>
<repository>
<id>apache.snapshots</id>
<name>Apache Development Snapshot Repository</name>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
<version>3.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-integration-cdi</artifactId>
<version>3.1.11</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet</artifactId>
<version>2.4.4.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>2.4.4.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
<!-- Required for a standalone JAR: -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
src/main/resources/META-INF/beans.xml:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
src/main/resources/META-INF/context.xml:
<!-- Required for Tomcat: https://docs.jboss.org/weld/reference/latest/en-US/html/environments.html#_tomcat -->
<Context>
<Resource name="BeanManager" auth="Container"
type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" />
</Context>
To use JAXB in addition to JSON, it seems that CXF's JAXRSCdiResourceExtension doesn't find any #Providers, so I also added a CDI Extension that creates JacksonJaxbJsonProvider as an AnnotatedType (this also seems to require that the JAX-RS Application object does not override getClasses or getSingletons and instead auto-discovers all #Paths):
package com.test;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
public class RegisterCDIBeans implements javax.enterprise.inject.spi.Extension {
public void beforeBeanDiscovery(#Observes BeforeBeanDiscovery bbd, BeanManager beanManager) {
final AnnotatedType<?> annotatedType = beanManager.createAnnotatedType(JacksonJaxbJsonProvider.class);
bbd.addAnnotatedType(annotatedType, annotatedType.toString());
}
}
And then register the CDI extension in src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension:
com.test.RegisterCDIBeans

you need to create the bean or use #Autowired to inject javax.enterprise.inject.Instance class into TestWebServices. you can create the bean into ApplicationContaxt.xml and use #Autowired #Qualifier to inject class.

Related

Minecraft Spigot/Paper best way to receive info to site?

How to best way to receive info to cite from minecraft plugin? Maybe used simple http servlet, but how start him without Tomcat? Or, maybe, better to use websockets?
I'm creating a project used plugin "Minecraft" like spigot plugin and try to add spring boot web starter but i don't know how to connect him to plugin.
I've added dependencies and change plugin to:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sniklz</groupId>
<artifactId>snikkzPlugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SnikkzPlugin</name>
<description>asdasd</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>papermc-repo</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.18.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
</project>
SniklzPlugin.class:
package com.sniklz.snikkzplugin;
import org.bukkit.plugin.java.JavaPlugin;
public final class SnikkzPlugin extends JavaPlugin {
#Override
public void onEnable() {
// Plugin startup logic
new Thread(() -> {
SniklzPluginApp.start();
}).start();
}
#Override
public void onDisable() {
// Plugin shutdown logic
}
}
sniklzPluginApp.class:
package com.sniklz.snikkzplugin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class SniklzPluginApp {
public static void start() {
SpringApplication.run(SniklzPluginApp.class);
}
}
controller->firstController.class:
package com.sniklz.snikkzplugin.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("/home")
public class FirstContoller {
#GetMapping
public String homeController() {
System.out.println("Hello World");
return "Hello world";
}
}
But when I build the plugin and start it from server, I get this error:
Exception in thread "Thread-6" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
[09:02:43 WARN]: at snikkzPlugin-1.0-SNAPSHOT.jar//com.sniklz.snikkzplugin.SniklzPluginApp.start(SniklzPluginApp.java:14)
[09:02:43 WARN]: at snikkzPlugin-1.0-SNAPSHOT.jar//com.sniklz.snikkzplugin.SnikkzPlugin.lambda$onEnable$0(SnikkzPlugin.java:11)
[09:02:43 WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
[09:02:43 WARN]: Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
[09:02:43 WARN]: at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:151)
[09:02:43 WARN]: at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:103)
[09:02:43 WARN]: at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
The issue come from that you don't have the spring code with your plugin. To fix this, you should include dependencies as jar.
You can also add a jar of spring in the class loader.
Finally, you can do new Thread(SniklzPluginApp::start).start(); for a one-line starter

error while reloading spring properties with #RefreshScope in spring cloud

I'm testing one prototype for spring-cloud using #RefreshScope annotation. I'm using one external property file for that. Which I have provided and configured in runtime argument.
pom.xml dependency
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.proto.reload</groupId>
<artifactId>CachingService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>CachingService</name>
<description>Demo project for cache</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<version>1.1.8.RELEASE</version>
</dependency>
<!-- <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-client</artifactId>
<version>1.1.3.RELEASE</version> </dependency> -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
This is main class
package com.proto.reload;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.ApplicationPidFileWriter;
#SpringBootApplication
public class CachingServiceApplication {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Invalid Commandline argument. Please provide Consumer Properties file.");
System.exit(0);
}
new SpringApplicationBuilder(CachingServiceApplication.class)
.listeners(new ApplicationPidFileWriter())
.properties("spring.config.name:" + args[0].replaceAll(".properties", ""))
.build()
.run(args);
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ConfigClass.getName());
}
}
}
Config class having #RefreshScope annotation
package com.proto.reload;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
#Configuration
#RefreshScope
public class ConfigClass {
private static String name;
public static String getName() {
return name;
}
#Value("${app.prop.name}")
public void setName(String name) {
this.name = name;
}
}
And this is property file I'm passing through argument
app.prop.name=FirstOldValue
spring.pid.file=TestOne.pid
When I run this code, I get the following error.
12:38:41.051 [main] DEBUG org.springframework.boot.context.logging.ClasspathLoggingApplicationListener - Application failed to start with classpath: [file:/C:/Program%20Files/Java/jre1.8.0_191/lib/resources.jar, file:/C:/Program%20Files/Java/jre1.8.0_191/lib/rt.jar, file:/C:/Program%20Files/Java/jre1.8.0_191/lib/jsse.jar, file:/C:/Program%20Files/Java/jre1.8.0_191/lib/jce.jar, file:/C:/Program%20Files/Java/jre1.8.0_191/lib/charsets.jar, file:/C:/Program%20Files/Java/jre1.8.0_191/lib/jfr.jar, file:/C:/Program%20Files/Java/jre1.8.0_191/lib/ext/access-bridge-64.jar, file:/C:/Program%20Files/Java/jre1.8.0_191/lib/ext/cldrdata.jar, ...]
12:38:41.105 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Object;)V
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:120)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:84)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:62)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:75)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:347)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
at com.proto.reload.CachingServiceApplication.main(CachingServiceApplication.java:19)
Am I using #RefreshScope in wrong way ?
This code works fine when I remove dependency and #RefreshScope, but its not updating property value at runtime. My goal is to load modified property value at runtime.
1.1.8.RELEASE for Spring Cloud is part of the Camden Release train which is for Spring Boot 1.4.x releases.
Please see the Release Trains section for what release train to use for your Spring Boot version
https://spring.io/projects/spring-cloud
Currently they are,
Release Train Boot Version
Greenwich 2.1.x
Finchley 2.0.x
Edgware 1.5.x
Dalston 1.5.x
As your using spring boot 2.1.1 your dependency management should look like the below, note as Greenwich doesn't have a RELEASE yet you need to add the milestone repository.
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RC2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
</dependencies>
try this
#RefreshScope
public class ConfigClass {
#Value("${app.prop.name}")
private static String name;
public static String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Add cloud context depedency and try again
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<version>1.1.8.RELEASE</version>
</dependency>
Update :
it is just not a valid use case to have #Configuration and #RefreshScope on the same element. As per this URL thread : https://github.com/spring-cloud/spring-cloud-config/issues/43

Springboot JdbcTemplate Autowired failed

I'm trying to access database using springboot, however spring application throws an exception below.
Error creating bean with name 'welcomeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jdbc.core.JdbcTemplate com.mysite.soLexiconWebSpring.jsp.WelcomeController.dataSource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Which I think is mainly
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency
that indicates that no bean is created from application config file.
However I googled for a while and got no luck. Can anybody tell me how to inject JdbcTemplate Correctly?
Here is my POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.0.2.RELEASE</version>
</parent>
<artifactId>soLexiconWebSpring</artifactId>
<groupId>com.mysite</groupId>
<packaging>war</packaging>
<name>Spring Boot Web JSP Sample</name>
<description>Spring Boot Web JSP Sample</description>
<version>0.0.1-SNAPSHOT</version>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
<m2eclipse.wtp.contextRoot>/</m2eclipse.wtp.contextRoot>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
</build>
</project>
Application.properties
spring.view.prefix=/WEB-INF/jsp/
spring.view.suffix=.jsp
application.message=Hello SuperLucky
#spring.datasource basic database parameter
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/so_lexicon
spring.datasource.username=xxx
spring.datasource.password=xxx
#set data pooling provider to org.apache.tomcat
spring.datasource.type = org.apache.tomcat.jdbc.pool.DataSource
#tomcat datasource settings
spring.datasource.tomcat.initial-size=20
spring.datasource.tomcat.max-wait=2000
spring.datasource.tomcat.max-active=100
spring.datasource.tomcat.max-idle=16
spring.datasource.tomcat.min-idle=4
spring.datasource.tomcat.test-on-connect=true
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.test-on-return=true
Application
package com.mysite.soLexiconWebSpring.jsp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class SampleWebJspApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SampleWebJspApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleWebJspApplication.class, args);
}
}
Controller
package com.mysite.soLexiconWebSpring.jsp;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.mysite.soLexiconWebSpring.jsp.beans.FullLexiconRowBean;
import com.mysite.soLexiconWebSpring.jsp.beans.LoginTokenBean;
import com.mysite.soLexiconWebSpring.jsp.dao.LexiconDaoImpl;
import com.mysite.soLexiconWebSpring.jsp.utils.DBUtils;
#Controller
public class WelcomeController {
#Value("${application.message:Hello World}")
private String message = "Hello World";
#Autowired
private JdbcTemplate dataSource;
#Autowired
private DBUtils dbUtils;
#RequestMapping("/soLexiconWebSpring")
public String welcome(Map<String, Object> model) {
model.put("time", new Date());
model.put("message", this.message);
return "welcome";
}
#RequestMapping("/soLexiconWebSpring/login")
public String login(#RequestParam("username") String username, #RequestParam("password") String password, Map<String, Object> model)
{
LoginTokenBean loginToken = new LoginTokenBean();
loginToken.setUsername(username);
loginToken.setPassword(password);
model.put("loginToken", loginToken);
LexiconDaoImpl lexRowDao = new LexiconDaoImpl(dataSource);
List<FullLexiconRowBean> result = lexRowDao.getLexiconRow(1, 5);
if(result != null) model.put("result", result);
else model.put("result", dbUtils.getLastException().toString());
dbUtils.setLastException(new Exception("A B C"));
model.put("dbUtils", dbUtils);
return "lexicon";
}
}
Thanks for #mrkemelpanic, I updated my project to springboot 2.0.4 (with some effort), and it finally works. So it might be a 1.0.2 bug or something.
Thanks.

JDBC required, but no need to use the jdbc

I have been coding with my spring project.
Here is my configuration:
-main class
#SpringBootApplication(
scanBasePackages ={"src.tl_client"}
)
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
return builder.sources(Application.class).bannerMode(Banner.Mode.OFF);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>src.tl_client</groupId>
<artifactId>src.tl_client</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>src.tl_client</name>
<description>Project for TE TECHLONG client side.</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<start-class>src.tl_client.Application</start-class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc -->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>-->
<!--<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<!–<scope>runtime</scope>–>
</dependency>-->
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports-fonts -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-fonts</artifactId>
<version>6.0.0</version>
</dependency>
<!--<dependency>
<groupId>src.tl_client</groupId>
<artifactId>src.tl_client</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/src/tl_client/liberies/KhBattambang.jar</systemPath>
</dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--<plugins>
<!– Package as an executable jar/war –>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>src.tl_client</groupId>
<artifactId>src.tl_client</artifactId>
<packaging>jar</packaging>
<file>${basedir}/src/tl_client/liberies/KhBattambang.jar</file>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>src.tl_client</id>
<url>${basedir}/src/tl_client/liberies/KhBattambang.jar</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
bean configuration
package src.tl_client.configuration;
import java.io.IOException;
import java.util.Locale;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#ComponentScan
#PropertySource(value={"classpath:configuration.properties"})
public class WebConfiguration extends WebMvcConfigurerAdapter {
#Autowired
private Environment environment;
#Bean
public HttpHeaders httpHeader(){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String credentials = environment.getProperty("LT.API.SECRET_HEADER");
System.out.println("header "+credentials);
headers.set("Authorization", "Basic " + credentials);
return headers;
}
#Bean
public RestTemplate restTemplate(){
RestTemplate restTemplate = new RestTemplate();
// Add the Jackson and String message converters
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
return restTemplate;
}
#Bean
public String WS_URL(){
return environment.getProperty("TL.API.URL");
}
#Bean
public String WEB_UI_URL(){
return environment.getProperty("TL.URL");
}
#Bean
public String KEY(){
return environment.getProperty("LT.API.SECRET_HEADER");
}
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET","POST","DELETE","PUT","OPTIONS","PATCH")
.allowedOrigins("*");
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("locale/glossary");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/pages/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/webapp/**").addResourceLocations("classpath:/webapp/");
registry.addResourceHandler("/path/**").addResourceLocations("file:/");
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public SimpleMappingExceptionResolver exceptionResolver() {
SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
Properties exceptionMappings = new Properties();
exceptionMappings.put("net.petrikainulainen.spring.testmvc.todo.exception.TodoNotFoundException", "error/404");
exceptionMappings.put("java.lang.Exception", "error/error");
exceptionMappings.put("java.lang.RuntimeException", "error/error");
exceptionResolver.setExceptionMappings(exceptionMappings);
Properties statusCodes = new Properties();
statusCodes.put("error/404", "404");
statusCodes.put("error/error", "500");
exceptionResolver.setStatusCodes(statusCodes);
return exceptionResolver;
}
#Bean(name="multipartResolver")
public CommonsMultipartResolver getResolver() throws IOException {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
//Set the maximum allowed size (in bytes) for each individual file.
resolver.setMaxUploadSizePerFile(222222*5);//5MB
//You may also set other available properties.
return resolver;
}
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
#Bean(name = "localeResolver")
public LocaleResolver localeResolver() {
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocale(new Locale("kh"));
resolver.setCookieName("TL.Locale");
resolver.setCookieMaxAge(4800);
return resolver;
}
}
With the project, it takes data from a restful web service, but when I deploy the error always occurs.
Error starting ApplicationContext. To display the auto-configuration report enable debug logging (start with --debug)
2017-10-18 20:10:42.687 ERROR 14079 --- [ost-startStop-1] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Cannot determine embedded database driver class for database type NONE
Action:
If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
18-Oct-2017 20:10:42.687 SEVERE [localhost-startStop-1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:988)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1860)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: 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 org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
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:776)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:150)
at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:130)
at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 10 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 31 more
Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineDriverClassName(DataSourceProperties.java:218)
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:42)
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat.dataSource(DataSourceConfiguration.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 32 more
18-Oct-2017 20:10:42.689 SEVERE [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Error deploying web application archive [/home/node1/Downloads/apache-tomcat-8.5.23/webapps/ROOT.war]
java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:756)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:988)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1860)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
With the error, my tomcat server will never start. I really wonder why the error occurs, because I really don't need to connect to any database.
Anyone tell me how to solve the problem please.
You will need to exclude DataSourceAutoConfigurationfrom your app.
#SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class App{
public static void main(final String[] args){
SpringApplication.run(App.class, args);
}
}

Spring Batch using MongoDB with Spring Boot throws Cannot determine embedded database driver class for database type NONE

I am Getting following exception on server-startup for Spring Batch application using mongodb. Please note I have correct configuration for Mongo DB but application still trying to load JDBC data source.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>batch</groupId>
<artifactId>batch-commerce</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>Pallete Commerce with SpringBoot on JBoss</name>
<properties>
<spring-batch.version>4.0.0.M1</spring-batch.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- We need to include the javax.servlet API specs, the implementation will be provided by Wildfly / JBoss-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- MongoDB for database -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<!-- Spring Security for authentication-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<!-- JSTL for JSP
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>-->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- Spring Batch -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>openshift</id>
<build>
<finalName>boot</finalName>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<outputDirectory>webapps</outputDirectory>
<warName>boot</warName>
</configuration>
</plugin>
</plugins>
</build>
</profile>
package com.batch;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.data.MongoItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.core.io.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import com.batch.StudentDTO;
import com.mongodb.MongoClient;
import org.springframework.batch.core.Step;
#SpringBootApplication
#EnableBatchProcessing
public class BatchApplication extends SpringBootServletInitializer {
private static final Logger logger = LoggerFactory.getLogger(BatchApplication.class);
#Bean
FlatFileItemReader<StudentDTO> fileReader(#Value("resources/import_file.csv") Resource in) throws Exception {
return new FlatFileItemReaderBuilder<StudentDTO>().name("file-reader").resource(in).targetType(StudentDTO.class)
.delimited().delimiter(",").names(new String[] { "emailAddress", "name", "purchasedPackage" }).build();
}
#Bean
public MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(), "shop");
}
#Bean
public MongoTemplate mongoTemplate() throws Exception {
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
return mongoTemplate;
}
#Bean
public ItemWriter<StudentDTO> writer() {
MongoItemWriter<StudentDTO> writer = new MongoItemWriter<StudentDTO>();
try {
writer.setTemplate(mongoTemplate());
} catch (Exception e) {
logger.error(e.toString());
}
writer.setCollection("student");
return writer;
}
// #Bean
// JdbcBatchItemWriter<StudentDTO> jdbcWriter(DataSource ds) {
// return new JdbcBatchItemWriterBuilder<StudentDTO>()
// .dataSource(ds)
// .sql("insert into STUDENT(EMAIL, NAME, PURCHASE_PACKAGE)
// values(:emailAddress, :name, :purchasedPackage)")
// .beanMapped()
// .build();
// }
//
#Bean
Job job(JobBuilderFactory jbf, StepBuilderFactory sbf, ItemReader<StudentDTO> reader,
ItemWriter<StudentDTO> writer) {
Step step1 = sbf.get("product-file").<StudentDTO, StudentDTO>chunk(100).reader(reader).writer(writer).build();
return jbf.get("productFeedJob").incrementer(new RunIdIncrementer()).start(step1).build();
}
public static void main(String[] args) {
SpringApplication.run(BatchApplication.class, args);
}
}
spring:
application:
name: shop
data:
mongodb:
host: ${OPENSHIFT_MONGODB_DB_HOST}
port: ${OPENSHIFT_MONGODB_DB_PORT}
database: ${MONGODB_DATABASE}
username: ${OPENSHIFT_MONGODB_DB_USERNAME}
password: ${OPENSHIFT_MONGODB_DB_PASSWORD}
mvc:
view:
suffix: .jsp
prefix: /views/
server:
error:
whitelabel:
enabled: true
security:
oauth2:
client:
client-id: ${SECURITY_OAUTH2_CLIENT_ID}
client-secret: ${SECURITY_OAUTH2_CLIENT_SECRET}
grant-type: ${SECURITY_OAUTH2_CLIENT_GRANT_TYPE}
access-token-uri: ${SECURITY_OAUTH2_CLIENT_ACCESS_TOKEN_URI}
logging.level:
org.springframework.web: DEBUG
org.hibernate: ERROR
org.springframework.security: INFO
Error: Description:
Cannot determine embedded database driver class for database type NONE
Action:
If you want an embedded database please put a supported one on the
classpath. If you have database settings to be loaded from a
particular profile you may need to active it (no profiles are
currently active).
12:37:00,953 ERROR [org.jboss.msc.service.fail] (ServerService Thread
Pool -- 79) MSC000001: Failed to start service
jboss.undertow.deployment.default-server.default-host."/batch-commerce-1.0.0":
org. jboss.msc.service.StartException in service
jboss.undertow.deployment.default-server.default-host."/batch-commerce-1.0.0":
java.lang.RuntimeException:
org.springframework.beans.factory.UnsatisfiedDepe ndencyException:
Error creating bean with name
'org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration':
Unsatisfied dependency expressed through field 'dataSources': Error c
reating bean with name 'dataSource' defined in class path resource
[org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]:
Bean instantiation via factory method failed; nes ted exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method
'dataSource' threw exception; nested exception is
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException:
Cannot determine embedded database driver class for database type
NONE. If you want an embedded databa se please put a supported one on
the classpath. If you have database settings to be loaded from a
particular profile you may need to active it (no profiles are
currently active).; 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]: F
actory method 'dataSource' threw exception; nested exception is
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException:
Cannot determine embedded database dri ver class for database type
NONE. If you want an embedded database please put a supported one on
the classpath. If you have database settings to be loaded from a
particular profile you may need to act ive it (no profiles are
currently active).
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:85)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
I feel the spring jdbc dependency with batch is expecting you to supply datasource details. If you ignore the DataSourceAutoConfiguration this should run.
Add this with your spring boot applicaiton class
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

Resources