ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean - spring

Trying to setup a simple web application scheduler. So here is my configuration:
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>scheduler</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>1.1.7.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<start-class>hello.Application</start-class>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>hello.Application</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>http://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>http://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
My classes look like below
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class Application implements WebApplicationInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(ScheduledTasks.class);
}
public void onStartup(ServletContext arg0) throws ServletException {
SpringApplication.run(ScheduledTasks.class);
}
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(8081);
factory.setSessionTimeout(50, TimeUnit.MINUTES);
return factory;
}
}
#EnableScheduling
public class ScheduledTasks {
#Scheduled(fixedRate = 500)
public void reportCurrentTime() {
System.out.println("Testing successful ");
}
}
But when i try to start the container i see the exception
ERROR 2592 --- [ost-startStop-1] o.s.boot.SpringApplication : Application startup failed
...
...
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:174)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:147)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:121)
... 20 more
I tried to follow Spring Boot Testing: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean but in vain.
Kindly suggest, thanks

You are only running ScheduledTasks:
SpringApplication.run(ScheduledTasks.class);
when you should run:
SpringApplication.run(Application.class);
Running ScheduledTasks means that Spring Boot doesn't know about the configuration in Application. Crucially, it means that it doesn't see #EnableAutoConfiguration which is what switches on auto-configuration and, because you have Tomcat on the classpath, creates the embedded Tomcat instance.
I would fix this by moving the #EnableScheduling annotation from ScheduledTasks to Application, running Application.class rather than ScheduledTasks.class, and annotating ScheduledTasks with #Component:
Application.class:
#Configuration
#EnableAutoConfiguration
#ComponentScan
#EnableScheduling
public class Application implements WebApplicationInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
// …
}
ScheduledTasks.class:
#Component
public class ScheduledTasks {
#Scheduled(fixedRate = 500)
public void reportCurrentTime() {
System.out.println("Testing successful ");
}
}
Moving #EnableScheduling means that its on a configuration class, where it belongs. Running Application.class means that Spring Boot sees all of its configuration, including enabling component scanning and enabling auto-configuration. Annotating ScheduledTasks with #Component means that it's found by component scanning and its #Scheduled method is detected.
This should get things up and running. I would also correct your pom so that you're not using a mixture of versions of Spring Boot (you have 1.1.6 and 1.1.7 in there at the moment) and get rid of your EmbeddedServletContainerFactory bean in favour of configuring the port and session timeout using application.properties in src/main/resources instead:
application.properties:
server.port = 8081
server.session-timeout = 3000

besides what #Andy Wilkinson pointed out which is true in the OP's case but not in mine
I saw that my spring-boot-starter-tomcat was with
<scope>provided</scope>
( as i was adding a servlet initializer to run it on wildfly) i commented out that bit and removed provided from spring-boot-starter-tomcat dependency and it started working. Adding here just in case some one else has the same issue

My one got fixed using this dependency :
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>

Related

Spring Boot/Tomcat, "Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean"

I know there are others questions on this, and I have checked them, but none solves my issue.
Very simple POM, ready:ing my app for use with an embedded web server, simply so I can start it up...
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Very easy Boot class:
#SpringBootApplication
#RestController
public class SpringBootApp {
public static void main(String[] args) {
SpringApplication.run(SpringApplication.class, args);
}
#RequestMapping(value = "/")
public String hello() {
return "Hello World from Tomcat";
}
}
Tried:
Extend the SpringBootServletInitializer class.
Update spring-boot-starter-parent to the latest (2.1.3).
Setting spring.profiles.active=default in application.properties.
Manually inject TomcatWebServerFactory (ugh...) in #Configuration
class.
Run mvn dependency:purge-local-repository and removed /repository dir
from my .m2 dir, fetching all again with mvn clean install -U.
ETC... I do not see why it is not working, I though Spring Boot was supposed to be easy.
Unable to start ServletWebServerApplicationContext due to missing
ServletWebServerFactory bean.
First argument for SpringApplication.run() is expected to be the primary configuration class of your application. In your case it is SpringBootApp.class and not SpringApplication.class. Following would be the correct configuration for your Spring Boot application.
public static void main(String[] args)
{
SpringApplication.run(SpringBootApp.class, args);
}

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

ClassNotFoundException CrudRepository

