Closed
Description
Vadim Beilin opened SPR-15031 and commented
org.springframework.jmx.export.MBeanExporter#registerBeanNameOrInstance(Object,String) may encounter situation when the bean value returned by the getBean(beanName) at line 601 is null. One common situation when this happens is when a FactoryBean.getObject() returns null (valid since Spring 2.0) based on some configuration settings.
MBeanExporter or its subclasses cannot deal with this situation:
- MBeanExporter:
Exception in thread "main" org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [spring.SpringTest$Fct] with key 'spring.SpringTest$Fct'; nested exception is javax.management.MalformedObjectNameException: Key properties cannot be empty
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:625)
at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:550)
at org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:432)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:792)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at spring.SpringTest.main(SpringTest.java:15)
Caused by: javax.management.MalformedObjectNameException: Key properties cannot be empty
at javax.management.ObjectName.construct(ObjectName.java:483)
at javax.management.ObjectName.<init>(ObjectName.java:1382)
at javax.management.ObjectName.getInstance(ObjectName.java:1273)
at org.springframework.jmx.support.ObjectNameManager.getInstance(ObjectNameManager.java:62)
at org.springframework.jmx.export.naming.KeyNamingStrategy.getObjectName(KeyNamingStrategy.java:141)
at org.springframework.jmx.export.MBeanExporter.getObjectName(MBeanExporter.java:751)
at org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:654)
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:602)
... 7 more
- AnnotationMBeanExporter:
Exception in thread "main" org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [spring.SpringTest$Fct] with key 'spring.SpringTest$Fct'; nested exception is java.lang.IllegalArgumentException: Candidate object must not be null
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:625)
at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:550)
at org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:432)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:792)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at spring.SpringTest.main(SpringTest.java:15)
Caused by: java.lang.IllegalArgumentException: Candidate object must not be null
at org.springframework.util.Assert.notNull(Assert.java:115)
at org.springframework.aop.support.AopUtils.getTargetClass(AopUtils.java:104)
at org.springframework.jmx.export.naming.MetadataNamingStrategy.getObjectName(MetadataNamingStrategy.java:111)
at org.springframework.jmx.export.MBeanExporter.getObjectName(MBeanExporter.java:751)
at org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:654)
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:602)
... 7 more
Example for reproduction:
package spring;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.annotation.*;
import org.springframework.jmx.export.MBeanExporter;
@Configuration
@Import({/*AnnotationMBeanExporter.class*/MBeanExporter.class, SpringTest.Fct.class})
public class SpringTest {
public static void main(String[] args) { new AnnotationConfigApplicationContext(SpringTest.class); }
public static class Fct implements FactoryBean<Something> {
// returns null if some condition is not met
@Override public Something getObject() throws Exception { return null; }
@Override public Class<?> getObjectType() { return Something.class; }
@Override public boolean isSingleton() { return true; }
}
// uncomment to use AnnotatedMBeanExporter
// @ManagedResource
public static class Something implements SomethingMBean{}
public static interface SomethingMBean {}
}
Tested with 4.2.6, code in either 4.3.x or 5. does not appear to have any changes.
Affects: 3.2.17, 4.2.6
Metadata
Metadata
Assignees
Labels
Type
Projects
Relationships
Development
No branches or pull requests
Activity
spring-projects-issues commentedon Dec 19, 2016
Juergen Hoeller commented
Without a dedicated
ObjectNamingStrategy
, it even fails with anNPE
later on...I've addressed this through corresponding not-null checks, silently ignoring such null beans now.
Thanks for the report!