For EventBus, I merged the code inside my java Spring app and have full control of it but the result didn't change.
When I run The EventBus in spring sts (javaw), there is no issue but when I run in the server with java -jar project.jar it gives the same SEVERE: Could not dispatch event: error
The below didn't work for me..
package edu.uams.event;
import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.Executor;
import org.apache.log4j.Logger;
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventHandler;
import com.google.common.eventbus.SubscriberExceptionHandler;
import edu.uams.domain.TirEvent;
import edu.uams.pacs.IncomingFileMonitor;
public class AysncTraumaEventBus extends AsyncEventBus {
private final static Logger logger = Logger.getLogger(AysncTraumaEventBus.class);
private String name = null;
public AysncTraumaEventBus(Executor executor,
SubscriberExceptionHandler subscriberExceptionHandler) {
super(executor, subscriberExceptionHandler);
logger.info("AysncTraumaEventBus created.");
}
public AysncTraumaEventBus(String name, Executor executor) {
super(name,executor);
this.name=name;
logger.info("AysncTraumaEventBus created. Name:"+this.name);
}
#Override
public void register(Object object) {
super.register(object);
}
#Override
public void unregister(Object object) {
super.unregister(object);
}
#Override
public void dispatch(Object event, EventHandler wrapper) {
try {
logger.info("Let's dispatch Aysnchroneous Trauma Event:"+ ((TirEvent) event).getResultMessage());
wrapper.handleEvent(event);
} catch (InvocationTargetException e) {
// My logger
logger.error("Could not dispatch event: " + event + " to handler " + wrapper+" e:"+e.getMessage());
logger.info("Lets try to disptach again!");
super.post(new ExceptionEvent(event, e));
}
}
public static final class ExceptionEvent {
public final Object event;
public final InvocationTargetException exception;
public ExceptionEvent(final Object event, final InvocationTargetException exception) {
this.event = event;
this.exception = exception;
}
}
}
Somehow the EventHandler can't invoke the target event..
wrapper.handleEvent(event);
When you look the wrapper (EventHandler):
public void handleEvent(Object event) throws InvocationTargetException {
checkNotNull(event);
try {
method.invoke(target, new Object[] { event });
} catch (IllegalArgumentException e) {
throw new Error("Method rejected target/argument: " + event, e);
} catch (IllegalAccessException e) {
throw new Error("Method became inaccessible: " + event, e);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof Error) {
throw (Error) e.getCause();
}
throw e;
}
}
You see that method.invoke(target, new Object[] { event }); throws the InvocationTargetException from the Method.class
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass(1);
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
Somehow it can't invoke.. But the most interesting part is that the same jar file along with EventBus can run fine in STS Run (javaw) but when I run java from commandline as java -jar project.jar it can't dispatch the event..
#Subscribe
#AllowConcurrentEvents
public void receivedDicomFile(TirEvent event){
try {
} catch (ClassNotFoundException e) {
logger.error(e.getMessage());
} catch (SQLException e) {
logger.error(e.getMessage());
} catch(Exception e){
logger.error(e.getMessage());
}
}
It always needs an try catch.. Thanks #dwnz for your help
Related
I have a similar problem as asked here - How to disable Redis Caching at run time if redis connection failed. My application is using #Cacheable at the service layer for most of the database/static resources call.
Cache is backed by Couchbase and whenever application fails to connect Couchbase node application goes down. Which is what we are not expecting, we expect data should be served from the source system whenever connection failed.
We tried implementing CacheErrorHandler but it does not work as expected because we want to execute the actual method which is making a service call and return the response rather than logging the Cache fail, basically bypassing the cache and as soon as the Couchbase node is up or connection established get the data from cache.
Any idea how we can achieve it?
Thanks #Daniel Bickler for the suggestion, below is the implementation I written referring #John Blum answer.
CouchbaseCustomCacheManager:
import java.util.Map;
import org.springframework.cache.Cache;
import com.couchbase.client.spring.cache.CacheBuilder;
import com.couchbase.client.spring.cache.CouchbaseCacheManager;
public class CouchbaseCustomCacheManager extends CouchbaseCacheManager {
public CouchbaseCustomCacheManager(
final Map<String, CacheBuilder> initialCaches) {
super(initialCaches);
}
#Override
public Cache getCache(String name) {
return new CouchbaseCacheWrapper(super.getCache(name));
}
protected static class CouchbaseCacheWrapper implements Cache {
private final Cache delegate;
public CouchbaseCacheWrapper(Cache couchbaseCache) {
this.delegate = couchbaseCache;
}
#Override
public String getName() {
try {
return delegate.getName();
} catch (Exception e) {
return null;
}
}
#Override
public Object getNativeCache() {
try {
return delegate.getNativeCache();
} catch (Exception e) {
return null;
}
}
#Override
public ValueWrapper get(Object key) {
try {
return delegate.get(key);
} catch (Exception e) {
return null;
}
}
#Override
public <T> T get(Object key, Class<T> type) {
try {
return delegate.get(key, type);
} catch (Exception e) {
return null;
}
}
#Override
public void put(Object key, Object value) {
try {
delegate.put(key, value);
} catch (Exception e) {
try {
handleErrors(e);
} catch (Exception e1) {
}
}
}
#Override
public ValueWrapper putIfAbsent(Object key, Object value) {
try {
return delegate.putIfAbsent(key, value);
} catch (Exception e) {
return null;
}
}
#Override
public void evict(Object key) {
try {
delegate.evict(key);
} catch (Exception e) {
try {
handleErrors(e);
} catch (Exception e1) {
}
}
}
#Override
public void clear() {
try {
delegate.clear();
} catch (Exception e) {
try {
handleErrors(e);
} catch (Exception e1) {
}
}
}
protected <T> T handleErrors(Exception e) throws Exception {
if (e instanceof Exception) {
return null;
} else {
throw e;
}
}
}
}
And used it as:
#Bean
public CacheManager cacheManager() {
final Map<String, CacheBuilder> cache = new HashMap<>();
for (final String appCache : "127.0.0.1,127.0.0.2,127.0.0.3".split(",")) {
cache.put(appCache, CacheBuilder.newInstance(CouchbaseCluster.create().openBucket(
"default", "")));
}
return new CouchbaseCustomCacheManager(cache);
}
I have an synchronous execution path which needs to either complete or timeout within a given time frame.
Let's say I have a class with a main() method in which I invoke method A(), which in-turn calls B(), and that in-turn calls C(), of the same or different classes, all synchronous, and without using an external resource like database , webservice, or file system (so not blocking IO, it's more like a CPU or memory intensive computation).
How do I code for its timeout in Java? I have looked at TimerTask but that is more of making the flow async and for scheduling tasks. Any other suggestions?
You should use ExecutorService to do that
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Callable() {
public String call() throws Exception {
//do operations you want
return "OK";
}
});
try {
System.out.println(future.get(2, TimeUnit.SECONDS)); //timeout is in 2 seconds
} catch (TimeoutException e) {
System.err.println("Timeout");
}
executor.shutdownNow();
You can run a parallel thread which will wait for the specified timeout and interrupt the current thread, and then run A(). However a, b and c must be interruptible, that is to check periodically current thread interrupted flag and throw InterruptedException, otherwise it wont work
final Thread current = Thread.currentThread();
Thread timer = new Thread() {
public void run() {
try {
Thread.sleep(5000);
current.interrupt();
} catch (InterruptedException e) {
// timer stopped
}
};
};
try {
A(); // this throws InterruptedException if interrupted by timer
timer.interrupt(); // no timeout lets stop the timer
} catch (InterruptedException e) {
// timeout
}
You can't do an synchronous call with a timeout but you can emulate it using a second thread. This is an example to do that:
package com.ardevco.example;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
class ExceptionThrower {
public static <R> R throwUnchecked(Throwable t) {
return ExceptionThrower.<RuntimeException, R> trhow0(t);
}
#SuppressWarnings("unchecked")
private static <E extends Throwable, R> R trhow0(Throwable t) throws E {
throw (E) t;
}
}
class TestApplicationException1 extends Exception {
private static final long serialVersionUID = 1L;
public TestApplicationException1(String string) {
super(string);
}
};
class TestApplicationException2 extends Exception {
private static final long serialVersionUID = 1L;
public TestApplicationException2(String string) {
super(string);
}
};
class TestApplicationTimeoutException extends Exception {
private static final long serialVersionUID = 1L;
public TestApplicationTimeoutException(String string) {
super(string);
};
}
public class SynchronousTimeoutTester {
public static final long SYNC_METHOD_TIMEOUT_IN_MILLISECONDS = 2000L;
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
public static void main(String[] args) {
SynchronousTimeoutTester tester = new SynchronousTimeoutTester();
/* call the method asynchronously 10 times */
for (int i = 0; i < 10; i++) {
try {
System.out.println("Result sync call: " + tester.getAsynchTest());
}
catch (TestApplicationException1 e) {
System.out.println("catched as TestApplicationException1: " + e);
}
catch (TestApplicationException2 e) {
System.out.println("catched as TestApplicationException2: " + e);
}
catch (TestApplicationTimeoutException e) {
System.out.println("catched as TestApplicationTimeoutException: " + e);
}
catch (InterruptedException e) {
System.out.println("catched as InterruptedException: " + e);
}
catch (Exception e) {
System.out.println("catched as Exception: " + e);
}
}
tester.shutdown();
}
private void shutdown() {
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}
catch (InterruptedException e) {
System.out.println("Error stopping threadpool:" + e);
}
}
private Integer testAsynch() throws TestApplicationException1, TestApplicationException2, InterruptedException {
Random random = new Random();
switch (random.nextInt(10)) {
case 0:
return 0;
case 1:
throw new TestApplicationException1("thrown TestApplicationException1");
case 2:
throw new TestApplicationException2("thrown TestApplicationException2");
case 3:
Thread.sleep(10000L);
return -1;
case 4:
throw new RuntimeException("thrown Exception");
default:
return random.nextInt(10);
}
}
private Integer getAsynchTest() throws TestApplicationException1, TestApplicationException2, Exception {
Integer dummy = null;
Future<Integer> testAsynchF = executorService.submit(
new Callable<Integer>() {
public Integer call() throws Exception {
return testAsynch();
}
});
try {
dummy = testAsynchF.get(SynchronousTimeoutTester.SYNC_METHOD_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS);
}
catch (ExecutionException e1) {
System.out.println("in getAsynchTest: ExecutionException: " + e1);
ExceptionThrower.throwUnchecked(e1.getCause());
}
catch (TimeoutException e1) {
System.out.println("in getAsynchTest: TimeoutException: " + e1);
throw new TestApplicationTimeoutException("TimeoutException" + e1);
}
catch (InterruptedException e1) {
System.out.println("in getAsynchTest: InterruptedException: " + e1);
throw new Exception(e1);
}
return dummy;
}
}
See also this post The approach is let your application care of timeout inside its logic. For that you can define some timer class and special checking method, e.g.:
public class TimeoutApp {
MyTimer timer;
Thread timerThread;
public static void main(String... args) {
new TimeoutApp().execute();
}
private void execute() {
try {
startTimer(1000);
action1();
checkTimeout();
action2();
checkTimeout();
action3();
stopTimer();
} catch (MyTimeoutException e) {
System.out.println("Interrupted on timeout!");
// ...clearing code if needed
System.exit(1);
} catch (InterruptedException e) {
System.out.println("Interrupted by exception!");
// ...clearing code if needed
e.printStackTrace();
System.exit(1);
}
}
private void action1() throws InterruptedException {
Thread.sleep(600);
System.out.println("action 1");
}
private void action2() throws InterruptedException {
Thread.sleep(500);
System.out.println("action 2");
}
private void action3() {
System.out.println("action 3");
}
private void checkTimeout() throws MyTimeoutException {
if (timer.isTimeoutReached()) {
throw new MyTimeoutException();
}
}
private void startTimer(long timeout) {
timer = new MyTimer(timeout);
timerThread = new Thread(timer);
timerThread.start();
}
private void stopTimer() {
timerThread.interrupt();
}
private class MyTimer implements Runnable {
private long timeout;
private boolean timeoutReached = false;
public MyTimer(long timeout) {
this.timeout = timeout;
}
public void run() {
long time = System.currentTimeMillis();
while (!timeoutReached && !Thread.interrupted()) {
if ((System.currentTimeMillis() - time) > timeout) {
timeoutReached = true;
}
}
}
public boolean isTimeoutReached() {
return timeoutReached;
}
}
private class MyTimeoutException extends Exception {
}
}
I'm computing a future for having a timeout in waiting for a serial event to happen:
Future<Response> future = executor.submit(new CommunicationTask(this, request));
response = new Response("timeout");
try {
response = future.get(timeoutMilliseconds, TimeUnit.MILLISECONDS);
} catch (InterruptedException | TimeoutException e) {
future.cancel(true);
log.info("Execution time out." + e);
} catch (ExecutionException e) {
future.cancel(true);
log.error("Encountered problem communicating with device: " + e);
}
The CommunicationTask class has implemented the Observer interface to listen to an change from the serial port.
The problem is that reading from the serial port is relatively slow and even when a serial event is happening the time runs out and a TimeoutException is thrown. What can I do to stop the timeout clock of my future when a serial event is happening?
I tried it with an AtomicReference but that didn't change anything:
public class CommunicationTask implements Callable<Response>, Observer {
private AtomicReference atomicResponse = new AtomicReference(new Response("timeout"));
private CountDownLatch latch = new CountDownLatch(1);
private SerialPort port;
CommunicationTask(SerialCommunicator communicator, Request request) {
this.communicator = communicator;
this.message = request.serialize();
this.port = communicator.getPort();
}
#Override
public Response call() throws Exception {
return query(message);
}
public Response query(String message) {
communicator.getListener().addObserver(this);
message = message + "\r\n";
try {
port.writeString(message);
} catch (Exception e) {
log.warn("Could not write to port: " + e);
communicator.disconnect();
}
try {
latch.await();
} catch (InterruptedException e) {
log.info("Execution time out.");
}
communicator.getListener().deleteObserver(this);
return (Response)atomicResponse.get();
}
#Override
public void update(Observable o, Object arg) {
atomicResponse.set((Response)arg);
latch.countDown();
}
}
What can I do to solve this problem?
EDIT:
Ok I had one error. I was counting down my latch befor setting the atomicResponse in my update function. Now it seems to work, but there's still the question if this approach is the right way to do so?
have you explored google's Guava 'future listener', it is based on Async future, hope following code snippet helps you....
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
public class SyncFutureExample {
public static void main(String[] args) {
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
ListenableFuture<String> lf = service.submit(new CommuncationTask());
//no need for future.get() or future.get(10,time minutes)
//add callbacks(= async future listeners) ....
Futures.addCallback(lf, new FutureCallback<String>() {
public void onSuccess(String input) {
System.out.println(input + " >>> success");//gets a callback once task is success
}
public void onFailure(Throwable thrown) {
System.out.println(thrown + " >>> failure");//gets a callback if task is failed
}
});
service.shutdown();
}
}
class CommuncationTask implements Callable<String>{
public String call() throws Exception {
TimeUnit.SECONDS.sleep(15);// some dummy serious task .............
return "TaskDone";
}
}
Hope this will help. I won't comment on it in the hopes that everything is clear from the code.
class CommunicationTask implements Callable<String>, Observer {
volatile boolean ignoreTimeoutException;
public CommunicationTask(SerialCommunicator communicator, Request request) {
}
public String call() throws Exception {
Thread.sleep(1000);
return "done";
}
public void update(Observable o, Object arg) {
ignoreTimeoutException = true;
}
}
class FutureCommunicationTask extends FutureTask<String> {
private CommunicationTask ct;
public FutureCommunicationTask(CommunicationTask ct) {
super(ct);
this.ct = ct;
}
public String get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
try {
return super.get(timeout, unit);
} catch (TimeoutException e) {
if (ct.ignoreTimeoutException) {
return get(); // no timeout wait
}
throw e;
}
}
}
public class Test {
public static void main(String[] args) throws Exception {
CommunicationTask ct = new CommunicationTask(null, null);
FutureTask<String> fct = new FutureCommunicationTask(ct);
ExecutorService ex = Executors.newSingleThreadExecutor();
ex.execute(fct);
// uncomment this line and timeout will be cancelled
ct.update(null, null);
String res = fct.get(1, TimeUnit.MILLISECONDS);
System.out.println(res);
}
}
public class Test {
public static void main(String[] args) {
try {
doSomething(new TestCallback() {
#Override
public void doCallback() {
throw new NullPointerException();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public static void doSomething(TestCallback callback){
callback.doCallback();
}
interface TestCallback {
public void doCallback();
}
}
RESULT:
java.lang.NullPointerException
at managers.concurrency.Test$1.doCallback(Test.java:11)
at managers.concurrency.Test.doSomething(Test.java:20)
at managers.concurrency.Test.main(Test.java:8)
In the above code we will get NullPointerException because the callback code is executed in the different part of stack. Is there a way to catch the such exceptions locally?
You are already catching the exception. Try something as follows -
try {
doSomething(new TestCallback() {
#Override
public void doCallback() {
throw new NullPointerException();
}
});
} catch (Exception e) {
System.out.println("Exception caught !!!");
}
Output:
Exception caught !!!
I'm currently developing a system that loads classes via rmi. This system uses a classloader that communicates with the server in order to get the classes. The code is as follows.
Server:
import rocks.squareRock;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server extends UnicastRemoteObject
implements RemInterface {
public Server() throws RemoteException {
super();
}
public static void main(String argv[]) {
try {
Server serv = new Server();
Naming.rebind("RockServer", serv);
} catch (Throwable t) {
t.printStackTrace();
}
}
public Class<?> getRockClass(String type) {
if (type.equals("squareRock"))
return squareRock.class;
else
return null;
}
}
Client:
import rocks.Rock;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class Client {
RemInterface reminterface = null;
RockLoader rl = null;
public Client() {
String strName = "rmi://127.0.0.1/RockServer";
try {
reminterface = (RemInterface) Naming.lookup(strName);
rl = new RockLoader(reminterface);
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
loadRock("squareRock");
}
public Rock loadRock(String rock) {
try {
return (Rock) rl.loadClass(rock, false).newInstance();
} catch (Throwable t) {
return null;
}
}
}
Interface:
public interface RemInterface {
public Class<?> getRockClass(String type) throws RemoteException;
}
RockLoader:
import java.io.Serializable;
public class RockLoader extends ClassLoader implements Serializable {
private RemInterface reminterface = null;
public RockLoader(RemInterface reminterface) {
super();
this.reminterface = reminterface;
}
#Override
protected synchronized Class<?> loadClass(String className, boolean resolve)
throws ClassNotFoundException {
try {
return reminterface.getRockClass(className);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
The error I'm getting with this is (client-side):
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: SquareRock
This confuses me, as I'm not unmarshalling a SquareRock instance, but a Class. The only thought I have is that my classloader might be wrong.
It doesn't matter whether it's a Class or an object. The receiving JVM must have that class in its classpath, unless you are using the RMI codebase feature. What you are doing is basically trying to implement the codebase feature yourself. You can't do that.