Pro Spring Integration Authors-
(and/or others doing JMX with Spring Integration)
I received your book this week and it came just in time! I'm actively architecting a Spring Integration application at work and your book is filling in some of the pieces that are not covered in other reference materials. Thanks!
I started with this example:
prospringintegration_src/monitoring/src/main/java/com/apress/prospringintegration/jmx/JmxNotificationListener.java
Then I did the following:
Added my own class (FileToRecordSplitter.java) to the same package as the JMX enabled example class (BasicMBean.java).
Added the @Component, @ManagedResource and @ManagedOperation to FileToRecordSplitter.java
Added the NotificationPublisher to FileToRecordSplitter.java
Added the jmx:notification-listening-channel-adapter and the elements necessary to support my splitter to notification-listener.xml.
Added the spring-integration-file dependency to the pom.xml
Finally, I executed JmxNotifcationListener.java and received a "Failed to find MBean instance" error message. Why am I receiving this error message?
Below is the error message and the things that I added to your example. Everything else is exactly as it came from the examples.
Thank you,
Joshua Smith
FileToRecordSplitter.java
-------------------------
package com.apress.prospringintegration.jmx;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import javax.management.Notification;
import org.apache.log4j.Logger;
import org.springframework.integration.annotation.Splitter;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.notification.NotificationPublisher;
import org.springframework.jmx.export.notification.NotificationPublisherAware;
import org.springframework.stereotype.Component;
@Component
@ManagedResource
public class FileToRecordSplitter implements NotificationPublisherAware {
private static final Logger LOGGER = Logger.getLogger(FileToRecordSplitter.class);
private NotificationPublisher notificationPublisher;
@Splitter
@ManagedOperation
public List<Record> split(File file) throws IOException {
List<Record> records = new ArrayList<Record>();
FileInputStream fstream = new FileInputStream(file);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
records.add(new Record(file.getName(), strLine.split("\\s+")));
}
LOGGER.info("Split " + file.getName() + " into " + records.size() + " records.");
notificationPublisher.sendNotification(new Notification("split", this, 0));
return records;
}
@Override
public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
this.notificationPublisher = notificationPublisher;
}
}
notification-listener.xml
-------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jmx="http://www.springframework.org/schema/integration/jmx"
xmlns:file="http://www.springframework.org/schema/integration/file"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/jmx
http://www.springframework.org/schema/integration/jmx/spring-integration-jmx-2.0.xsd
http://www.springframework.org/schema/integration/file
http://www.springframework.org/schema/integration/file/spring-integration-file-2.0.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:mbean-export/>
<context:mbean-server/>
<context:component-scan base-package="com.apress.prospringintegration.jmx"/>
<int:channel id="notification"/>
<jmx:notification-listening-channel-adapter
channel="notification"
object-name="com.apress.prospringintegration.jmx:name=basicMBean,type=BasicMBean"/>
<jmx:notification-listening-channel-adapter
channel="notification"
object-name="com.apress.prospringintegration.jmx:name=fileToRecordSplitter,type=FileToRecordSplitter"/>
<stream:stdout-channel-adapter channel="notification" append-newline="true"/>
<int:poller default="true" max-messages-per-poll="10" fixed-rate="100" />
<file:inbound-channel-adapter id="fileChannel"
directory="file:/tmp/input" prevent-duplicates="true">
</file:inbound-channel-adapter>
<int:splitter id="fileToRecordSplitter"
input-channel="fileChannel"
output-channel="nullChannel" >
<bean class="com.apress.prospringintegration.jmx.FileToRecordSplitter"/>
</int:splitter>
</beans>
Added to pom.xml
----------------
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId>
</dependency>
Error Message
-------------
INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@36b8bef7: startup date [Sat Apr 23 12:12:47 EDT 2011]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [jmx/notification-listener.xml]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'fileToRecordSplitter': replacing [Generic bean: class [com.apress.prospringintegration.jmx.FileToRecordSplitter]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [/Users/josh/Documents/ProjectsCommon/SpringIntegration/ProSpringIntegrationSourceCodeFromApress/prospringintegration_src/monitoring/target/classes/com/apress/prospringintegration/jmx/FileToRecordSplitter.class]] with [Generic bean: class [org.springframework.integration.config.ConsumerEndpointFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
INFO : org.springframework.integration.config.xml.DefaultConfiguringBeanFactoryPostProcessor - No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.
INFO : org.springframework.integration.config.xml.DefaultConfiguringBeanFactoryPostProcessor - No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created.
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@70d05c13: defining beans [mbeanExporter,mbeanServer,basicMBean,fileToRecordSplitter,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.integration.internalDefaultConfiguringBeanFactoryPostProcessor,notification,org.springframework.integration.jmx.NotificationListeningMessageProducer#0,org.springframework.integration.jmx.NotificationListeningMessageProducer#1,org.springframework.integration.stream.CharacterStreamWritingMessageHandler#0,org.springframework.integration.config.ConsumerEndpointFactoryBean#0,org.springframework.scheduling.support.PeriodicTrigger#0,org.springframework.integration.context.defaultPollerMetadata,fileChannel,org.springframework.integration.file.config.FileListFilterFactoryBean#0,org.springframework.integration.file.config.FileReadingMessageSourceFactoryBean#0,fileChannel.adapter,org.springframework.integration.config.SplitterFactoryBean#0,nullChannel,errorChannel,_org.springframework.integration.errorLogger,taskScheduler]; root of factory hierarchy
INFO : org.springframework.jmx.export.annotation.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
INFO : org.springframework.jmx.export.annotation.AnnotationMBeanExporter - Bean with name 'basicMBean' has been autodetected for JMX exposure
INFO : org.springframework.jmx.export.annotation.AnnotationMBeanExporter - Located managed bean 'basicMBean': registering with JMX server as MBean [com.apress.prospringintegration.jmx:name=basicMBean,type=BasicMBean]
INFO : org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler - Initializing ExecutorService 'taskScheduler'
INFO : org.springframework.context.support.DefaultLifecycleProcessor - Starting beans in phase -2147483648
INFO : org.springframework.integration.endpoint.EventDrivenConsumer - started fileToRecordSplitter
INFO : org.springframework.integration.endpoint.EventDrivenConsumer - started org.springframework.integration.config.ConsumerEndpointFactoryBean#0
INFO : org.springframework.integration.endpoint.EventDrivenConsumer - started _org.springframework.integration.errorLogger
INFO : org.springframework.context.support.DefaultLifecycleProcessor - Starting beans in phase 0
INFO : org.springframework.integration.jmx.NotificationListeningMessageProducer - started org.springframework.integration.jmx.NotificationListeningMessageProducer#0
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@70d05c13: defining beans [mbeanExporter,mbeanServer,basicMBean,fileToRecordSplitter,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.integration.internalDefaultConfiguringBeanFactoryPostProcessor,notification,org.springframework.integration.jmx.NotificationListeningMessageProducer#0,org.springframework.integration.jmx.NotificationListeningMessageProducer#1,org.springframework.integration.stream.CharacterStreamWritingMessageHandler#0,org.springframework.integration.config.ConsumerEndpointFactoryBean#0,org.springframework.scheduling.support.PeriodicTrigger#0,org.springframework.integration.context.defaultPollerMetadata,fileChannel,org.springframework.integration.file.config.FileListFilterFactoryBean#0,org.springframework.integration.file.config.FileReadingMessageSourceFactoryBean#0,fileChannel.adapter,org.springframework.integration.config.SplitterFactoryBean#0,nullChannel,errorChannel,_org.springframework.integration.errorLogger,taskScheduler]; root of factory hierarchy
INFO : org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler - Shutting down ExecutorService 'taskScheduler'
INFO : org.springframework.jmx.export.annotation.AnnotationMBeanExporter - Unregistering JMX-exposed beans on shutdown
Exception in thread "main" org.springframework.context.ApplicationContextException: Failed to start bean 'org.springframework.integration.jmx.NotificationListeningMessageProducer#1'; nested exception is java.lang.IllegalStateException: Failed to find MBean instance.
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:169)
at org.springframework.context.support.DefaultLifecycleProcessor.access$1(DefaultLifecycleProcessor.java:154)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:335)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:143)
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:108)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:908)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:428)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.apress.prospringintegration.jmx.JmxNotificationListener.main(JmxNotificationListener.java:23)
Caused by: java.lang.IllegalStateException: Failed to find MBean instance.
at org.springframework.integration.jmx.NotificationListeningMessageProducer.doStart(NotificationListeningMessageProducer.java:121)
at org.springframework.integration.endpoint.AbstractEndpoint.start(AbstractEndpoint.java:84)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:166)
... 9 more
Caused by: javax.management.InstanceNotFoundException: com.apress.prospringintegration.jmx:name=fileToRecordSplitter,type=FileToRecordSplitter
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1094)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.addNotificationListener(DefaultMBeanServerInterceptor.java:1190)
at com.sun.jmx.mbeanserver.JmxMBeanServer.addNotificationListener(JmxMBeanServer.java:799)
at org.springframework.integration.jmx.NotificationListeningMessageProducer.doStart(NotificationListeningMessageProducer.java:118)
... 11 more