I encountered a problem with logging exceptions using play framework.
Suppose, we have some runnable class RunnableClass, that can be initialized in Global class and can be executed in Executor service.
public class Global extends GlobalSettings {
#Override
public void beforeStart(Application app) {
Runnable runnableClass = new RunnableClass();
runnableClass.setSmth(new Smth());
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
scheduledExecutorService.scheduleAtFixedRate(runnableClass, 0, 1, TimeUnit.MINUTES);
}
}
Suppose, we need to operate with Smth class in run() method of RunnableClass.
private class RunnableClass implements Runnable {
private Smth smth;
public void setSmth(Smth smth) {
this.smth = smth;
}
#Override
public void run() {
smth.doSomething();
}
}
But for some reason we will not get here NullPointerExcception or any else exception. Obviously, that stack trace of this exception will be logged at least to console, but i see nothing either in console, nor in application.log file.
My version of play - 2.2.1, sbt launcher version - 0.13.0, application.conf file - default.
I tried next link:
http://www.playframework.com/documentation/2.0.x/SettingsLogger
Related
I have the requirement to use AWS Simple Workflow (SWF) for an orchestration type of system design. There is parent application that is start this child workflow then signal the workflow to work on activities. I have a workflow that starts up and waits for signals to happen before it can start doing activity work. Once one activity is done then it will report back to by closing out the activity on the parent workflow.
How do I wait for the signal and also use the results from another activity that was invoked by a signal?
Do I need to look into the execution history for the result of an activity and not rely on doing this work in the decide?
Thanks for the help
Code Example:
#SuppressWarnings("unused")
#Slf4j
public class ChildWorkflowImpl implements ChildWorkflow {
private final Settable<Message> firstStepReceived = new Settable<>();
private final Settable<Message> secondStepReceived = new Settable<>();
#Autowired
private FirstActivityClient firstActivityClient;
#Autowired
private SecondActivityClient secondActivityClient;
#Autowired
private AmazonSimpleWorkflow amazonSimpleWorkflow;
#Override
public void startWorkflow(SubsystemMessage subsystemMessage) {
//wait for signal to start
new Task(firstStepReceived) {
#Override
protected void doExecute() throws Throwable {
//Initiate Activity
startStage(firstStepReceived.get(););
}
};
//wait for second signal but pass in data from first activity
new Task(secondStepReceived) {
#Override
protected void doExecute() throws Throwable {
}
};
}
public void firstStep(Message message) {
Promise<FirstActivityResponse> firstActivity = firstActivityClient.execute();
//wait for signal for disable
new Task(firstActivity) {
public void doExecute() {
//report back status for stage by closing parent activity
}
};
}
public void secondStep(FirstActivityResponse response) {
Promise<SecondActivityResponse> secondActivityResponse = secondActivityClient.execute(response);
new Task(secondActivityResponse) {
public void doExecute() {
//report back status for stage
}
};
}
}
You add a signal method to the workflow interface and use Settable to notify the other part of the workflow code about the signal. See Settable documentation from this documentation page.
BTW. I recommend looking at temporal.io which is a greatly improved version of SWF which supports synchronous programming without all these pesky tasks.
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.
From this answer https://stackoverflow.com/a/25125159/4367326 I have routingAppender working but I want to set the ThreadContext for every thread in the program.
When I set
ThreadContext.put("logFileName", "TestLogFile");
it works for the main thread and logs as expected but not for any other threads in my application. How can I achieve this?
Every child thread will inherit fathers ThreadContext state if you set up system property isThreadContextMapInheritable to true. But this will not work for Executors so you need to manually copy data from one thread to another.
Update#2
You can do something like this:
public abstract class ThreadContextRunnable implements Runnable {
private final Map context = ThreadContext.getContext();
#Override
public final void run() {
if (context != null) {
ThreadContext.putAll(context);
}
try {
runWithContext();
} finally {
ThreadContext.clearAll();
}
}
protected abstract void runWithContext();
}
And then you only need to implement runWithContext method.
Let's say the class MyCoolProcess has the logic of my app which is needed to be called in it's own thread. We'll create a thread, call it and continue with the application.
This class is a EJB; annotated with #Stateless
Now we have the MyController class; which is going to call a new thread.
Code:
public class MyController {
#EJB
MyCoolProcess p;
public Response foo() {
Thread t = new Thread() {
public void run() {
p.run();
}
};
t.start();
// continues ...
}
}
#Stateless
public class MyCoolProcess {
public void run() {
// heavy task
}
}
That is working fine; the point is... before that solution I've tried with the Runnable interface. Which was I wanted at first time. The approach would be:
public class MyController {
#EJB
MyCoolProcess p;
public Response foo() {
Thread t = new Thread(p);
t.start();
// continues ...
}
}
#Stateless
public class MyCoolProcess implements Runnable {
#Override
public void run() {
// heavy task
}
}
That doesn't work. Actually, the server cannot start. Crashes trying to inject the dependencies. I'm not be able to implement the interface Runnable if I'm a EJB isn't it? WHY
And... is there any way to do the Runnable way instead the anonymous class?
From the EJB spec:
The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.
See Adam's Blog.
For my thesis I'm working on a Discrete Event System Simulator. The simulation consists in a set of SimulatorThread extends Thread whose action consist in scheduling Events to the Simulator. Each SimulatorThread interracts with the Simulator through the SimulatorInterface.
public abstract class SimulatorThread extends Thread {
private SimulatorInterface si;
public SimulatorThread(SimulatorInterface si) {
this.si = si;
}
...
}
public final class Simulator {
private ExecutorService exec;
...
public void assignThread(SimulatorThread... stList) {
...
}
}
Before the simulation begins, each SimulatorThread is assigned to the Simulator, then the Simulator will execute each thread through exec.execute(simulatorThread). My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption. Infact the output of System.out.print(Thread.currentThread().getClass()) is class java.lang.Thread, but I would like that the output is class SimulatorThread which can be obtained by running the thread using the instruction simulatorThread.start() instead of using the executor. So I thought that the problem is in writing an ad-hoc ThreadFactory that return an instance of SimulatorThread.
Infact I tried to use the trivial SimulatorThreadFactory extends ThreadFactory:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new SimulatorThread(new SimulatorInterface());
}
}
and with this I obtained the previously cited output 'class SimulatorThread'. The problem is that when I call 'exec.execute(simulatorThread)', the parameter has an attribute 'SimulatorInterface' to which I need to get access, but I can't becaues the parameter of the method 'newThread' is a 'Runnable'. I expose here a wrong code that I hope expresses what I mean better than how I explain in words:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
SimulatorInterface si = r.getSimulatorInterface(); // this is what
// I would like
// the thread factory
// to do
return new SimulatorThread(si);
}
}
So, how can I access to attribute 'SimulatorInterface' of the 'SimulatorThread' inside the method newThread in order to create a SimulatorThread if its paramater is a Runnable?
If I understand your needs, the right way to do this is to not extend Thread but to implement Runnable. Then all of the benefits of your own class hierarchy can be enjoyed:
public abstract class SimulatorRunnable extends Runnable {
protected SimulatorInterface si;
public SimulatorRunnable(SimulatorInterface si) {
this.si = si;
}
}
public final class Simulator extends SimulatorRunnable {
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
// here you can use the si
si.simulate(...);
}
}
Then you submit your simulator to your thread-pool:
Simulator simulator = new Simulator(si);
...
exec.submit(simulator);
My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption
You should not be passing a Thread into an ExecutorService. It is just using it as a Runnable (since Thread implements Runnable) and the thread-pool starts its' own threads and will never call start() on your SimulatorThread. If you are extending Thread then you need to call thread.start() directly and not submit it to an ExecutorService. The above pattern of implements Runnable with an ExecutorService is better.
#Gray's answer is correct, pointing out that the ExecutorService is designed to use its own threads to execute your Runnables, and sometimes created threads will even be reused to run different Runnables.
Trying to get information from (SimulatorThread) Thread.currentThread() smells like a 'global variable' anti-pattern. Better to pass the 'si' variable along in method calls.
If you really want global variables that are thread-safe, use ThreadLocals:
public final class Simulator extends SimulatorRunnable {
public static final ThreadLocal<SimulatorInterface> currentSim = new ThreadLocal<>();
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
currentSim.set(si)
try{
doStuff();
}
finally{
currentSim.unset();
}
}
private void doStuff()
{
SimulatorInterface si = Simulator.currentSim.get();
//....
}
}