Spring-amqp RabbitMQ - no exchange 'myexchange' in vhost '/' ERROR

16,731

Your problem is:

cache-mode="CONNECTION" 

See Reference Manual:

Automatic declaration is only performed when the CachingConnectionFactory cache mode is CHANNEL (the default). This limitation exists because exlusive and auto-delete queues are bound to the connection.

(Oops! Typo is there. Will fix soon :-) )

Share:
16,731
Rashida
Author by

Rashida

Updated on June 05, 2022

Comments

  • Rashida
    Rashida almost 2 years

    I know this question has been asked before but I couldnot find any suitable solution to my problem, hence posting it again.

    I am trying to write a rabbitmq producer using spring-amqp to publish my messages on direct queue. Since its a producer application, my exchange and queue have to be created. Also I am not defining any listener bean as I do not need it at the producer end. Below is my rabbitmq-config.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:rabbit="http://www.springframework.org/schema/rabbit"
    xsi:schemaLocation="http://www.springframework.org/schema/rabbit
    http://www.springframework.org/schema/rabbit/spring-rabbit-1.5.xsd
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!-- Spring AMQP Admin -->
    <rabbit:admin id="amqpAdmin"
        connection-factory="rabbitmqConnectionFactory"
        auto-startup="true" />
    
    <!-- Spring AMQP Template -->
    <rabbit:template id="amqpTemplate"
        connection-factory="rabbitmqConnectionFactory"
        routing-key="my.key" exchange="my.exchange" 
        channel-transacted="true"/>
    
    <!-- Connection Factory -->
    <rabbit:connection-factory id="rabbitmqConnectionFactory"
        host="${rabbitmq.host:localhost}" 
        port="${rabbitmq.port:5672}" 
        username="${rabbitmq.username}"
        password="${rabbitmq.password}" 
        virtual-host="${rabbitmq.vhost:/}"
        cache-mode="CONNECTION" 
        channel-cache-size="${rabbitmq.channel-cache-size:25}" />
    
    <!-- Queue and Exchange -->
    <rabbit:queue id="my.queue" durable="false"
        auto-declare="true" auto-delete="true" />
    
    <rabbit:direct-exchange name="my.exchange" durable="false"
        auto-declare="true" auto-delete="true" declared-by="amqpAdmin">
        <rabbit:bindings>
            <rabbit:binding queue="my.queue" key="my.key"/>
        </rabbit:bindings>
    </rabbit:direct-exchange>
    </beans>
    

    I just have a simple producer class, which uses the above amqpTemplate to send a message. But when I try running my producer application, all I get is: no exchange 'my.exchange' in vhost '/' ERROR

    ERROR CachingConnectionFactory:1089 - Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'my.exchange' in vhost '/', class-id=60, method-id=40)
    DEBUG CachingConnectionFactory:842 - Detected closed channel on exception.  Re-initializing: AMQChannel(amqp://[email protected]:5672/,1)
    DEBUG RabbitResourceHolder:189 - Rolling back messages to channel: Cached Rabbit Channel: AMQChannel(amqp://[email protected]:5672/,1), conn: Proxy@17a7f733 Dedicated Rabbit Connection: SimpleConnection@2118cddf [delegate=amqp://[email protected]:5672/]
    TRACE CachingConnectionFactory:906 - Returning cached Channel: AMQChannel(amqp://[email protected]:5672/,1)
    Exception in thread "main"
    DEBUG CachingConnectionFactory:1008 - Returning connection 'Proxy@17a7f733 Dedicated Rabbit Connection: SimpleConnection@2118cddf [delegate=amqp://[email protected]:5672/]' to cache
    org.springframework.amqp.AmqpIOException: java.io.IOException
        at org.springframework.amqp.rabbit.connection.RabbitUtils.commitIfNecessary(RabbitUtils.java:105)
        at org.springframework.amqp.rabbit.core.RabbitTemplate.doSend(RabbitTemplate.java:1354)
        at org.springframework.amqp.rabbit.core.RabbitTemplate$3.doInRabbit(RabbitTemplate.java:623)
        at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1298)
        at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1271)
        at org.springframework.amqp.rabbit.core.RabbitTemplate.send(RabbitTemplate.java:619)
        at org.springframework.amqp.rabbit.core.RabbitTemplate.send(RabbitTemplate.java:613)
        at org.springframework.amqp.rabbit.core.RabbitTemplate.send(RabbitTemplate.java:603)
        at com.symantec.spe.cloud.amqpclient.JsonMessagePublisherImpl.sendMessage(JsonMessagePublisherImpl.java:53)
        at com.symantec.spe.cloud.amqpclient.test.TestProducer.main(TestProducer.java:50)
    Caused by: java.io.IOException
        at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:106)
        at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:102)
        at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:124)
        at com.rabbitmq.client.impl.ChannelN.txCommit(ChannelN.java:1163)
        at com.rabbitmq.client.impl.ChannelN.txCommit(ChannelN.java:61)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:835)
        at com.sun.proxy.$Proxy7.txCommit(Unknown Source)
        at org.springframework.amqp.rabbit.connection.RabbitUtils.commitIfNecessary(RabbitUtils.java:103)
        ... 9 more
    Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchang
    e 'my.exchange' in vhost '/', class-id=60, method-id=40)
        at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:67)
        at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:33)
        at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:361)
        at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:226)
        at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:118)
        ... 18 more
    Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchang
    e 'my.exchange' in vhost '/', class-id=60, method-id=40)
        at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:484)
        at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:321)
        at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:144)
        at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:91)
        at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:554)
        at java.lang.Thread.run(Unknown Source)
    

    Any help on this would be really appreciated. Thanks.

  • Gary Russell
    Gary Russell almost 8 years
    Also, even with CHANNEL cache mode, since both the exchange and queue are auto-delete, if the consumer starts and stops (or somehow loses its connection) while the producer is still running, the queue and exchange will be deleted; the producer will have no knowledge of that and won't re-declare in that case.
  • Rashida
    Rashida almost 8 years
    @Artem Bilan, thanks for your help. It solved my problem. I changed the cache-mode to CHANNEL and since I wanted durable and non-exclusive queues, I set those fields appropriately.
  • Rashida
    Rashida almost 8 years
    @GaryRussell, would this be true for non-exclusive queues as well? Thanks.
  • Gary Russell
    Gary Russell almost 8 years
    exclusive is irrelevant - auto-delete queues are deleted by rabbit when the consumer no longer consumes from them. They will exist after declaration until a consumer starts consuming, and then stops after which they are deleted. auto-delete exchanges are deleted when the last bound queue is deleted. Read the RabbitMQ documentation to get a full understanding of these semantics.
  • Gary Russell
    Gary Russell almost 8 years
    BTW, cache mode CONNECTION is rarely needed. A single connection is generally recommended.
  • Rashida
    Rashida almost 8 years
    @GaryRussell, thanks a lot for your input, I will also go through the docs.