I'm reading the JPA docs on spring, and i'm trying to restructure my code.
What i have now:
BrewerRepository
#Repository
public class BrewerRepository {
#PersistenceContext(name = "vivesPU")
private EntityManager entityManager;
public List<Brewer> getAll() {
return null;
}
}
BrewerService
#Service
public class BrewerService {
#Autowired
private BrewerRepository brewerRepository;
public List<Brewer> getAll() {
return null;
}
}
HomeController
#Controller
public class HomeController {
#Autowired
private BrewerService brewerService;
#GetMapping("/")
public String index(Model model) {
List<Brewer> brewers = this.brewerService.getAll();
model.addAttribute("brewers", brewers);
return "index";
}
}
PersistenceJPAConfig
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories
public class PersistenceJPAConfig{
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
entityManager.setDataSource(dataSource());
entityManager.setPackagesToScan("org.vives.model");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
entityManager.setJpaVendorAdapter(vendorAdapter);
entityManager.setJpaProperties(additionalProperties());
return entityManager;
}
#Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
dataSource.setUrl("jdbc:derby://localhost:1527/beers;create=true");
dataSource.setUsername( "app" );
dataSource.setPassword( "app" );
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManager){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManager);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
private Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect");
properties.setProperty("hibernate.transaction.jta.platform", "org.hibernate.service.jta.platform.internal.SunOneJtaPlatform");
properties.setProperty("hibernate.show_sql", "true");
return properties;
}
}
With this code, the application starts without problems.
When i change the Repository and Service like this:
#Repository
public interface BrewerRepository extends CrudRepository<Brewer, Long> {
}
#Service
public class BrewerService {
#PersistenceContext(name = "vivesPU")
private EntityManager entityManager;
#Autowired
private BrewerRepository brewerRepository;
public List<Brewer> getAll() {
return null;
}
}
Error log:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'homeController': Unsatisfied dependency expressed through field 'brewerService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'brewerService' defined in file [.\glassfish-5.0\glassfish5\glassfish\domains\domain1\applications\spring-mvc-quickstart-1.0-SNAPSHOT\WEB-INF\classes\org\vives\service\BrewerService.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [org.vives.service.BrewerService] from ClassLoader [WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)]]]
...
Context initialization failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'homeController': Unsatisfied dependency expressed through field 'brewerService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'brewerService' defined in file [.\glassfish-5.0\glassfish5\glassfish\domains\domain1\applications\spring-mvc-quickstart-1.0-SNAPSHOT\WEB-INF\classes\org\vives\service\BrewerService.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [org.vives.service.BrewerService] from ClassLoader [WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)]
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'brewerService' defined in file [.\glassfish-5.0\glassfish5\glassfish\domains\domain1\applications\spring-mvc-quickstart-1.0-SNAPSHOT\WEB-INF\classes\org\vives\service\BrewerService.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [org.vives.service.BrewerService] from ClassLoader [WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)]
...
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.vives.service.BrewerService] from ClassLoader [WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)]
...
Caused by: java.lang.NoClassDefFoundError: org/springframework/data/repository/CrudRepository
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at org.glassfish.web.loader.WebappClassLoader.findClass(WebappClassLoader.java:1059)
at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1588)
at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1471)
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
at java.lang.Class.getDeclaredFields(Class.java:1916)
at org.springframework.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:754)
... 82 more
Caused by: java.lang.ClassNotFoundException: org.springframework.data.repository.CrudRepository
at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1621)
at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1471)
... 92 more
]]
I've tried to look for an answer, but without success. Can someone explain to me why this is happening and tell me how I can fix it?
What I've tried so far:
checked the dependencies
deleted the .m2 folder and installed all
dependencies again messed a bit with annotations
changed a bit the project structure, according to this post
EDIT:
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>org.vives</groupId>
<artifactId>spring-mvc-quickstart</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>spring-mvc-quickstart</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java-version>1.8</java-version>
<!-- Override Spring version -->
<spring.version>5.0.0.RELEASE</spring.version>
<jackson.version>2.9.1</jackson.version>
<thymeleaf-extras-java8time-version>3.0.1.RELEASE</thymeleaf-extras-java8time-version>
<!-- AssertJ is not a part of Spring IO platform, so the version must be provided explicitly -->
<assertj-core-version>3.8.0</assertj-core-version>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<!-- Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<!-- Avoid issue #72 Could not initialize class org.thymeleaf.templateresolver.ServletContextTemplateResolver due to 'validation is not supported' -->
<exclusions>
<exclusion>
<artifactId>pull-parser</artifactId>
<groupId>pull-parser</groupId>
</exclusion>
</exclusions>
<version>5.2.9.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-release</id>
<name>Spring Release Repository</name>
<url>https://repo.spring.io/release</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Came to this error [ Caused by: java.lang.ClassNotFoundException: org.springframework.data.repository.CrudRepository ] was using springboot dev tools auto build
but stopped the program -> clean -> run solved the issue on my end.
the CrudRepository class is not found which means that the pom dependencies are not defined well. The Crud repository is defined the spring-data-jpa and it is included but i think the problem could be found in the spring different dependencies that you are using that may conflict with each other. for example some dependencies may be included as a child dependencies in others, so they must not be included again. Also you must make sure that the spring dependencies versions are consistent.
I cleared the .m2 repository (path e.g. C:\Users\Hetal Rachh\.m2\repository) and then did a mvn clean install build and it worked.
The Constructor Injection is missing like:
#Autowired
public BrewerService(BrewerRepository brewerRepository) {
this.brewerRepository = brewerRepository
}
#Override
public List<Brewer> getAll() {
return brewerRepository.findAll();
}
As Amr Alaa mentioned, there was an issue with the dependencies. I solved my problem by creating a new project in a different folder and adding the dependencies again.
I usually update the project and let it rebuild, then restart the program in the spring boot dashboard.

