I have created a simple spring application to test excludeFilters in #ComponentScan annotation.
TestConfig.java
package com.example.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
#Configuration
#ComponentScan(
excludeFilters = #ComponentScan.Filter(
type = FilterType.REGEX,
pattern = {"com.example.Demo"}
)
)
public class TestConfig {
}
Demo.java
package com.example;
import org.springframework.stereotype.Component;
#Component
public class Demo {
}
Main class ExcludeFilterTest.java
public class ExcludeFilterTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.example");
}
}
when running the application I can see the Demo class is getting identified as a candidate component class and also instance is getting created.
here are the logs
12:05:34.151 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/sk/learning-development/interview/logging_test/target/classes/com/example/Demo.class]
12:05:34.160 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/sk/learning-development/interview/logging_test/target/classes/com/example/config/TestConfig.class]
12:05:34.172 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#687080dc
12:05:34.188 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
12:05:34.275 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
12:05:34.277 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
12:05:34.278 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
12:05:34.282 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'demo'
12:05:34.298 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'testConfig'
Process finished with exit code 0
why the Demo class instance is getting created?
Try this instead.
public class ExcludeFilterTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(com.example.config.TestConfig.class);
}
}
Related
This question already has an answer here:
Karate Spring Integration
(1 answer)
Closed 1 year ago.
We have a Spring Boot project which uses an application.yml file to configure the spring context for things like datasource, rabbitmq etc.
The YAML file can be loaded in the karate-config.js to pick-up the baseUrl and that works fine.
function fn() {
var env = karate.env; // get system property 'karate.env'
karate.log('karate.env system property was:', env);
if (!env) {
env = 'dev';
}
karate.log('karate environment set to:', env);
var config = karate.read('classpath:application.yml');
karate.log('baseUrl configured for API tests: '+config.baseUrl)
if (env == 'dev') {
var Factory = Java.type('MockSpringMvcServlet');
karate.configure('httpClientInstance', Factory.getMock());
//var result = karate.callSingle('classpath:demo/headers/common-noheaders.feature', config);
} else if (env == 'stg') {
// customize
} else if (env == 'prod') {
// customize
}
return config;
}
The Mock Spring MVC servlet class taken from the karate mock servlet demo github project:
/**
* #author pthomas3
*/
public class MockSpringMvcServlet extends MockHttpClient {
private final Servlet servlet;
private final ServletContext servletContext;
public MockSpringMvcServlet(Servlet servlet, ServletContext servletContext) {
this.servlet = servlet;
this.servletContext = servletContext;
}
#Override
protected Servlet getServlet(HttpRequestBuilder request) {
return servlet;
}
#Override
protected ServletContext getServletContext() {
return servletContext;
}
private static final ServletContext SERVLET_CONTEXT = new MockServletContext();
private static final Servlet SERVLET;
static {
SERVLET = initServlet();
}
private static Servlet initServlet() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(MockConfig.class);
context.setServletContext(SERVLET_CONTEXT);
DispatcherServlet servlet = new DispatcherServlet(context);
ServletConfig servletConfig = new MockServletConfig();
try {
servlet.init(servletConfig);
} catch (Exception e) {
throw new RuntimeException(e);
}
return servlet;
}
public static MockSpringMvcServlet getMock() {
return new MockSpringMvcServlet(SERVLET, SERVLET_CONTEXT);
}
}
However, the MockConfig.class fails on the EnableAutoConfiguration annotation:
#Configuration
#EnableAutoConfiguration
// #PropertySource("classpath:application.yml") // only for key/value pair .properties files and not YAML
public class MockConfig {
// Global Exception Handler ...
// Services ...
// Controllers ...
#Bean
public NumbersAPI numbersAPI() {
return new NumbersAPI();
}
}
The exception is:
2019-04-23 15:13:21.297 INFO --- [ main] com.intuit.karate : karate.env system property was: null
2019-04-23 15:13:21.306 INFO --- [ main] com.intuit.karate : karate environment set to: dev
2019-04-23 15:13:21.429 INFO --- [ main] com.intuit.karate : baseUrl configured for API tests: http://localhost:50000
2019-04-23 15:13:21.469 INFO --- [ main] o.s.mock.web.MockServletContext : Initializing Spring FrameworkServlet ''
2019-04-23 15:13:21.469 INFO --- [ main] o.s.web.servlet.DispatcherServlet : FrameworkServlet '': initialization started
2019-04-23 15:13:21.496 INFO --- [ main] .s.AnnotationConfigWebApplicationContext : Refreshing WebApplicationContext for namespace '-servlet': startup date [Tue Apr 23 15:13:21 EDT 2019]; root of context hierarchy
2019-04-23 15:13:21.535 INFO --- [ main] .s.AnnotationConfigWebApplicationContext : Registering annotated classes: [class MockConfig]
2019-04-23 15:13:22.215 INFO --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Dbcp2; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Dbcp2.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Tomcat; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]]
2019-04-23 15:13:22.330 WARN --- [ main] o.s.b.a.AutoConfigurationPackages : #EnableAutoConfiguration was declared on a class in the default package. Automatic #Repository and #Entity scanning is not enabled.
2019-04-23 15:13:22.714 INFO --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration' of type [org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration$$EnhancerBySpringCGLIB$$cafe2407] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-04-23 15:13:23.212 WARN --- [ main] .s.AnnotationConfigWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is 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).
2019-04-23 15:13:23.215 ERROR --- [ main] o.s.web.servlet.DispatcherServlet : Context initialization failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is 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).
I've used the documentation from the karate mock-servlet github project as guidance to make other karate tests work successfully, but I don't know how to configure the spring context for our karate tests using an application YAML file.
The #PropertySource only supports properties files as you already found out.
Have a look at the following SOF question:
Spring #PropertySource using YAML
Hope this helps.
I was able to get the application.yml file to be respected and loaded by Spring by making the following changes:
Add a YamlPropertySourceFactory util class to the test package:
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class YamlPropertySourceFactory implements PropertySourceFactory {
#Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
Properties propertiesFromYaml = loadYamlIntoProperties(resource);
String sourceName = name != null ? name : resource.getResource().getFilename();
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
}
private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
try {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
return factory.getObject();
} catch (IllegalStateException e) {
// for ignoreResourceNotFound
Throwable cause = e.getCause();
if (cause instanceof FileNotFoundException)
throw (FileNotFoundException) e.getCause();
throw e;
}
}
}
and
Referencing the above in the #PropertySource annotation in the MockConfig class as follows:
#Configuration
#EnableAutoConfiguration
#PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:application.yml")
public class MockConfig {
// Global Exception Handler ...
#Bean
public ExampleAPIExceptionHandler exampleAPIExceptionHandler() {
return new ExampleAPIExceptionHandler();
}
// Services ...
// Controllers ...
#Bean
public NumbersAPI numbersAPI() {
return new NumbersAPI();
}
}
The Spring context loads and all karate tests pass.
If there is a simpler way to load a YAML file as a Spring context using Karate, then please post it. For now, this will work.
Reference: Use #PropertySource with YAML files
I have a spring batch written using Spring boot. My batch only reads from MongoDB and prints the record.
I'm not using any SQL DB nor have any dependencies declared in project but While running it I'm getting below exception:
s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'batchConfigurer' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchConfigurerConfiguration$JdbcBatchConfiguration.class]: Unsatisfied dependency expressed through method 'batchConfigurer' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-06-01 10:43:39.485 ERROR 15104 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 1 of method batchConfigurer in org.springframework.boot.autoconfigure.batch.BatchConfigurerConfiguration$JdbcBatchConfiguration required a bean of type 'javax.sql.DataSource' that could not be found.
- Bean method 'dataSource' not loaded because #ConditionalOnProperty (spring.datasource.jndi-name) did not find property 'jndi-name'
- Bean method 'dataSource' not loaded because #ConditionalOnClass did not find required class 'javax.transaction.TransactionManager'
Action:
Consider revisiting the conditions above or defining a bean of type 'javax.sql.DataSource' in your configuration.
In my pom.xml I've added below dependancies:
spring-boot-starter-batch
spring-boot-starter-data-mongodb
spring-boot-starter-test
spring-batch-test
Here's my batch configuration class:
#Configuration
#EnableBatchProcessing
public class BatchConfig {
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Autowired
private MongoTemplate mongoTemplate;
#Bean
public Job job() throws Exception {
return jobBuilderFactory.get("job1").flow(step1()).end().build();
}
#Bean
public Step step1() throws Exception {
return stepBuilderFactory.get("step1").<BasicDBObject, BasicDBObject>chunk(10).reader(reader())
.writer(writer()).build();
}
#Bean
public ItemReader<BasicDBObject> reader() {
MongoItemReader<BasicDBObject> reader = new MongoItemReader<BasicDBObject>();
reader.setTemplate(mongoTemplate);
reader.setCollection("test");
reader.setQuery("{'status':1}");
reader.setSort(new HashMap<String, Sort.Direction>() {
{
put("_id", Direction.ASC);
}
});
reader.setTargetType((Class<? extends BasicDBObject>) BasicDBObject.class);
return reader;
}
public ItemWriter<BasicDBObject> writer() {
MongoItemWriter<BasicDBObject> writer = new MongoItemWriter<BasicDBObject>();
return writer;
}
}
Here's is my launcher class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class MyBatchApplication {
...
}
Spring Batch requires the use of a relational data store for the job repository. Spring Boot enforces that fact. In order to fix this, you'll need to add an in memory database or create your own BatchConfigurer that uses the Map based repository. For the record, the recommended approach is to add an in memory database (HSQLDB/H2/etc).
I'm giving Kotlin a whirl and was converting the test below that was running fine in Java to Kotlin. After converting the test using the IntelliJ conversion tool I tried to run it but I got this error:
22:32:19.476 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class com.test.app.web.DeveloperControllerTest]
22:32:19.486 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
22:32:19.494 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
22:32:19.517 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.test.app.web.DeveloperControllerTest] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
22:32:19.539 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither #ContextConfiguration nor #ContextHierarchy found for test class [com.test.app.web.DeveloperControllerTest], using SpringBootContextLoader
22:32:19.543 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.test.app.web.DeveloperControllerTest]: class path resource [com/test/app/web/DeveloperControllerTest-context.xml] does not exist
22:32:19.544 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.test.app.web.DeveloperControllerTest]: class path resource [com/test/app/web/DeveloperControllerTestContext.groovy] does not exist
22:32:19.544 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.test.app.web.DeveloperControllerTest]: no resource found for suffixes {-context.xml, Context.groovy}.
22:32:19.545 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.test.app.web.DeveloperControllerTest]: DeveloperControllerTest does not declare any static, non-private, non-final, nested classes annotated with #Configuration.
java.lang.StackOverflowError
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
at java.util.concurrent.ConcurrentHashMap.containsKey(ConcurrentHashMap.java:964)
at java.lang.reflect.WeakCache.containsValue(WeakCache.java:175)
at java.lang.reflect.Proxy.isProxyClass(Proxy.java:791)
at java.lang.reflect.Proxy.getInvocationHandler(Proxy.java:815)
at sun.reflect.annotation.AnnotationInvocationHandler.asOneOfUs(AnnotationInvocationHandler.java:226)
at sun.reflect.annotation.AnnotationInvocationHandler.equalsImpl(AnnotationInvocationHandler.java:201)
at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:64)
at com.sun.proxy.$Proxy13.equals(Unknown Source)
at java.util.HashMap.putVal(HashMap.java:634)
at java.util.HashMap.put(HashMap.java:611)
at java.util.HashSet.add(HashSet.java:219)
at org.springframework.boot.test.context.ImportsContextCustomizer$ContextCustomizerKey.collectElementAnnotations(ImportsContextCustomizer.java:239)
at org.springframework.boot.test.context.ImportsContextCustomizer$ContextCustomizerKey.collectClassAnnotations(ImportsContextCustomizer.java:226)
Java test:
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
public class DeveloperControllerTest {
#Autowired
private MockMvc mvc;
#Test
public void createNewDeveloper() throws Exception {
mvc.perform(
post("/api/v1/developers")
.param("username", "boaty")
.param("email", "boaty#mcboatface.org")
.param("password", "123loveboats")
.param("passwordConfirmation", "123loveboats")
).andExpect(status().isCreated());
}
}
Converted to Kotlin:
#RunWith(SpringRunner::class)
#SpringBootTest
#AutoConfigureMockMvc
class DeveloperControllerTest {
#Autowired
lateinit var mvc: MockMvc
#Test
#Throws(Exception::class)
fun createNewDeveloper() {
mvc.perform(
post("/api/v1/developers")
.param("username", "boaty")
.param("email", "boaty#mcboatface.org")
.param("password", "123loveboats")
.param("passwordConfirmation", "123loveboats"))
.andExpect(status().isCreated)
}
}
What I've noticed with this is that if I remove the annotation AutoConfigureMockMvc Spring will boot and try to run, but it'll fail because it can't autowire MockMvc.
I'm using Kotlin 1.0.1-2 together with Spring Boot 1.4.0-M2.
try adding
#ComponentScan(basePackages = arrayOf("YourAppBasePackage"))
#SpringBootTest(classes = arrayOf(MyExampleApplication::class))
This solved the issue for me
The stack overflow is occurring when Spring Boot attempts to introspect the annotations on DeveloperControllerTest.
DeveloperControllerTest is annotated with kotlin.Metadata. Metadata is annotated with kotlin.annotation.Retention. Retention is annotated with kotlin.annotation.Target and Target is annotated with itself. Target being annotated with itself is the cause of the stack overflowing.
It is legal, although probably quite unusual, for an annotation to be used to annotate itself. Spring Boot should probably be more defensive.
I'm trying to create Vaadin 7.5.5 app with add-on com.vaadin.vaadin-spring.1.0.0. This is not Spring Boot app, but deploy-able war with Spring context which should bootstrap Vaadin.
The error is:
Scope 'vaadin-view' is not active for the current thread
nested exception is java.lang.IllegalStateException: No active view
Here is full error trace:
2015-09-25 21:27:33 DEBUG DefaultListableBeanFactory:448 - Creating instance of bean 'vaadinSpringApplication'
2015-09-25 21:27:33 DEBUG InjectionMetadata:72 - Registered injected element on class [com.myapp.vaadin.demo.VaadinSpringApplication]: AutowiredFieldElement for com.vaadin.spring.navigator.SpringViewProvider com.myapp.vaadin.demo.VaadinSpringApplication.viewProvider
2015-09-25 21:27:33 DEBUG InjectionMetadata:72 - Registered injected element on class [com.myapp.vaadin.demo.VaadinSpringApplication]: AutowiredFieldElement for com.myapp.vaadin.demo.DefaultView com.myapp.vaadin.demo.VaadinSpringApplication.defaultView
2015-09-25 21:27:33 DEBUG InjectionMetadata:72 - Registered injected element on class [com.myapp.vaadin.demo.VaadinSpringApplication]: AutowiredFieldElement for com.myapp.vaadin.demo.SpringLoginView com.myapp.vaadin.demo.VaadinSpringApplication.springLoginView
2015-09-25 21:27:33 DEBUG InjectionMetadata:72 - Registered injected element on class [com.myapp.vaadin.demo.VaadinSpringApplication]: AutowiredFieldElement for com.myapp.vaadin.demo.SpringMainView com.myapp.vaadin.demo.VaadinSpringApplication.springMainView
2015-09-25 21:27:33 DEBUG InjectionMetadata:86 - Processing injected element of bean 'vaadinSpringApplication': AutowiredFieldElement for com.vaadin.spring.navigator.SpringViewProvider com.myapp.vaadin.demo.VaadinSpringApplication.viewProvider
2015-09-25 21:27:33 DEBUG DefaultListableBeanFactory:250 - Returning cached instance of singleton bean 'viewProvider'
2015-09-25 21:27:33 DEBUG AutowiredAnnotationBeanPostProcessor:490 - Autowiring by type from bean name 'vaadinSpringApplication' to bean named 'viewProvider'
2015-09-25 21:27:33 DEBUG InjectionMetadata:86 - Processing injected element of bean 'vaadinSpringApplication': AutowiredFieldElement for com.myapp.vaadin.demo.DefaultView com.myapp.vaadin.demo.VaadinSpringApplication.defaultView
2015-09-25 21:27:33 DEBUG DefaultListableBeanFactory:448 - Creating instance of bean 'viewCache'
2015-09-25 21:27:33 DEBUG DefaultListableBeanFactory:250 - Returning cached instance of singleton bean 'com.vaadin.spring.VaadinConfiguration'
2015-09-25 21:27:33 DEBUG CommonAnnotationBeanPostProcessor:216 - Found destroy method on class [com.vaadin.spring.internal.DefaultViewCache]: void com.vaadin.spring.internal.DefaultViewCache.destroy()
2015-09-25 21:27:33 DEBUG CommonAnnotationBeanPostProcessor:288 - Registered destroy method on class [com.vaadin.spring.internal.DefaultViewCache]: org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement#5cd39ffa
2015-09-25 21:27:33 DEBUG DefaultListableBeanFactory:484 - Finished creating instance of bean 'viewCache'
Sep 25, 2015 9:27:33 PM com.vaadin.server.DefaultErrorHandler doDefault
SEVERE:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'vaadinSpringApplication': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myapp.vaadin.demo.DefaultView com.myapp.vaadin.demo.VaadinSpringApplication.defaultView; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultView': Scope 'vaadin-view' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No active view
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:344)
at com.vaadin.spring.internal.BeanStore.create(BeanStore.java:71)
at com.vaadin.spring.internal.UIScopeImpl$UIBeanStore.create(UIScopeImpl.java:279)
at com.vaadin.spring.internal.BeanStore.get(BeanStore.java:62)
at com.vaadin.spring.internal.SessionLockingBeanStore.get(SessionLockingBeanStore.java:46)
at com.vaadin.spring.internal.UIScopeImpl.get(UIScopeImpl.java:81)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:219)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1057)
at com.vaadin.spring.server.SpringUIProvider.createInstance(SpringUIProvider.java:172)
at com.vaadin.server.communication.UIInitHandler.getBrowserDetailsUI(UIInitHandler.java:191)
at com.vaadin.server.communication.UIInitHandler.synchronizedHandleRequest(UIInitHandler.java:74)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:351)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
Here is application main class:
#Theme("valo")
#SpringUI
public class VaadinSpringApplication extends UI {
#Configuration
#EnableVaadin
public static class VaadinSpringApplicationConfiguration {}
#Autowired
SpringViewProvider viewProvider;
#Override
protected void init(VaadinRequest request) {
Navigator navigator = new Navigator(this, this);
navigator.addProvider(viewProvider);
navigator.navigateTo(DefaultView.NAME);
}
}
DefaultView.java
#SpringComponent
#SpringView(name = DefaultView.NAME)
public class DefaultView extends CustomComponent implements View {
public static final String NAME = "defaultView";
#Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
Button button = new Button("Click Me");
setCompositionRoot(layout);
}
}
As you may see from logs, spring beans (viewCache, defaultView, springLoginView, springMainView) has been created. But once I've tried to inject it into main class - got the error "Scope 'vaadin-view' is not active for the current thread".
Please advice. Thank you.
I am using Spring 3.2 DispatcherServlet. I am looking for an initialization hook that takes place after the DispatcherServlet initialization completes; either a standard Spring solution or servlet solution. Any suggestions?
As a point of reference, the final logging statements after servlet startup follow. I want my initialization method to execute right after the configured successfully log statement.
DEBUG o.s.w.s.DispatcherServlet - Published WebApplicationContext of servlet 'mySpringDispatcherServlet' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.mySpringDispatcherServlet]
INFO o.s.w.s.DispatcherServlet - FrameworkServlet 'mySpringDispatcherServlet': initialization completed in 5000 ms
DEBUG o.s.w.s.DispatcherServlet - Servlet 'mySpringDispatcherServlet' configured successfully
From my research, so far the following have not had the desired effect:
Extending ContextLoaderListener/implementing ServletContextListener per this answer.
Implementing WebApplicationInitializer per the javaoc.
My beans use #PostConstruct successfully; I'm looking for a Servlet or container level hook that will be executed essentially after the container initializes and post-processes the beans.
The root issue was that I couldn't override the final method HttpsServlet.init(). I found a nearby #Override-able method in DispatcherServlet.initWebApplicationContext that ensured my beans and context were fully initialized:
#Override
protected WebApplicationContext initWebApplicationContext()
{
WebApplicationContext wac = super.initWebApplicationContext();
// do stuff with initialized Foo beans via:
// wac.getBean(Foo.class);
return result;
}
From Spring's Standard and Custom Events.
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
#Component
public class ApplicationContextListener implements
ApplicationListener<ContextRefreshedEvent> {
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("ApplicationContext was initialized or refreshed: "
+ event.getApplicationContext().getDisplayName());
}
}
The event above will be fired when the DispatcherServlet is initialized, such as when it prints:
INFO org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'ServletName': initialization completed in 1234 ms
You can implement ApplicationListener<ContextStartedEvent> within your application context. This event listener will then be called once for your root context and once for each servlet context.
public class StartupListener implements ApplicationListener<ContextStartedEvent> {
public void onApplicationEvent(ContextStartedEvent event) {
ApplicationContext context = (ApplicationContext) event.getSource();
System.out.println("Context '" + context.getDisplayName() + "' started.");
}
}
If you define this listener within your servlet context, it should be called just once for the servlet context intself.
try this, change your port number.
In my case i changed from server.port=8001 to server.port=8002