添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm new to Spring, first off.

I'm using a Spring service to monitor an email account and act when a new message is added. My Spring header code is:

@Component
public class EmailMonitor implements ApplicationListener<ContextRefreshedEvent> {
    private static final Logger log = LoggerFactory.getLogger(EmailMonitor.class);
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
       // monitor emails

Whenever I start it I get a number of pages of

"RMI TCP Connection(1)-192.168.1.18: name = \"[Ljava.rmi.server.ObjID;\", codebase = \"\", defaultLoader = jdk.internal.loader.ClassLoaders$PlatformClassLoader@332228c4","logger_name":"sun.rmi.loader"...
{"@timestamp":"2021-05-10T17:01:22.212+01:00","@version":"1","message":"RMI TCP Connection(1)-192.168.1.18: name = \"javax.management.ObjectName\", codebase = \"\"","logger_name":"sun.rmi.loader","thread_name":"RMI TCP Connection(1)-192.168.1.18","level":"DEBUG","level_value":10000,"appname":"email-notifier"}
{"@timestamp":"2021-05-10T17:01:22.213+01:00","@version":"1","message":"connectionId=rmi://192.168.1.18  4, name=org.springframework.boot:type=Admin,name=SpringApplication, attribute=Ready","logger_name":"javax.management.remote.rmi","thread_name":"RMI TCP Connection(1)-192.168.1.18","level":"DEBUG","level_value":10000,"appname":"email-notifier"}
{"@timestamp":"2021-05-10T17:01:22.213+01:00","@version":"1","message":"RMI TCP Connection(1)-192.168.1.18: [192.168.1.18] exception: ","logger_name":"sun.rmi.server.call","thread_name":"RMI TCP Connection(1)-192.168.1.18","level":"DEBUG","level_value":10000,"stack_trace":"javax.management.InstanceNotFoundException: org.springframework.boot:type=Admin,name=SpringApplication\n\tat java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1083)\n\tat java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:637)\n\tat java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678)\n\tat java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1443)\n\tat java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307)\n\tat java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1399)\n\tat java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.getAttribute(RMIConnectionImpl.java:637)\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:567)\n\tat java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)\n\tat java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)\n\tat java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)\n\tat java.base/java.security.AccessController.doPrivileged(AccessController.java:691)\n\tat java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)\n\tat java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)\n\tat java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)\n\tat java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)\n\tat java.base/java.security.AccessController.doPrivileged(AccessController.java:391)\n\tat java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)\n\tat java.base/java.lang.Thread.run(Thread.java:831)\n","appname":"email-notifier"}
{"@timestamp":"2021-05-10T17:01:22.214+01:00","@version":"1","message":"[javax.management.remote.rmi.RMIConnectionImpl@6d666aa: connectionId=rmi://192.168.1.18  4] closing.","logger_name":"javax.management.remote.rmi","thread_name":"RMI TCP Connection(1)-192.168.1.18","level":"DEBUG","level_value":10000,"appname":"email-notifier"}
{"@timestamp":"2021-05-10T17:01:22.214+01:00","@version":"1","message":"[javax.management.remote.rmi.RMIConnectionImpl@6d666aa: connectionId=rmi://192.168.1.18  4] closed.","logger_name":"javax.management.remote.rmi","thread_name":"RMI TCP Connection(1)-192.168.1.18","level":"DEBUG","level_value":10000,"appname":"email-notifier"}

And then the program ends, when it's supposed to wait and listen to the javax email account notifier.

Any ideas on this? I'm unsure what the role of the RMI server is in this context (and I'm struggling to find doc references that tie up Spring and RMI). My understanding is that Spring will start the services it requires, but apparently not in this case.

And it should wait because? If there is nothing keeping the process alive it will start and directly shutdown. So unless you are creating a thread in the onApplicationEvent nothing will happen. – M. Deinum May 11, 2021 at 9:30 Maybe you're right. However my understanding is that "as long as the listener object is registered in the Spring application context, it will receive events. When Spring routes an event, it uses the signature of our listener to determine if it matches an event or not." So doesn't Spring keep it alive to keep listening? – David Boshton May 11, 2021 at 9:34 No it doesn't keep it alive. It is an internal Spring even listener, not a JMS, Kafka etc. listeners for which a process would be started for monitoring. That and there is only 1 ContextRefreshedEvent going to be fired. – M. Deinum May 11, 2021 at 9:39 Also instead of writing your own I would suggest Spring Integration which has mail support out-of-the-box to do all of this. – M. Deinum May 11, 2021 at 9:50 That would be more useful. @M.Deinum could you add that (and the reference) as an answer and I'll accept it? – David Boshton May 13, 2021 at 13:55

To check for email and operate on it you are probably better of using Spring Integration which has out-of-the-box email support.

Regarding your question I suspect you misunderstood the ApplicationListener. It can be used to receive events fired through the internal event API of Spring. It won't start a listener thread like the listeners for Kafka or JMS would do. Althouhg both listeners in their own sense they are quite different beast.

But as mentioned you are probably better of using the email support of Spring Integration, saves you from writing your own.

I think you misunderstood the concept of spring context listeners.

Spring application context starts during the startup of spring driven application. It has various "hooks" - points that you could listen to and be notified once they happen. So yes, context can be refreshed and when it happens, the listener "fires" and your code is executed. But that's it - it won't actually do anything useful afterwards, when the context starts. You can read about the context events here for example.

So with this in mind, basically your application context gets refreshed once, and the listener will be called also only once during the application startup.

Now I didn't understand how is RMI server related to all this :) You can remove the @Component annotation from the listener and restart the application, probably it will still search for the RMI server (please try that and update in the comment or something)

So first off, I think you should try to understand how is RMI related to all this, I think there is some other component in the system that gets loaded by spring boot and it searches for the RMI. Maybe You can take a thread dump or something and see which thread really works with RMI.

To get an event "when the message is added" is an entirely different thing, you will probably have to implement it by yourself or if the thirdparty that works with email has such a functionality - try to find how to achieve that with that thirdpary API, but for sure its not a ContextRefreshed event.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.