Announcement Announcement Module
Collapse
No announcement yet.
Some problem about rabbitAdmin declareing queue Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Some problem about rabbitAdmin declareing queue

    Code:
    public class PriceRecognizerMqService implements PriceRecognizer {
    
    	private static final Logger logger = LoggerFactory
    			.getLogger(PriceRecognizerMqService.class.getSimpleName());
    
    	@Resource(name = "ocrRabbitTemplate")
    	private RabbitTemplate template;
    	@Autowired
    	private RabbitAdmin admin;
    	@Resource(name = "replyOcrQueue")
    	private Queue replyQueue;
    	
    	@Resource(name="relyListener")
    	private SimpleMessageListenerContainer listener;
    	@PostConstruct
    	public void init() {
    
    		template.setReplyQueue(replyQueue);
    		//admin.initialize();
    		listener.start();
    	}
    ........
    }
    Code:
    	<!-- queue name -->
    	<util:constant static-field="cn.com.summall.etl.ocr.Constants.REQUEST_SEND_QUEUE"
    		id="sendOcrRequestQueue" />
    	<util:constant static-field="cn.com.summall.etl.ocr.Constants.REPLY_SEND_QUEUE"
    		id="replyOcrRequestQueue" />
    	<!-- queue object configuration -->
    	<rabbit:queue name="#{sendOcrRequestQueue}" durable="true"></rabbit:queue>
    	<rabbit:queue name="#{replyOcrRequestQueue}" durable="true" id="replyOcrQueue"></rabbit:queue>
    	<!-- rabbit -->
    	<rabbit:template queue="#{sendOcrRequestQueue}"
    		reply-timeout="#{messageTimeout}" connection-factory="rabbitConnectionFactory"
    		routing-key="#{sendOcrRequestQueue}" id="ocrRabbitTemplate"
    		channel-transacted="false" >
    	</rabbit:template>
    	<rabbit:listener-container  id="relyListener"
    		concurrency="1" connection-factory="rabbitConnectionFactory"
    		prefetch="30" transaction-size="5" auto-startup="false"
    		message-converter="clientOcrConvert"
    		error-handler="mqErrorHandler">
    		<rabbit:listener method="handleMessage" queue-names="#{replyOcrRequestQueue}"
    			ref="ocrReplyListener" />
    	</rabbit:listener-container>

    the listener is used to receive the result by the type of rpc .I know I can configurate the reply-queue and reply listener to build them automatically ,but if there is no the queue in the server ,the reply-listener can't work and throws the exception :"channel error; reason: {#method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'queue.etlOcrClient.result' in vhost '/', class-id=50, method-id=10), null, ""} ". so I defined a listener-container to act as a reply-listener.As you see ,if I delete admin.initialize(); it will throw the exception :
    Code:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cn.com.summall.etl.ocr.ProviderTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private cn.com.summall.etl.ocr.PriceRecognizer cn.com.summall.etl.ocr.ProviderTest.priceRecognizer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mqRecognizer': Invocation of init method failed; nested exception is org.springframework.amqp.UncategorizedAmqpException:    
       Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private cn.com.summall.etl.ocr.PriceRecognizer cn.com.summall.etl.ocr.ProviderTest.priceRecognizer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mqRecognizer': Invocation of init method failed; nested exception is org.springframework.amqp.UncategorizedAmqpException: java.util.concurrent.TimeoutException: Timed out waiting for startup
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506)
    	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    	... 26 more
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mqRecognizer': Invocation of init method failed; nested exception is org.springframework.amqp.UncategorizedAmqpException: java.util.concurrent.TimeoutException: Timed out waiting for startup
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:135)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1448)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:876)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:818)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735)
    	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
    	... 28 more
    Caused by: org.springframework.amqp.UncategorizedAmqpException: java.util.concurrent.TimeoutException: Timed out waiting for startup
    	at org.springframework.amqp.rabbit.connection.RabbitUtils.convertRabbitAccessException(RabbitUtils.java:115)
    	at org.springframework.amqp.rabbit.connection.RabbitAccessor.convertRabbitAccessException(RabbitAccessor.java:106)
    	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.start(AbstractMessageListenerContainer.java:365)
    	at cn.com.summall.etl.ocr.PriceRecognizerMqService.init(PriceRecognizerMqService.java:44)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:346)
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:299)
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:132)
    	... 40 more
    Caused by: java.util.concurrent.TimeoutException: Timed out waiting for startup
    	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.getStartupException(SimpleMessageListenerContainer.java:512)
    	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doStart(SimpleMessageListenerContainer.java:337)
    	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.start(AbstractMessageListenerContainer.java:363)
    	... 48 more
    but if I use admin.initialize(),the exception will disappear.And I doubt that when the rabbitAdmin will execute initialize() to declare queues automatically.and I find that the container whose auto-startup is true will start before admin initial.Could you explain the order of rabbit-client starting up. Thank you
    Last edited by andy lin; Oct 31st, 2012, 05:56 AM.

  • #2
    You must not start() the listener container from a @PostConstruct method because the application context is not yet fully baked at that time.

    If you wish to start it manually, you must wait until the context has been fully initialized, either by refresh()ing the context manually during initialization (rather than using the default mechanism where the context refresh()es itself, or by listening for an ContextRefreshedEvent in an ApplicationListener.

    Comment


    • #3
      Could you give me a example to do it correctly ? and what about the mechanism of the client starting ?

      Comment


      • #4
        How are you starting your application context?

        If programmatically, instead of using

        Code:
        ApplicationContext ctx = new ClassPathXmlApplicationContext(...);
        use
        Code:
        AbstractXmlApplicationContext ctx = new ClassPathXmlApplicationContext();
        crx.setConfigLocation(...);
        ctx.refresh();
        ctx.getBean(SimpleMessageListenerContainer.class).start();
        But, if that's all you want to do then why not just let it start up automatically (auto-startup="true"),


        If you are running in a web container and/or don't programmatically create the context, implement ApplicationListener<ContextRefreshedEvent> and you will get an event when the context refresh is complete.


        I don't know what you mean by "client starting".

        Comment


        • #5
          Because I find if the queue or exchange doesn't exist in the server,the container can't start successfully,the rabbitAdmin initialize() will be invoked after the container starts. so I have to do like that . the meaning of "client starting" is that when rabbitmq client starts ,what it will do ? and when the the initialize() in rabbitAdmin will be invoked.In one word ,I want to solve the problem that the queue and exchange can be built automatically

          Comment


          • #6
            But that's how it works; the RabbitAdmin.initialize() is called automatically because the Admin is registered as ConnectionListener with the ConnectionFactory (the registration happens in Admin.afterPropertiesSet().

            So, when the container requests a channel, the factory first creates a connection, and the admin is called to declare the queues etc. This all happens before the container ever gets its channel on which it tries to create a consumer for the queue.

            There's nothing to "start" in the client - it's passive.

            Comment

            Working...
            X