We're running GraphQL sample Java application in WebLogic 12c, but encountered some errors with servlet during startup.
The servlet was configured and register our servlets using a ServletRegistrationBean as below:
#Configuration
#ConditionalOnWebApplication
#ConditionalOnClass(DispatcherServlet.class)
#ConditionalOnBean({GraphQLSchema.class, GraphQLSchemaProvider.class})
#ConditionalOnProperty(value = "graphql.servlet.enabled", havingValue = "true", matchIfMissing = true)
#AutoConfigureAfter({GraphQLJavaToolsAutoConfiguration.class, SpringGraphQLCommonAutoConfiguration.class})
#EnableConfigurationProperties(GraphQLServletProperties.class)
public class GraphQLWebAutoConfiguration {
...
#Bean
#ConditionalOnMissingBean
public GraphQLServlet graphQLServlet(GraphQLSchemaProvider schemaProvider, ExecutionStrategyProvider executionStrategyProvider) {
return new SimpleGraphQLServlet(schemaProvider, executionStrategyProvider, listeners, instrumentation, errorHandler, contextBuilder);
}
#Bean
ServletRegistrationBean graphQLServletRegistrationBean(GraphQLServlet servlet) {
ServletRegistrationBean bean = new ServletRegistrationBean(servlet, graphQLServletProperties.getServletMapping());
bean.setLoadOnStartup(1);
return bean;
}
}
In the weblogic server log, it prints out errors:
<Oct 2, 2017 1:51:28 PM SGT> <Error> <HTTP> <BEA-101125> <[ServletContext#933807824[app:CPRES module:CPRES path:null spec-version:3.1]] Error occurred while instantiating servlet: "simpleGraphQLServlet".
java.lang.InstantiationException: graphql.servlet.SimpleGraphQLServlet
at java.lang.Class.newInstance(Class.java:427)
at weblogic.servlet.internal.WebComponentContributor.getNewInstance(WebComponentContributor.java:252)
at weblogic.servlet.internal.WebComponentContributor.getNewInstance(WebComponentContributor.java:245)
at weblogic.servlet.internal.WebComponentContributor.createServletInstance(WebComponentContributor.java:274)
at weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.newServletInstanceIfNecessary(StubSecurityHelper.java:365)
Truncated. see log file for complete stacktrace
Caused By: java.lang.NoSuchMethodException: graphql.servlet.SimpleGraphQLServlet.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
at weblogic.servlet.internal.WebComponentContributor.getNewInstance(WebComponentContributor.java:252)
at weblogic.servlet.internal.WebComponentContributor.getNewInstance(WebComponentContributor.java:245)
at weblogic.servlet.internal.WebComponentContributor.createServletInstance(WebComponentContributor.java:274)
Truncated. see log file for complete stacktrace
>
<Oct 2, 2017 1:51:28 PM SGT> <Error> <HTTP> <BEA-101216> <Servlet: "simpleGraphQLServlet" failed to preload on startup in Web application: "CPRES".
javax.servlet.ServletException: Servlet class: 'graphql.servlet.SimpleGraphQLServlet' couldn't be instantiated
at weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.run(StubSecurityHelper.java:326)
at weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.run(StubSecurityHelper.java:294)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:196)
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
Truncated. see log file for complete stacktrace
>
<Oct 2, 2017 1:51:29 PM SGT> <Error> <Deployer> <BEA-149265> <Failure occurred in the execution of deployment request with ID "19094957742917053" for task "130" on [partition-name: DOMAIN]. Error is: "weblogic.application.ModuleException: javax.servlet.ServletException: Servlet class: 'graphql.servlet.SimpleGraphQLServlet' couldn't be instantiated"
weblogic.application.ModuleException: javax.servlet.ServletException: Servlet class: 'graphql.servlet.SimpleGraphQLServlet' couldn't be instantiated
It looks that the weblogic is trying to create a new servlet instance instead of the ServletBean SimpleGraphQLServlet created and managed by Spring context.
Any advance? Thanks.
A walkaround solution is to write a Servlet wrapper class like this:
public class DelegateGraphQLServlet extends HttpServlet {
protected GraphQLServlet graphQLServlet;
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
ApplicationContext ac = (ApplicationContext) servletConfig.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
this.graphQLServlet = (GraphQLServlet)ac.getBean("graphQLServlet");
}
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
graphQLServlet.service(req, res);
}
}
Related
I have a problem with a realization of Spring in Action example of a programme.
Test class:
#Test
public void testBasicUsage() throws PerformanceException {
ApplicationContext context = new ClassPathXmlApplicationContext("/**/java/springidol/spring-idol.xml");
Performer performer = (Performer) context.getBean("juggler");
performer.perform();
}
Juggler class that should be configured by Spring
public class Juggler implements Performer {
private int beanBags = 3;
public Juggler() {
}
public Juggler(int beanBags) {
this.beanBags = beanBags;
}
#Override
public void perform() throws PerformanceException {
System.out.println("JUGGLING " + beanBags + " BEANBAGS");
}
}
And xml configuration file for this bean:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="juggler"
class="springidol.Juggler">
<constructor-arg value="15"/>
</bean>
</beans>
this code throw NoSuchBeanDefinitionException:
Aug 30, 2018 1:20:43 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext#1c53fd30: startup date [Thu Aug 30 13:20:43 EEST 2018]; root of context hierarchy
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'juggler' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:686)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089)
at springidol.TestMain.testBasicUsage(TestMain.java:12)
I think the class-path you provided in ClassPathXmlApplicationContextshould be where the XML configuration in present. The files on classpaths are automatically scanned, we just need to provide folder paths.
Try below in Test class with changes:
ApplicationContext context = new ClassPathXmlApplicationContext("java/springidol/spring-idol.xml");
Reference: Spring Source
I'm new to spring boot and i'm very much interested to learn this technology. Here is the issue, I got one configuration file with #configuration tag. so i can't run the application when i try to add #enablemvc annotation or if i add new file with #enablemvc annoation in the spring boot application. i really appreciate if some one can help me with thisss.
log
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is org.springframework.beans.factory.BeanInitializationException: Failed to init ResourceHttpRequestHandler; nested exception is java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/], class path resource [images/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#39e6b948]]] does not run in a WebApplicationContext but in: org.springframework.context.annotation.AnnotationConfigApplicationContext#19b44076: startup date [Sat Feb 10 09:34:19 EST 2018]; root of context hierarchy
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.builder.SpringApplicationBuilder.configureAsChildIfNecessary(SpringApplicationBuilder.java:147) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at com.boot.main.ClientMain.main(ClientMain.java:31) [bin/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_131]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.9.RELEASE.jar:1.5.9.RELEASE]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is org.springframework.beans.factory.BeanInitializationException: Failed to init ResourceHttpRequestHandler; nested exception is java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/], class path resource [images/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#39e6b948]]] does not run in a WebApplicationContext but in: org.springframework.context.annotation.AnnotationConfigApplicationContext#19b44076: startup date [Sat Feb 10 09:34:19 EST 2018]; root of context hierarchy
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
... 23 common frames omitted
Caused by: org.springframework.beans.factory.BeanInitializationException: Failed to init ResourceHttpRequestHandler; nested exception is java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/], class path resource [images/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#39e6b948]]] does not run in a WebApplicationContext but in: org.springframework.context.annotation.AnnotationConfigApplicationContext#19b44076: startup date [Sat Feb 10 09:34:19 EST 2018]; root of context hierarchy
at org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry.getHandlerMapping(ResourceHandlerRegistry.java:150) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.resourceHandlerMapping(WebMvcConfigurationSupport.java:446) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$7c7bc0fe.CGLIB$resourceHandlerMapping$28(<generated>) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$7c7bc0fe$$FastClassBySpringCGLIB$$d042f6eb.invoke(<generated>) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$7c7bc0fe.resourceHandlerMapping(<generated>) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_131]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
... 24 common frames omitted
Caused by: java.lang.IllegalStateException: WebApplicationObjectSupport instance [ResourceHttpRequestHandler [locations=[class path resource [resources/], class path resource [images/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#39e6b948]]] does not run in a WebApplicationContext but in: org.springframework.context.annotation.AnnotationConfigApplicationContext#19b44076: startup date [Sat Feb 10 09:34:19 EST 2018]; root of context hierarchy
at org.springframework.web.context.support.WebApplicationObjectSupport.getWebApplicationContext(WebApplicationObjectSupport.java:112) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.context.support.WebApplicationObjectSupport.getServletContext(WebApplicationObjectSupport.java:128) ~[spring-web-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.initContentNegotiationStrategy(ResourceHttpRequestHandler.java:306) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.afterPropertiesSet(ResourceHttpRequestHandler.java:268) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry.getHandlerMapping(ResourceHandlerRegistry.java:147) ~[spring-webmvc-4.3.12.RELEASE.jar:4.3.12.RELEASE]
... 35 common frames omitted
AutoConfiguration.java
#Configuration
//#EnableAutoConfiguration
#ConditionalOnClass(MyClass.class)
#EnableConfigurationProperties(MyProperties.class)
#ComponentScan({ "com.boot", "com.jspClient" })
#SpringBootApplication
public class AutoConfiguration {
private static Log log = LogFactory.getLog(AutoConfiguration.class);
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
/*#Bean
public UrlBasedViewResolver urlBasedViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}*/
//http://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/simple-mapping-exception-resolver/
//https://github.com/paulc4/mvc-exceptions/blob/master/src/main/java/demo/config/ExceptionConfiguration.java
#Bean
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties errorMaps = new Properties();
errorMaps.setProperty(UserNotFoundException.class.getName(), "myError");
errorMaps.setProperty("Exception", "generic_error");
resolver.setExceptionMappings(errorMaps);
resolver.setDefaultErrorView("generic_error");
resolver.setExceptionAttribute("exc");
return resolver;
}
#Bean
WebMvcConfigurer configurer () {
return new WebMvcConfigurerAdapter() {
#Override
public void addResourceHandlers (ResourceHandlerRegistry registry) {
ResourceHandlerRegistration resourceRegistration = registry
.addResourceHandler("/pages/**")
.addResourceLocations("/resources/","classpath:/images/") //Configuring Multiple Locations for a Resource
.setCachePeriod(3600); //The resources served will be cached in the browser for 3600 seconds
registry.addResourceHandler("resources/**").addResourceLocations("/resources/");
//registry.addResourceHandler("/css/**").addResourceLocations("/css/");
//registry.addResourceHandler("/img/**").addResourceLocations("/img/");
//registry.addResourceHandler("/js/**").addResourceLocations("/js/");
}
};
}
}
AppConfig.java
#Configuration
#ComponentScan("com.boot.controllers")
#EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties errorMaps = new Properties();
errorMaps.setProperty("ElectricityNotFoundException", "error");
errorMaps.setProperty("NullPointerException", "error");
resolver.setExceptionMappings(errorMaps);
resolver.setDefaultErrorView("globalerror");
resolver.setExceptionAttribute("exc");
return resolver;
}
}
WebAppInitializer.java
public class WebAppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(servletContext);
Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
dynamic.addMapping("/");
dynamic.setLoadOnStartup(1);
}
}
ClientMain.java
#ComponentScan("com.boot") // to scan controller under com.boot -> com.boot.controllers
#SpringBootApplication
public class ClientMain {
private static SpringApplicationBuilder start(Class<?>... sources) {
return new SpringApplicationBuilder(ClientMain.class)
.child(sources);
}
public static void main(String[] args) throws Exception {
// using just Spring alone
/*ApplicationContext context = new AnnotationConfigApplicationContext(AutoConfiguration.class);
}
}
JspClientMain.java
#ComponentScan("com.boot")
#SpringBootApplication
public class JspClientMain {
public static void main(String[] args) {
SpringApplication.run(JspClientMain.class, args);
}
}
In general, the #EnableWebMvc should not be used in Spring boot applications. I quote an article by Boz Hogan:
It turns out that Spring Boot doesn’t mix well with the standard Spring MVC #EnableWebMvc. What happens when you add the annotation is that Spring Boot's autoconfiguration is disabled.
The bad part (that wasted me a few hours) is that in no guide you can find that explicitly stated. (...)
Here's a quote from the Spring Boot documentation:
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own #Configuration class of type WebMvcConfigurer but without #EnableWebMvc. (...)
If you want to take complete control of Spring MVC, you can add your own #Configuration annotated with #EnableWebMvc.
So, to use #EnableWebMvc in a Spring Boot app, you need to take complete control of Spring MVC—I read that as you need to be a Spring wiz.
We had a problem with a Spring boot 1.5.9 application that had a dependency to a shared lib that contained a class annotated with #EnableWebMvc. Removing the annotation solved the problem.
It seems the issue is caused by mixing two different kind of initializers i.e WebApplicationInitializer and ApplicationContextInitializer.
Both WebApplicationInitializer and ApplicationContextInitializer serve fairly different purposes.
The WebApplicationInitializer is used by a Servlet Container at startup of the web application and provides a way for programmatic creating a web application(replacement for a web.xml file),
ApplicationContextInitializer provides a hook to configure the Spring application context before it gets fully created.
For a non spring boot application/normal spring mvc app it is programmatic configuration of web.xml. like you have done in your code in WebAppInitializer.java
public class WebAppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws
ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(servletContext);
Dynamic dynamic = servletContext.addServlet("dispatcher", new
DispatcherServlet(ctx));
dynamic.addMapping("/");
dynamic.setLoadOnStartup(1);
}
}
ApplicationContextInitializer is essentially code that gets executed before the Spring application context gets completely created. A good use case for using an ApplicationContextInitializer would be to set a Spring environment profile programmatically, along these lines.
For Spring-Boot based application then registering an ApplicationContextInitializer could be done like below:
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class SampleWebApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SampleWebApplication.class)
.initializers(new DemoApplicationContextInitializer())
.run(args);
}
}
public class DemoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext ac) {
ConfigurableEnvironment appEnvironment = ac.getEnvironment();
appEnvironment.addActiveProfile("demo");
}
}
I am in the proces of creating simple CRUD program with Spring data rest Spring data rest,
but I have a problem with security configuration (example was taken from here.
I have a WebAppInitializer:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{JpaRepositoryConfig.class, SecurityConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{CustRepositoryRestMvcConfiguration.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
protected Filter[] getServletFilters() {
return new Filter[]{ new DelegatingFilterProxy("springSecurityFilterChain")};
}
}
I have a next crud repository:
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.rest.repository.annotation.RestResource;
import org.springframework.security.access.prepost.PreAuthorize;
#PreAuthorize("hasRole('ROLE_USER')")
#RestResource(path = "products", rel = "products")
public interface ProductRepository extends PagingAndSortingRepository<Product, Long> {
#PreAuthorize("hasRole('ROLE_ADMIN')")
#Override
Product save(Product s);
#PreAuthorize("hasRole('ROLE_ADMIN')")
#Override
void delete(Long aLong);
}
I have a next security configuration:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("greg").password("turnquist").roles("USER").and()
.withUser("ollie").password("gierke").roles("USER", "ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/products").hasRole("ADMIN")
.antMatchers(HttpMethod.PUT, "/products/**").hasRole("ADMIN")
.antMatchers(HttpMethod.PATCH, "/products/**").hasRole("ADMIN").and()
.csrf().disable();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
I used next version of dependencies:
<java-version>1.7</java-version>
<spring-data-rest-version>1.0.0.RELEASE</spring-data-rest-version>
<spring.version>3.2.2.RELEASE</spring.version>
<org.slf4j-version>1.7.5</org.slf4j-version>
From project configured log4j I am getting these errors:
SEVERE: Error filterStart
org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/admin] startup failed due to previous errors
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationCon
text - Closing Root WebApplicationContext: startup date [Tue Dec 30 00:09:21 EET
2014]; root of context hierarchy
......
DEBUG: org.springframework.beans.factory.support.DisposableBeanAdapter - Invokin
g destroy() on bean with name 'org.springframework.security.config.annotation.au
thentication.configuration.AuthenticationConfiguration'
DEBUG: org.springframework.beans.factory.support.DefaultListableBeanFactory - Re
trieved dependent beans for bean '(inner bean)': [(inner bean), productRepositor
y]
DEBUG: org.springframework.beans.factory.support.DisposableBeanAdapter - Invokin
g destroy() on bean with name 'securityConfig'
From tomcat 7.0.56 localhost log I also have these errors in the logs:
SEVERE: Exception starting filter delegatingFilterProxy
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:568)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1102)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:278)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1121)
at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326)
at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:236)
at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:194)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:109)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4830)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5510)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1083)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1879)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
What is causing the errors in these logs?
When I try to run Spring java annotation based configuration I get that exception trace
Sep 28, 2014 10:24:38 PM
org.springframework.context.support.AbstractApplicationContext
prepareRefresh INFO: Refreshing
org.springframework.context.annotation.AnnotationConfigApplicationContext#20ad9418:
startup date [Sun Sep 28 22:24:38 EET 2014]; root of context hierarchy
Exception in thread "main" java.lang.IllegalStateException: Cannot
load configuration class: com.learn.HelloWorldConfig at
org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:378)
at
org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:263)
at
org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:265)
at
org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:126)
at
org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:609)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at com.learn.MainApp.main(MainApp.java:9) Caused by:
org.springframework.cglib.core.CodeGenerationException:
java.lang.reflect.InvocationTargetException-->null at
org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:237)
at
org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at
org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at
org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(ConfigurationClassEnhancer.java:128)
at
org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:100)
at
org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:368)
... 6 more Caused by: java.lang.reflect.InvocationTargetException 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:483) at
org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:384)
at
org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
... 11 more Caused by: java.lang.SecurityException: class
"com.learn.HelloWorldConfig$$EnhancerBySpringCGLIB$$3f39adab"'s signer
information does not match signer information of other classes in the
same package at
java.lang.ClassLoader.checkCerts(ClassLoader.java:895) at
java.lang.ClassLoader.preDefineClass(ClassLoader.java:665) at
java.lang.ClassLoader.defineClass(ClassLoader.java:758) ... 17 more
HelloWorld.java
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
HelloWorldConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class HelloWorldConfig {
#Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
MainApp.java
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(HelloWorldConfig.class);
ctx.refresh();
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
ctx.close();
System.out.println("Test");
}
}
Why I get that exception ?
Using stock TomEE+, I cannot get a simple JAX-RS resource to work. I constantly get an error of:
Jun 30, 2012 5:09:59 PM org.apache.cxf.jaxrs.utils.ResourceUtils checkMethodDispatcher
WARNING: No resource methods have been found for resource class com.tensorwrench.test.BaseResource
Jun 30, 2012 5:09:59 PM org.apache.cxf.jaxrs.utils.ResourceUtils checkMethodDispatcher
WARNING: No resource methods have been found for resource class com.tensorwrench.test.BaseResource
Jun 30, 2012 5:09:59 PM org.apache.cxf.jaxrs.utils.ResourceUtils checkMethodDispatcher
WARNING: No resource methods have been found for resource class com.tensorwrench.test.BaseResource
Jun 30, 2012 5:09:59 PM org.apache.cxf.jaxrs.AbstractJAXRSFactoryBean checkResources
SEVERE: No resource classes found
Jun 30, 2012 5:09:59 PM org.apache.catalina.startup.HostConfig deployWAR
SEVERE: Error deploying web application archive D:\workspace\api\src\main\catalina_base\webapps\testapi-1.0.war
org.apache.cxf.service.factory.ServiceConstructionException
at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:194)
at org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deploy(CxfRsHttpListener.java:126)
at org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployPojo(CxfRsHttpListener.java:97)
at org.apache.openejb.server.rest.RESTService.deployPojo(RESTService.java:270)
at org.apache.openejb.server.rest.RESTService.afterApplicationCreated(RESTService.java:173)
at org.apache.tomee.webservices.TomeeJaxRsService.afterApplicationCreated(TomeeJaxRsService.java:55)
at org.apache.tomee.catalina.WebDeploymentListeners.afterApplicationCreated(WebDeploymentListeners.java:38)
at org.apache.tomee.catalina.TomcatWebAppBuilder.afterStart(TomcatWebAppBuilder.java:818)
at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:103)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:401)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:168)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:895)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:871)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:962)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1603)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.ws.rs.WebApplicationException
at org.apache.cxf.jaxrs.AbstractJAXRSFactoryBean.checkResources(AbstractJAXRSFactoryBean.java:312)
at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:144)
... 23 more
Resource class:
package com.tensorwrench.test;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
#Path("/test")
public class BaseResource {
#GET #Produces("text/plain") #Path("test") Response helloWorld() {
return Response.ok("Hello world","plain/text").build();
}
#GET #Produces("text/plain") String helloWorld2() {
return "Hello world without path!";
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="api" version="3.0"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd">
<display-name>Service</display-name>
build.gradle:
apply plugin: 'java'
apply plugin: 'war'
repositories { mavenCentral() }
dependencies {
providedCompile 'org.apache.openejb:javaee-api:6.0-4'
}
version = '1.0'
jar {
manifest {
attributes 'Title': 'Services',
'Version': version
}
}
</web-app>
I've tried a number of permutations, adding beans.xml, removing, changing order of the annotations, using different compile dependencies for the Java EE classes. I consistently get this error.
It looks like your resource methods are not public in scope. Try this:
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
#Path("/test")
public class BaseResource {
#GET #Produces("text/plain") #Path("test") public Response helloWorld() {
return Response.ok("Hello world","plain/text").build();
}
#GET #Produces("text/plain") public String helloWorld2() {
return "Hello world without path!";
}
}