How to keep apache camel context alive in thread main - java

I'm trying to make simple application that will listen one queue from artemis and then proceed messages and after that create new message in second queue.
I have created in method Main Camel context and added routing (it forwards messages to bean). And to test this routing and that this bean works correctly I'm sending
few messages to this queue - rigth after context started in main thread
public static void main(String args[]) throws Exception {
CamelContext context = new DefaultCamelContext();
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616", "admin", "admin");
context.addComponent("cmp/q2", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
context.addRoutes(new RouteBuilder() {
public void configure() {
from("cmp/q2:cmp/q2").bean(DataRequestor.class, "doSmth(${body}, ${headers})");
}
});
ProducerTemplate template = context.createProducerTemplate();
context.start();
for (int i = 0; i < 2; i++) {
HashMap<String, Object> headers = new HashMap<String, Object>();
headers.put("header1", "some header info");
template.sendBodyAndHeaders("cmp/q2:cmp/q2", "Test Message: " + i, headers);
}
context.stop();
}
And in this case application works fine, but it stops when method main completed - it proceess only messages that were created by it self.
Now after I have test bean that is used in routing, I want to modify application such way that it should start and stay active(keeping camle context and routin alive ) - so that i can create massages manually in web UI (active mq management console).
But I really don't know how.
I have tried infinite loop with Thread.sleep(5000);
I tried to start one more thread(also with infinite loop) in main method.
But it didn't work.(The most suspicious for me in case with infinite loop is that apllication is running, but when i create message in web UI it just desapears - and no any traces in system out that it was processed by my bean in routing, a suppose that it should be processed by my bean or just stay in the queue untouched, but it just disapears).
I now that my question is dummy, but I already have wasted 3 days to find a solution, so any advices or link to tutorials or some valueable information are appreciated.
PS: I've got one painfull restriction - Spring frameworks are not allowed.

I think the most simple solution for running standalone camel is starting it with camel Main. Camel online documentation has also an example of using it http://camel.apache.org/running-camel-standalone-and-have-it-keep-running.html.
I will copy paste the example code here just in case:
public class MainExample {
private Main main;
public static void main(String[] args) throws Exception {
MainExample example = new MainExample();
example.boot();
}
public void boot() throws Exception {
// create a Main instance
main = new Main();
// bind MyBean into the registry
main.bind("foo", new MyBean());
// add routes
main.addRouteBuilder(new MyRouteBuilder());
// add event listener
main.addMainListener(new Events());
// set the properties from a file
main.setPropertyPlaceholderLocations("example.properties");
// run until you terminate the JVM
System.out.println("Starting Camel. Use ctrl + c to terminate the JVM.\n");
main.run();
}
private static class MyRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
from("timer:foo?delay={{millisecs}}")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("Invoked timer at " + new Date());
}
})
.bean("foo");
}
}
public static class MyBean {
public void callMe() {
System.out.println("MyBean.callMe method has been called");
}
}
public static class Events extends MainListenerSupport {
#Override
public void afterStart(MainSupport main) {
System.out.println("MainExample with Camel is now started!");
}
#Override
public void beforeStop(MainSupport main) {
System.out.println("MainExample with Camel is now being stopped!");
}
}
}
The route keeps executing until you hit Ctlr+c or stop it in some other way...
If you test this, notice that you need example.properties file in your classpath, with the property millisecs.

At the very minimum you need a main thread to kick off a thread to run the camel route and then check for when that thread is done. The simple java threading approach using the main loop to check .wait() and the end of the camel route thread to signal .notify() when it finishes (or shutdown) would get the job done.
From there you can look into an executor service or use a micro-container like Apache Karaf
PS. Props for going Spring-free!

