I am trying to create a basic application that would use Spring Boot
and reactive programming
(and without web.xml
)
This is my servlet
public class RootServlet extends ServletHttpHandlerAdapter {
public RootServlet(HttpHandler httpHandler) {
super(httpHandler);
}
public RootServlet() {
this(WebHttpHandlerBuilder
.webHandler(toHttpHandler(routingFunction()))
.build()
);
}
private static RouterFunction<?> routingFunction() {
return route(GET("/ping"), new PingHandlerFunction());
}
}
This is my handler function
public class PingHandlerFunction implements HandlerFunction<ServerResponse> {
@Override
public Mono<ServerResponse> handle(ServerRequest request) {
return ok().body(fromObject("true"));
}
}
And this is my application
@SpringBootApplication
@ComponentScan(basePackages = { "com.lapots.tree.model" })
public class TreeModelApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(TreeModelApplication.class, args);
}
@Bean
public ServletRegistrationBean servletRegistrationBean() throws Exception {
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new RootServlet(), "/");
registrationBean.setLoadOnStartup(1);
registrationBean.setAsyncSupported(true);
return registrationBean;
}
}
I put properties into resources/application.properties
server.port=8080
logging.level.root=INFO
spring.application.name=tree-model-test
To start web application I use gretty
plugin
apply plugin: 'war'
apply plugin: 'org.akhikhl.gretty'
gretty {
springBoot = true
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-parent:$springBootVersion"
compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion"
compile "org.springframework.boot:spring-boot-starter-webflux:$springBootVersion"
providedCompile "javax.servlet:javax.servlet-api:$servetApiVersion"
}
Where springBootVersion=2.0.0.BUILD-SNAPSHOT
and servletApiVersion=4.0.0-b03
But when I try to start application using gradle jettyRun
I get this exception
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/context/web/SpringBootServletInitializer
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at org.eclipse.jetty.webapp.WebAppClassLoader.findClass(WebAppClassLoader.java:510)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:441)
at org.akhikhl.gretty.FilteringClassLoader.loadClass(FilteringClassLoader.java:62)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:403)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at java_lang_Class$forName.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:141)
at org.akhikhl.gretty.JettyServerConfigurer.createContext(JettyServerConfigurer.groovy:118)
at org.akhikhl.gretty.JettyServerConfigurer$createContext$0.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:190)
at org.akhikhl.gretty.JettyServerConfigurer.createAndConfigureServer(JettyServerConfigurer.groovy:68)
at org.akhikhl.gretty.JettyServeurer.createAndConfigureServer(JettyServerConfigurer.groovy)
at org.akhikhl.gretty.JettyServerConfigurer$createAndConfigureServer.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at org.akhikhl.gretty.JettyServerManager.startServer(JettyServerManager.groovy:41)
at org.akhikhl.gretty.ServerManager$startServer$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at org.akhikhl.gretty.Runner.run(Runner.groovy:117)
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:497)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSi
te.java:210)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:71)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at org.akhikhl.gretty.Runner.main(Runner.groovy:44)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.web.SpringBootServletInitializer
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(r.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:450)
at org.akhikhl.gretty.FilteringClassLoader.loadClass(FilteringClassLoader.java:62)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:403)
... 46 more
Exception in thread "Thread-3" org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0_60\b
in\java.exe'' finished with non-zero exit value 1
at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:366)
at org.gradle.process.internal.DefaultJavaExecAction.execute(DefaultJavaExecAction.java:31)
at org.gradle.api.internal.file.DefaultFileOperations.javaexec(DefaultFileOperations.java:159)
at org.gradle.api.internal.project.AbstractProject.javaexec(AbstractProject.java:784)
at org.gradle.api.internal.project.AbstractProject.javaexec(AbstractProject.java:780)
at org.gradle.api.Project$javaexec$6.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.akhikhl.gretty.DefaultLauncher.javaExec(DefaultLauncher.groovy:89)
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:497)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:382)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1015)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at org.akhikhl.gretty.LauncherBase$_launchThread_closure4.doCall(LauncherBase.groovy:256)
at org.akhikhl.gretty.LauncherBase$_launchThread_closure4.doCall(LauncherBase.groovy)
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:497)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:292)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1015)
at groovy.lang.Closure.call(Closure.java:423)
at groovy.lang.Closure.call(Closure.java:417)
at groovy.lang.Closure.run(Closure.java:504)
at java.lang.Thread.run(Thread.java:745)
What is the problem?
After the discussion with @KumareshBabu we found out that in earlier versions of spring boot
the class SpringBootServletInitializer
was located in org.springframework.boot.context.web
while now it is located in org.springframework.boot.web.servlet.support
package.
So I decided to use workaround gretty/issue-334