So if I get it right the issue is for now in CDI you don't really know if the backing instance - if exists - is created or not (ie toString() is not enough). I think on this point CDI can be enhanced to have a isInstantiated() method in its SPI and potentially a forceInstantiation() one to solve it - would also allow to fix the @Startup issue.
Now for JMS having an event based SPI would be a good addition allowing some programmatic registration - naming is to completely to rework but the idea would be:
public void startJms(@Observes final JmsAfterStart jmsStart) {
jmsStart.registerListener(message -> System.out.println(message))
.registerListener(new MyTypedMessageListener()); // or even an injected instance
}
// JmsBeforeShutdown would be needed as well with a unregister for symmetry but auto deregistration is possible as well
with MyTypedMessageListener:
public class MyTypedMessageListener {
public void onMessage(MyTypedMessageICreatedInMyApp msg() {}
}
For this last case a really elegant solution would be to just reuse @Observes to fire the message from the jms "container" listener and propagate it to the "user" listener. This would then allow to decouple the application listener from JMS.
For client side having a custom qualifier supporting placeholding - a bit like jbatch for system properties - would be nice and would allow to skip JNDI which means enabling SE usage as well.