Disclaimer: this is written in Kotlin but it is somewhat trivial to port to java
Disclaimer: this is written for Apache-Camel 2.24.2
Disclaimer: I am also learning about Apache-Camel. The docs are a little heavy for me
I tried the Main route to set it up but it quickly got a little convoluted. I know that this is a java thread but I'm using kotlin ATM, I'll leave most of the types and imports available so it's easier for java devs.
class Listener
The first I had to fight with was understanding the lifecycle of Main. It turns out that there is an interface you can implement to add in the implementations of such events. With such an implementation I can hook up any routines that have to be sure that camel has started (no guessing required).
import org.apache.camel.CamelContext
import org.apache.camel.main.MainListener
import org.apache.camel.main.MainSupport
typealias Action = () -> Unit
class Listener : MainListener {
private var afterStart: Action? = null
fun registerOnStart(action:Action) {
afterStart = action
}
override fun configure(context: CamelContext) {}
override fun afterStop(main: MainSupport?) {}
override fun afterStart(main: MainSupport?) {
println("started!")
afterStarted?.invoke().also { println("Launched the registered function") }
?: println("Nothing registered to start")
}
override fun beforeStop(main: MainSupport?) {}
override fun beforeStart(main: MainSupport?) {}
}
class ApplicationCore
Then I set up the configuration of the context (Routes, Components, etc,...)
import org.apache.camel.CamelContext
import org.apache.camel.impl.DefaultCamelContext
import org.apache.camel.impl.SimpleRegistry
import org.apache.camel.main.Main
class ApplicationCore : Runnable {
private val main = Main()
private val registry = SimpleRegistry()
private val context = DefaultCamelContext(registry)
private val listener = Listener() // defined above
// for Java devs: this is more or less a constructor block
init {
main.camelContexts.clear()
listener.registerOnStart({ whateverYouAreDoing().start() })// <- your stuff should run in its own thread because main will be blocked
main.camelContexts.add(context)
main.duration = -1
context.addComponent("artemis", ...)// <- you need to implement your own
context.addRoutes(...)// <- you already know how to do this
...// <- anything else you could need to initialize
main.addMainListener(listener)
}
fun run() {
/* ... add whatever else you need ... */
// The next line blocks the thread until you close it
main.run()
}
fun whateverYouAreDoing(): Thread {
return Thread() {
ProducerTemplate template = context.createProducerTemplate();
for (i in 0..1) {
val headers = HashMap<String, Any>()
headers["header1"] = "some header info"
template.sendBodyAndHeaders("cmp/q2:cmp/q2", "Test Message: $i", headers)
}
context.stop()// <- this is not good practice here but its what you seem to want
}
}
}
In kotlin, initialization is rather easy. You can easily translate this into java because it is quite straight forward
// top level declaration
fun main(vararg args:List<String>) = { ApplicationCore().run() }

Related

Spring boot JPA repository passed to another thread not working

I have an autowired jpa repository object working. However, I need to use it to add rows into the database from multiple threads.
Though, after passing it to another thread, it fails.
Code structure
#SpringBootApplication(exclude = HealthcheckConfig.class)
public class Application implements CommandLineRunner {
#Autowired
private DBRepository dbRepository;
#Autowired
private AppConfig appConfig;
private ExecutorService executors = Executors.newFixedThreadPool(3);
Application() {
}
#Override
public void run(final String... args) {
final DBSchemaObject temp = new Application("testdb", "testfield");
dbRepository.save(temp); // This WORKs!!!
for (FileStatus fileStatus: fileStatuses) {
executors.execute(new ThreadSafeClass(dbRepository));
}
}
public static void main(final String[] args) {
new SpringApplicationBuilder(Application.class)
.web(WebApplicationType.NONE)
.run(args)
.close();
}
}
However, doing a dbRepository.save() from a thread safe class, I get error
cause: java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext#41330d4f has been closed already
detailedMessage: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Could not bind properties to 'DataSourceProperties' : prefix=spring.datasource, ignoreInvalidFields=false, ignoreUnknownFields=true
Stacktrace:
{StackTraceElement#14839} "org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)"
{StackTraceElement#14840} "org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)"
{StackTraceElement#14841} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354)"
{StackTraceElement#14842} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204)"
{StackTraceElement#14843} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)"
{StackTraceElement#14844} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)"
{StackTraceElement#14845} "org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)"
{StackTraceElement#14846} "org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)"
{StackTraceElement#14847} "org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)"
{StackTraceElement#14848} "org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)"
{StackTraceElement#14849} "org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410)"
{StackTraceElement#14850} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334)"
{StackTraceElement#14851} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)"
{StackTraceElement#14852} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)"
{StackTraceElement#14853} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)"
{StackTraceElement#14854} "org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)"
{StackTraceElement#14855} "org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)"
{StackTraceElement#14856} "org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)"
{StackTraceElement#14857} "org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)"
{StackTraceElement#14858} "org.springframework.beans.factory.support.DefaultListableBeanFactory$1.orderedStream(DefaultListableBeanFactory.java:481)"
{StackTraceElement#14859} "org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:167)"
{StackTraceElement#14860} "org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:149)"
{StackTraceElement#14861} "org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)"
{StackTraceElement#14862} "org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)"
{StackTraceElement#14863} "org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)"
{StackTraceElement#14864} "org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)"
{StackTraceElement#14865} "org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)"
{StackTraceElement#14866} "org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)"
{StackTraceElement#14867} "com.sun.proxy.$Proxy99.save(Unknown Source)"
{StackTraceElement#14868} "com.xxxx.run(Application.java:109)"
{StackTraceElement#14869} "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)"
{StackTraceElement#14870} "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)"
{StackTraceElement#14871} "java.lang.Thread.run(Thread.java:748)"
How can I use the spring boot repository object across multiple threads ?
The problem is that your run() method just schedules the tasks to be executed, but does not wait for their completion. This what is happening:
new SpringApplicationBuilder(Application.class) You are creating a new application context with the command line runner Application
.run(args) Then you initialize and execute your application context's run() method
The run() method schedules the tasks to be executed and exists immediately:
public void run(final String... args) {
for (FileStatus fileStatus: fileStatuses) {
executors.execute(new ThreadSafeClass(dbRepository));
}
}
Because run() terminated, spring assumes that the application has finished and calls .close(); Thus closing the application context and making it impossible to use any spring features such as repositories.
The scheduled tasks get executed, but the context was already closed, thus they fail and throw the exception.
The solution is to wait for the tasks' completion before exiting from the run method. As your example is too minimal, this is just an example. Alternatively you can use other methods to wait for the completion of the tasks such as CountDownLatch , etc, without having to shutdown the thread pool:
for (FileStatus fileStatus: fileStatuses) {
executors.execute(new ThreadSafeClass(dbRepository));
}
executors.shutdown(); // prevents the executor from accepting any new tasks
executors.awaitTermination(); // wait for the tasks to finish
ExecutorService::shutdown javadoc
ExecutorService::awaitTermination javadoc

Polling SQS using dropwizard

What I am trying to achieve:
I want to make a dropwizard client that polls Amazon SQS.
Whenever a message is found in the queue, it is processed and stored.
Some information about the processed messages will be available through an API.
Why I chose Dropwizard:
Seemed like a good choice to make a REST client. I need to have metrics, DB connections and integrate with some Java services.
What I need help with:
It is not very clear how and where the SQS polling will fit in a typical dropwizard application.
Should it be a managed resource? Or a console reporter console-reporter? Or something else.
You can use com.google.common.util.concurrent.AbstractScheduledService to create a consumer thread and add it to the dropwizard's environment lifecycle as ManagedTask. Following is the pseudocode -
public class YourSQSConsumer extends AbstractScheduledService {
#Override
protected void startUp() {
// may be print something
}
#Override
protected void shutDown() {
// may be print something
}
#Override
protected void runOneIteration() {
// code to poll on SQS
}
#Override
protected Scheduler scheduler() {
return newFixedRateSchedule(5, 1, SECONDS);
}
}
In Main do this -
YourSQSConsumer consumer = new YourSQSConsumer();
Managed managedTask = new ManagedTask(consumer);
environment.lifecycle().manage(managedTask);
As an alternative to RishikeshDhokare's answer, one can also go ahead with the following code which does not need to include additional jar as a dependency in your project to keep the uber jar as much lightweight as possible.
public class SQSPoller implements Managed, Runnable {
private ScheduledExecutorService mainRunner;
#Override
public void start() throws Exception {
mainRunner = Executors.newSingleThreadScheduledExecutor()
mainRunner.scheduleWithFixedDelay(this, 0, 100, TimeUnit.MILLISECONDS);
}
#Override
public void run() {
// poll SQS here
}
#Override
public void stop() throws Exception {
mainRunner.shutdown();
}
}
And in the run() of your Application class, you can register the above class as follows.
environment.lifecycle().manage(new SQSPoller());
You can use either scheduleWithFixedDelay() or scheduleAtFixedRate() depending upon your use case.

Reactor Eventbus example which gives back a response or an error

First thing first, I am pretty new to the domain of asychronous processing. In my current project, we are using spring boot along with project reactor, specifically Eventbus, to do some asynchronous processing. Use of eventbus I guess would also make our system more scalable.
Till now, the use of EventBus has been pretty limited where we do some processing in an EventBus consumer which does not return something. The configiuration and example processor are as follows:
//Config File
#SpringBootApplication
public class Application implements CommandLineRunner {
#Autowired
private EventBus eventBus;
#Autowired
private BatchProcessor batchProcessor;
#Override
public void run(String... arg0) throws Exception {
eventBus.on("batchProcessor", batchProcessor);
}
}
//Consumer
#Service
public class BatchProcesspr implements Consumer<Event<Request>> {
#Override
public void accept(Event<Request> event) {
// processing goes here
}
Till now, this was fine with the accept method having a void return type. But, now I have a scenario where I would like to return a response from the processor method, or if an error occurs while processing need to throw an appropriate exception and in either case, the response/exception needs to be returned to the point of invocation.
Can this be done using reactor? if yes, please provide an easy example for this. I have read about Promise but cannot find an example similar to my case.
Did you try sendAndReceive? http://projectreactor.io/ext/docs/reference/#bus-request-reply
EventBus bus;
bus.receive($("job.sink"), (Event<String> ev) -> {
return ev.getData().toUpperCase();
});
bus.sendAndReceive(
"job.sink",
Event.wrap("Hello World!"),
s -> System.out.printf("Got %s on thread %s%n", s, Thread.currentThread())
);
You can easily register another consumer on the caller side that is notified when the service responds.

How to escalate top-most supervisors in Akka?

I have the following top-level (“parent-most”) actor:
// Groovy pseudo-code
class Master extends UntypedActor {
ActorRef child1
ActorRef child2
ActorRef child3
ActorRef backup
#Override
void onReceive(Object message) throws Exception {
if(message instanceof Terminated) {
Terminated terminated = message as Terminated
if(terminated.actor != backup) {
terminated.actor = backup
} else {
// TODO: What to do here? How to escalate from here?
}
} else {
child1.tell(new DoSomething(message), getSelf())
child2.tell(new DoSomethingElse(message), getSelf())
child3.tell(new DoSomethingElser(message, getSelf())
}
}
#Override
SupervisorStrategy supervisorStrategy() {
new OneForOneStrategy(10, Duration.minutes(“1 minute”, new Future<Throwable, SupervisorStrategy.Directive> {
#Override
Directive apply(Throwable t) throws Exception {
if(isRecoverable(t) { // Don’t worry about how/where this is defined or how it works
SupervisorStrategy.stop()
} else {
SupervisorStrategy.escalate()
}
}
})
}
}
As you can see, it supervises three children, and when those 3 children throw “recoverable” exceptions, they are stopped and are replaced with a backup. So far, so good.
The problem I’m now facing is that if the backup actors throws any throwable whatsoever, I want to consider this Master actor (and really, my app in general) to be in a state where it cannot continue processing any input, and to escalate the exception to the guardian-level.
I’m brand new to Akka and not sure where to put this code, and what it should look like. Again, I just need logic that says:
If the backup actor throws any throwable, escalate the exception to the Master’s parent, which should really be an Akka “guaradian” actor/construct
The first part of this is that we need to know when an exception is thrown from the backup; I can handle this part, so let’s pretend our strategy now looks like this:
#Override
SupervisorStrategy supervisorStrategy() {
new OneForOneStrategy(10, Duration.minutes(“1 minute”, new Future<Throwable, SupervisorStrategy.Directive> {
#Override
Directive apply(Throwable t) throws Exception {
if(wasThrownFromBackup(t)) {
SupervisorStrategy.escalate()
} else if(isRecoverable(t) {
SupervisorStrategy.stop()
} else {
SupervisorStrategy.escalate()
}
}
})
}
But as you can see, I’m still struggling to implement the escalation “out of the actor system”. Ideas? Java code example greatly preferred as Scala looks like hieroglyphics to me.
Have a look at the 'Reaper' pattern here http://letitcrash.com/post/30165507578/shutdown-patterns-in-akka-2 Sorry it is in Scala but I think it is easy enough to translate to Java.
Also have a look here, https://groups.google.com/forum/#!topic/akka-user/QG_DL7FszMU
You should set in your configuration
akka.actor.guardian-supervisor-strategy = "akka.actor.StoppingSupervisorStrategy"
This will cause any 'top level' actor which escalates to be stopped by the system. Then you implement another top level actor called 'Reaper' (or whatever you want to call it) which has just one job, watch the main top level actor and take action (e.g. context.system.shutdown()) when the top level actor stops.
I don't know the akka java API so can't provide you with an exact example, but in Scala, from the LetItCrash blog above, it looks like:
import akka.actor.{Actor, ActorRef, Terminated}
import scala.collection.mutable.ArrayBuffer
object Reaper {
// Used by others to register an Actor for watching
case class WatchMe(ref: ActorRef)
}
abstract class Reaper extends Actor {
import Reaper._
// Keep track of what we're watching
val watched = ArrayBuffer.empty[ActorRef]
// Derivations need to implement this method. It's the
// hook that's called when everything's dead
def allSoulsReaped(): Unit
// Watch and check for termination
final def receive = {
case WatchMe(ref) =>
context.watch(ref)
watched += ref
case Terminated(ref) =>
watched -= ref
if (watched.isEmpty) allSoulsReaped()
}
}
class ProductionReaper extends Reaper {
// Shutdown
def allSoulsReaped(): Unit = context.system.shutdown()
}
In your application startup, you create your master actor, create your reaper, send a WatchMe(masterActor) message to the reaper.

What should the Java main method be for a standalone application (for Spring JMS)?

I am interested in creating a Spring standalone application that will run and wait to receive messages from an ActiveMQ queue using Spring JMS. I have searched a lot of places and cannot find a consistent way of implementing the main method for such a standalone application. There appears to be few examples of Spring standalone applications. I have looked at Tomcat, JBoss, ActiveMQ and other examples from the around the web but I have not come to a conclusion so ...
What is the best practice for implementing a main method for a Java application (specifically Spring with JMS) ?
Update:
Here's an example from: http://forum.springsource.org/showthread.php?t=48197
Is this the best way of doing this?
public static void main(String args[]) {
try {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
. . . . .
Object lock = new Object();
synchronized (lock) {
lock.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
When using Spring JMS you already use components/beans in your configuration that get auto-started and will stay alive (subscribe and read from queue/topic) until you stop the application.
To start and keep the application running, loading the applicationcontext should therefore be enough.
Good practice though is to also call the registerShutdownHook, so on a application halt (i.e via ctrl+c in the console), al your beans are gracefully shutdown and disposed :)
public static void main(String args[]) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
context.registerShutdownHook();
}
This is what we have, inside app-context.xml we use spring JMS classes like (org.springframework.jms.listener.DefaultMessageListenerContainer to manage number of consumers and provide custom listener using org.springframework.jms.listener.adapter.MessageListenerAdapter)
app-context.xml contains all spring beans listeners and other stuff, the code below is bootstrapping Spring provided listeners on queues. So idea is to use Spring classes to manage multiple consumers. Let me know if this is what you need and need more information on configuring MessageListenerAdapter.
public static void main(String[] args)
{
try
{
new ClassPathXmlApplicationContext("app-context.xml");
}
catch (Throwable e)
{
e.printStackTrace();
System.exit(-1);
}
}
The main idea is to make main thread wait until app will be finished.
while(!finished) is correct way to wait until main thread will be wake up.
finishEventHandler - is a method that handles finish/quit event.
I consider that JMS initialization is done in Spring conf. and in ". . . . ." section.
public static void main(String args[]) {
try {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
lock = new Object();
while(!finished) {
synchronized (lock) {
lock.wait();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void finishEventHandler() {
finished = true;
lock.notify();
}
In your main() do something like this:
// gather config files
String[] configs = { "classpath:applicationContext-myutil.xml" };
// create the app context
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(configs);
// obtain reference to your utility bean
MyUtilityBean utility = (MyUtilityBean) ctx.getBean("utility");
// invoke methods on your utility bean
utility.doSomething()
You would inject your Utiltity bean with Spring's JMS template to do the gruntwork for your usecase.
Attempt a read in a loop. If a message is found, process it, then sleep and iterate again. Also put some sort of terminator logic in there (interrupt the thread). You could terminate after X attempts, read from a file, kill the JVM, read a terminator msg from the queue, etc., etc.
public static void main(String[] args) {
while(true) {
// look for some terminator
// attempt to read off queue
// process message
try {
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {
break;
}
}
}

Categories