简体   繁体   English

使用无限循环导入jar时,Spring Java项目未启动Tomcat

[英]Spring Java project not starting Tomcat when importing jar with infinite loop

I have a java app that is just takes a jar from another project, the jar is using an infinite loop to poll for messages on AWS SQS topic.我有一个 Java 应用程序,它只是从另一个项目中获取一个 jar,该 jar 使用无限循环来轮询有关 AWS SQS 主题的消息。

The loop looks for methods annotated with @subscriber in my client application.该循环在我的客户端应用程序中查找用@subscriber注释的方法。

I have a bean that will return a class which has a method annotated.我有一个 bean,它将返回一个带有注释方法的类。 When I remove the bean that is calling a class with an annotation method my tomcat is started on a port.当我删除使用注释方法调用类的 bean 时,我的 tomcat 在端口上启动。 When i add it in again there is no port hosted.当我再次添加它时,没有托管端口。

In the pom file I have these 2 dependencies added (along with some others but these should be the relevant ones)在 pom 文件中,我添加了这两个依赖项(以及其他一些依赖项,但这些应该是相关的)

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

My main class looks like this我的主班看起来像这样

@SpringBootApplication
@ComponentScan(basePackages = {"com.mypackage.reuse", "com.mypackage.sample.subscriber"})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

The logs I get when I start my app启动应用程序时得到的日志

2020-03-12 14:32:56.228  INFO 2429 --- [           main] c.l.g.e.f.sample.subscriber.Application  : The following profiles are active: development
2020-03-12 14:32:57.580  INFO 2429 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 1339 (http)
2020-03-12 14:32:57.586  INFO 2429 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-03-12 14:32:57.587  INFO 2429 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.29]
2020-03-12 14:32:57.650  INFO 2429 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-03-12 14:32:57.651  INFO 2429 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1363 ms
2020-03-12 14:32:58.038  INFO 2429 --- [           main] org.reflections.Reflections              : Reflections took 111 ms to scan 2 urls, producing 23 keys and 53 values 

there is no log after that I would expect something like this which is what I get if I remove the loop.之后没有日志,我希望像这样的东西,如果我删除循环,我会得到这样的结果。 When i remove the loop i get something like below but the problem is i need the loop to continuously poll.当我删除循环时,我得到如下内容,但问题是我需要循环连续轮询。

Exposing 2 endpoint(s) beneath base path '/actuator'
Tomcat started on port(s): 1339 (http) with context path ''

Since there is no error,既然没有错误,

Spring boot probably does something, and it might take time... When the initialization of the application context is done spring boot finally writes "tomcat started on port 1339 message" spring boot 大概做了点什么,可能需要时间…… 应用上下文的初始化完成后,spring boot 终于写到“tomcat started on port 1339 消息”

I don't know what exactly happens when "reflections API to find methods annotated with @subscirber" but if implemented inefficiently - this can definitely take some time.我不知道当“使用反射 API 查找用@subscirber 注释的方法”时究竟会发生什么,但如果实施效率低下 - 这肯定需要一些时间。

So I suggest taking a thread dump and trying to analyze the running threads when you reach the point in log where you feel that the application gets stuck.因此,我建议进行线程转储,并在到达日志中感觉应用程序卡住的点时尝试分析正在运行的线程。

Another suspicious point is what you wrote:另一个可疑点是你写的:

When I remove the bean that is calling a class with an annotation method my tomcat is started on a port.当我删除使用注释方法调用类的 bean 时,我的 tomcat 在端口上启动。

What is this bean exactly?这豆究竟是什么? what is the class with an annotation method?带有注释方法的类是什么? Does it try to connect to AWS?它是否尝试连接到 AWS? If so what if the definitions are wrong and it gets stuck trying to connect?如果是这样,如果定义错误并且尝试连接时卡住了怎么办? Again the stack trace will clarify a lot of things here.同样,堆栈跟踪将在这里澄清很多事情。

Update更新

Threas dump (you should read it from the bottom to the top - it shows the current calls execution chsin) shows that in the SubscriberFactory's constructor you're trying to connect to SQS of Aws and it gets stuck...威胁转储(您应该从底部到顶部阅读它 - 它显示了当前的调用执行 chsin)表明在 SubscriberFactory 的构造函数中,您正在尝试连接到 Aws 的 SQS 并且它卡住了......

This is abnormal situation.这是不正常的情况。 Probably you did something wrong with connection parameters.可能您在连接参数方面做错了。

From the point of view of spring initialization it stucks the whole initialization process, because spring creates the beans one by one in one thread从spring初始化的角度来看,它卡住了整个初始化过程,因为spring在一个线程中一个一个地创建bean

Anyway, proper connection to sqs will probably resolve the issue.无论如何,正确连接到 sqs 可能会解决这个问题。

Update 2更新 2

Answering the question of running the bean in different thread.回答在不同线程中运行 bean 的问题。

You dont run the bean but rather the method in the bean.您不运行 bean 而是运行 bean 中的方法。

It should not be a constructor or method annotated with @PostConstruct because these are methods called by spring during the initialization它不应该是用@PostConstruct注释的构造函数或方法,因为这些是spring 在初始化期间调用的方法

You can use @Async method in listener that will run when the application is ready.您可以在应用程序准备就绪时运行的侦听器中使用@Async方法。

You can read about asynchronous methods here, in this tutorial (note, you also need @EnableAsync )您可以在本教程中在此处阅读有关异步方法的信息(注意,您还需要@EnableAsync

The method should be called/implemented im the listener and be public void该方法应该在侦听器中被调用/实现并且是public void

The concept of listeners is easy to grasp - these are hooks to application context initialization lifecycle.侦听器的概念很容易掌握——它们是应用程序上下文初始化生命周期的挂钩。 You'll need to follow thos thread你需要关注那些线程

You override the default Tomcat HTTP port with your application.properties file and that's why you don't see it starting at 8080:您使用application.properties文件覆盖了默认的 Tomcat HTTP 端口,这就是为什么您看不到它从 8080 开始的原因:

server:
  port: 1339

change it to将其更改为

server:
  port: 8080

or remove it completly to have the default configuration或完全删除它以获得默认配置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM