LoginSignup
2
4

More than 5 years have passed since last update.

Spring Bootのアプリケーションをlambdaでスケジュール実行したときにハマった

Posted at

lambdaでSpring Bootで書かれたアプリケーションを15分に1回スケジュール実行しようとすると、1回目はうまくいくのだが、2回目以降以下のエラーになった。

{
  "errorMessage": "Unable to register MBean [org.springframework.cloud.context.environment.EnvironmentManager@7bd6185a] with key 'environmentManager'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager",
  "errorType": "org.springframework.jmx.export.UnableToRegisterMBeanException",
  "stackTrace": [
    "org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:625)",
    "org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:550)",
    "org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:432)",
    "org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:792)",
    "org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)",
    "org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)",
    "org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)",
    "org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)",
    "org.springframework.boot.SpringApplication.run(SpringApplication.java:307)",
    "jp.co.recruit.rtc.hoc.elbconnector.ElbConnectorMain.handleRequest(ElbConnectorMain.java:44)",
    "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
    "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)",
    "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)",
    "java.lang.reflect.Method.invoke(Method.java:498)"
  ],
  "cause": {
    "errorMessage": "org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager",
    "errorType": "javax.management.InstanceAlreadyExistsException",
    "stackTrace": [
      "com.sun.jmx.mbeanserver.Repository.addMBean(Repository.java:437)",
      "com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerWithRepository(DefaultMBeanServerInterceptor.java:1898)",
      "com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:966)",
      "com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:900)",
      "com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:324)",
      "com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:522)",
      "org.springframework.jmx.support.MBeanRegistrationSupport.doRegister(MBeanRegistrationSupport.java:195)",
      "org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:678)",
      "org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:615)",
      "org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:550)",
      "org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:432)",
      "org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:792)",
      "org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)",
      "org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)",
      "org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)",
      "org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)",
      "org.springframework.boot.SpringApplication.run(SpringApplication.java:307)",
      "jp.co.recruit.rtc.hoc.elbconnector.ElbConnectorMain.handleRequest(ElbConnectorMain.java:44)",
      "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
      "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)",
      "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)",
      "java.lang.reflect.Method.invoke(Method.java:498)"
    ]
  }
}

調べると、これはSpringがJMXを使うためのMBeanを登録してくれるのだが、ApplicationContextを作る度に登録される。
Lambdaのスケジュール実行では1回目と2回目以降は同一のJVM内で動作するようなので、1回に実行したときにMBeanを登録し、2回目に実行したときに同じMBeanを登録しようとしてエラーになっている模様。

これを回避するには、JMX自体を無効にしてしまえばMBeanは登録されない。
具体的にはapplication.propertiesに以下を追加すればOK。

spring.jmx.enabled=false
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4