【问题标题】:Run a Java class from Spring startup从 Spring 启动运行 Java 类
【发布时间】:2017-01-07 01:41:34
【问题描述】:

我正在使用 Java8 和 Spring4.3.1。

我有一个 Java/Spring 应用程序托管浏览器和移动应用程序客户端访问的 RESTfult 服务。其次,我编写了一个聊天服务器来侦听来自客户端的事件 (socket.io)。此聊天服务器从类 main 方法运行。

Chat Server 类有一个我想运行的main 方法,并允许在我的 Spring 应用程序启动时监听事件。这可能吗?

如果我自己运行main,它可以工作,但我希望它在我启动加载 Spring 应用程序的 Wildfly 服务器时启动。

或者有更好的方法吗?聊天服务器不应该从main 方法运行吗?

我有以下代码:

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();
        }
    }
}

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) {
...

并得到以下错误:

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

【问题讨论】:

  • 感觉就像你在这里混合了一大堆不同的启动器模式。该服务器的意图是在 Web 上运行吗?如果不是,为什么是 servlet?如果是这样,那么明显的“侧面”插座是怎么回事?
  • 聊天服务器需要运行以监听事件。我有一个使用 sockets.io 发送消息的 Ionic 移动应用程序。如果我从 cmd 行运行聊天服务器,它可以完美运行,但是我有另一个 Java 应用程序运行带有 RESTful 服务的 Spring。当这个 java 应用程序启动时,我还想启动聊天服务器。 RESTful 服务和聊天服务器都需要从浏览器和移动应用程序访问。
  • 也许我的处理方法不正确,但我在这里寻求建议。

标签: java spring spring-boot war wildfly


【解决方案1】:

您可以通过扩展SpringBootServletInitializer 将聊天服务器部署在Wildfly 中,而不是从main 启动它。

文档: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);
    //}
}

将生成的工件更改为war,并在wildfly中正常部署:

<project>
    <packaging>war</packaging>
    ...
<project>

您可能必须排除tomcat,它是使用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 为 Wildfly 提供了 pom.xml 的 Spring Boot 示例:spring-boot-deployment-test-wildfly

【讨论】:

  • Alex,这是与我退出的 Java 应用程序不同的战争吗?最好我想从同一个应用程序运行聊天服务器。我尝试在我现有的 Spring 应用程序中创建 SpringBootApp 类并启动 Spring Boot,但随后出现以下错误:StartException in service jboss.undertow.deployment.default-server.default-host./jbosswildfly: java.lang.RuntimeException: java.lang.ClassCastException: org.apache.tomcat.websocket.server.WsServerContainer cannot be cast to io.undertow.websockets.jsr.ServerWebSocketContainerNew missing/unsatisfied dependencies:
  • 谢谢亚历克斯。我只是不确定,但现在很清楚,它是一个单独的应用程序。感谢您的帮助。
猜你喜欢
  • 2018-04-22
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-08
  • 1970-01-01
相关资源
最近更新 更多