Is there a specific way to accomplish this? I tried to find a solution on here but couldn't find what I need. I have a Spring Boot application that will be accepting multiple arguments from the command line. The argument in question is the queue name (i.e. the destination). It can be one of several of our many queues. The JmsListener
is in the form
@JmsListener(destination="dest_goes_here")
public void processOrder(Message message){. . .}
I have a class that basically looks like this
public class Arguments {
private static queue
private static antoherArg
:
:
getters and setters
}
And what I would like to say is destination = Arguments.getQueue()
, but it seems destination
can only be a static final
variable? I assume this because the error presents a little tooltip that alludes to that.
I also tested it, as I have yet another class called Constants
, that obvioulsy contains constants, and if I hard code the queue name as public static final String QUEUE = "MyQ";
then say destination = Constants.QUEUE
it is ok with that.
So then I assumed I could do something like this in my listener class private static final String QUEUE = Arguments.getQueue();
But it doesn't like that either. Alas, I am stumped.
So really two questions here if anyone is willing to knowledge share. Why is the @JmsListener
ok with having destination
set to my second solution, but not the first and the last?
And then the main question (that I'd prefer you answer over the first) is, what strategies can I make use of to set destination to a variable that originates from the command line (i.e. be dynamic)?
Edit: To clarify, I cannot keep the value in my Constants
class, as the value will be coming from the command line and needs to be passed to the JmsListener class to be used as the destination
.
That's how Java works, destination
must be a compile-time constant expression and a function invocation isn't considered one. Take a look at the official language specification for more details. EDIT: you can also look at this answer.
As far as your second (and more important) question goes, I have several suggestions for you.
First, you can read the queue name from a configuration property, like so: destination="${jms.queue.name1}"
where jms.queue.name1
is your configuration property. Then, since you are using Spring Boot, you can use command-line arguments to override your configuration properties (see externalized configuration documentation for more details). That way, you'll be able to specify the queue name at runtime by passing it as a command-line argument like so --jms.queue.name1=foo
.
Second, you can use programmatic listener registration, like so:
@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
endpoint.setId("myJmsEndpoint");
endpoint.setDestination(Arguments.getQueue());
endpoint.setMessageListener(message -> {
// processing
});
registrar.registerEndpoint(endpoint);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With