spring boot actuator for standalone spring application

I am trying to learn spring boot actuator. I have a simple basic application which runs via main method. It has not tomcat or anything. It has just one class as below
public class StartUp {
public static void main(String... args) throws InterruptedException {
ConfigurableApplicationContext ctx = SpringApplication.run(StartUp.class,
args);
StartUp mainObj = ctx.getBean(StartUp.class);
mainObj.init();
System.out.println("Application exited");
}
public void init() throws InterruptedException {
System.out.println("inside init method");
Thread.sleep(10 * 60 * 1000);
System.out.println("outside init method");
}
}
I have configured spring actuator as below in pom:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<!-- [3] -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
I was trying to view the applications health and info, i have configured the below in application.properties
management.port=8091
management.address=127.0.0.1
management.security.enabled=false
endpoints.shutdown.enabled=true
info.app.name=Startup Dashboard
info.app.version=2.0-ALPHA
logging.file=dashboard.log
while trying the url : http://localhost:8091/info
it never gets resolved.
Is it not possible to configure actuator for standalone applications ?
Your application is not a Spring Boot App yet.
One has to use the #SpringBootApplication at the minimum to convert an app into one.
#SpringBootApplication
public class BootadminMsAlphaApplication {
public static void main(String[] args) {
SpringApplication.run(BootadminMsAlphaApplication.class, args);
}
}
is one such simplest example.
Without this, the spring-boot dependency in your classpath have not been asked to do its magical things to make your application smart. The all-in-one annotation brings spring-boot's auto-configuration into play, that configures a lot of good stuff for the app, including Actuators (if in classpath).
It looks like your application isn't a Spring Boot application. It needs to be.

Configure integration test or use Spring JDBC in Unit Test using Spring Boot?

Am using the latest versions of Spring Boot, Spring JDBC, and Spring Rest...
My project is setup as a typical Maven project containing the following filesystem structure:
myproject
|
--src/main/java/com/myapp
--src/main/resource/application.properties
|
--src/test/java/com/myapp
--src/test/resources/application.properties
|
pom.xml
My application.properties are as follows (connecting to a local MySQL 5 database):
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=
spring.datasource.name=testdb
spring.datasource.initialize=true
spring.datasource.driverClassName=com.mysql.jdbc.Driver
MyDAO:
public interface MyDao {
public List<App> findAllApps();
}
MyDaoImpl:
#Repository("myDao")
public class MyDaoImpl implements MyDao {
#Autowired
JdbcTemplate jdbcTemplate;
public List<App> findAllApps() {
List<App> apps = this.jdbcTemplate.query(
"select app_name from app",
new RowMapper<App>() {
public App mapRow(ResultSet rs, int rowNum) throws SQLException {
App app = new App();
app.setAppName(rs.getString("app_name"));
return app;
}
});
return apps;
}
}
Its called in MyService class using Dependency Injection:
#RestController
public class MyService {
#Autowired
#Qualifier("myDao")
MyDao myDao;
#RequestMapping(value = "/apps", method = RequestMethod.GET, consumes = "text/plain", produces = "application/json")
public void process() throws JsonParseException, IOException {
List<App> apps = myDao.findAllApps();
System.out.println(apps.toString());
}
}
This totally works as stated in my RestController...
But however, in a typical JUnit test:
public class MyServiceTest {
#Autowired
#Qualifier("myDao")
MyDao myDao;
#Test
public void process() {
List<App> apps = myDao.findAllApps();
}
}
The call to myDao.findAllApps() returns a NullPointerException...
I even tried running my app (using the embedded tomcat) first by issuing the following from the command line:
mvn spring-boot:run
However a non-database specific JUnit test works inside Eclipse or when I do:
mvn clean install
Question(s):
How can I set it up so I can run an integration test and it actually hits my database (or a mock db for that matter) from MyServiceTest?
Why is the dependency injection failing when trying to inject in MyServiceTest for Spring JDBC?
Is there a way to setup my unit tests to test Rest calls?
Many thanks for everyone who took the time to read this and many many thanks for the people that respond!
Here's my pom.xml (per Eddu's request):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>myproject</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.2.RELEASE</version>
</parent>
<properties>
<java.version>1.7</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>org.jboss.repository.releases</id>
<name>JBoss Maven Release Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
It seems you aren't loading Spring's context in your test so the dependency injection isn't performed. You should do something like:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=Application.class) //Application being your
// Spring boot base config class
public class MyServiceTest { ... }
#Autowired
#Qualifier("myDao")
MyDao myDao;
You can have a look at an example in my github
Thanks everyone!
Steve - you were correct!
After much trial & tribulation, the #SpringApplicationConfiguration worked:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes=Application.class)
Eddu Melendez - I removed the spring-starter-data-jpa dependency with spring-boot-starter-jdbc and also removed the spring-jdbc dependency from my pom.xml file.
Thank you all for trying to help me solve this issue!

Resources