问题
I am using Java8 and Spring4.3.1.
I have a Java/Spring application hosting RESTfult services accessed by browser and mobile app clients. Second, I have written a Chat Server that listens for events (socket.io
) from the clients. This Chat Server is running from the classes main
method.
The Chat Server class has a main
method that I want to run, and allow to listen for events when my Spring application starts. Is this possible?
If I run the main
myself, it works, but I want it to start up when I start my Wildfly server that loads the Spring application.
Or is there a better approach? Should the Chat Server not be running from the main
method?
I have the following code:
package com.jobs.spring.configuration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(servletContext);
Dynamic dynamic = servletContext.addServlet("rest", new DispatcherServlet(ctx));
dynamic.addMapping("/*");
dynamic.setLoadOnStartup(1);
try {
com.jobs.spring.chat.Server chatServer = new com.jobs.spring.chat.Server();
chatServer.run(null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
and
public class Server implements CommandLineRunner {
private static final String SERVER = "localhost";
private static final Integer PORT = 3700;
@Override
public void run(String... args) throws Exception {
main(args);
}
public static void main(String[] args) {
...
and get the following error:
18:47:08,142 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 66) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./jbosswildfly: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./jbosswildfly: java.lang.NoClassDefFoundError: Failed to link com/jobs/spring/chat/Server (Module "deployment.jbosswildfly.war:main" from Service Module Loader): org/springframework/boot/CommandLineRunner
Caused by: java.lang.NoClassDefFoundError: Failed to link com/jobs/spring/chat/Server (Module "deployment.jbosswildfly.war:main" from Service Module Loader): org/springframework/boot/CommandLineRunner
回答1:
You could deploy your chat server in Wildfly
, by extending SpringBootServletInitializer
, instead of launching it from a main
.
Documentation: howto-create-a-deployable-war-file
@SpringBootApplication
public class SpringBootApp extends SpringBootServletInitializer{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SpringBootApp.class);
}
//public static void main(String[] args){
// new SpringApplicationBuilder()
// .sources(SpringBootApp.class)
// .run(args);
//}
}
Change the artifact produced to war
, and deploy it normally in wildfly
:
<project>
<packaging>war</packaging>
...
<project>
You may have to exclude tomcat, which is automatically imported with spring-boot-starter-web
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
Spring provided a Spring Boot example of a pom.xml
for wildfly: spring-boot-deployment-test-wildfly
来源:https://stackoverflow.com/questions/39233115/run-a-java-class-from-spring-startup