I have some methods which throws some exception, and I want to use AspectJ around advise to calculate the execution time and if some exception is thrown and to log into error log and continue the flow by re-throwing the exception.
I tried to achieve this by following but eclipse says "Unhandled Exception type".
Code-against whom AspectJ is to used :-
public interface Iface {
public void reload() throws TException;
public TUser getUserFromUserId(int userId, String serverId) throws ResumeNotFoundException, TException;
public TUser getUserFromUsername(String username, String serverId) throws ResumeNotFoundException, TException;
public TResume getPartialActiveProfileFromUserId(int userId, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException;
public TResume getPartialActiveProfileFromUsername(String username, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException, TException;
}
Code AspectJ :-
public aspect AspectServerLog {
public static final Logger ERR_LOG = LoggerFactory.getLogger("error");
Object around() : call (* com.abc.Iface.* (..)) {
Object ret;
Throwable ex = null;
StopWatch watch = new Slf4JStopWatch();
try {
ret = proceed();
} catch (UserNotFoundException e) {
ex = e;
throw e;
} catch (ResumeNotFoundException e) {
ex = e;
throw e;
} catch (Throwable e) {
ex = e;
throw new RuntimeException(e);
} finally {
watch.stop(thisJoinPoint.toShortString());
if (ex != null) {
StringBuilder mesg = new StringBuilder("Exception in ");
mesg.append(thisJoinPoint.toShortString()).append('(');
for (Object o : thisJoinPoint.getArgs()) {
mesg.append(o).append(',');
}
mesg.append(')');
ERR_LOG.error(mesg.toString(), ex);
numEx++;
}
}
return ret;
}
}
Please help why this AspectJ is not working.
you can avoid catching the exceptions and just use a try/finally block without the catch.
And if you really need to log the exception you can use an after throwing advice, like this:
public aspect AspectServerLog {
public static final Logger ERR_LOG = LoggerFactory.getLogger("error");
Object around() : call (* com.abc.Iface.* (..)) {
StopWatch watch = new Slf4JStopWatch();
try {
return proceed();
} finally {
watch.stop(thisJoinPoint.toShortString());
}
}
after() throwing (Exception ex) : call (* com.abc.Iface.* (..)) {
StringBuilder mesg = new StringBuilder("Exception in ");
mesg.append(thisJoinPoint.toShortString()).append('(');
for (Object o : thisJoinPoint.getArgs()) {
mesg.append(o).append(',');
}
mesg.append(')');
ERR_LOG.error(mesg.toString(), ex);
}
}
I'm afraid you cannot write advice to throw exceptions that aren't declared to be thrown at the matched join point. Per: http://www.eclipse.org/aspectj/doc/released/progguide/semantics-advice.html :
"An advice declaration must include a throws clause listing the checked exceptions the body may throw. This list of checked exceptions must be compatible with each target join point of the advice, or an error is signalled by the compiler."
There has been discussion on the aspectj mailing list about improving this situation - see threads like this: http://dev.eclipse.org/mhonarc/lists/aspectj-dev/msg01412.html
but basically what you will need to do is different advice for each variant of exception declaration. For example:
Object around() throws ResumeServiceException, ResumeNotFoundException, TException:
call (* Iface.* (..) throws ResumeServiceException, ResumeNotFoundException, TException) {
that will advise everywhere that has those 3 exceptions.
There is an "ugly" workaround - I found them in Spring4 AbstractTransactionAspect
Object around(...): ... {
try {
return proceed(...);
}
catch (RuntimeException ex) {
throw ex;
}
catch (Error err) {
throw err;
}
catch (Throwable thr) {
Rethrower.rethrow(thr);
throw new IllegalStateException("Should never get here", thr);
}
}
/**
* Ugly but safe workaround: We need to be able to propagate checked exceptions,
* despite AspectJ around advice supporting specifically declared exceptions only.
*/
private static class Rethrower {
public static void rethrow(final Throwable exception) {
class CheckedExceptionRethrower<T extends Throwable> {
#SuppressWarnings("unchecked")
private void rethrow(Throwable exception) throws T {
throw (T) exception;
}
}
new CheckedExceptionRethrower<RuntimeException>().rethrow(exception);
}
}
Related
This is my code i want to call a method with another parameter with use of exception handling i want to sorround with try and catch my calling function. That Have a error of internal local variable is not assigned so i want to sorround it by try catch
how can i sorround a method calling with parameter
public void nik() {
System.out.println("nik or me ghar ja rhe he");
}
public int nik(int time) throws MyMagicExcep {
int a throw ;
System.out.println("nik or me "+a+time+" bje ghar jayege");
return 0;
}
public static void main(String[] args) {
first obj = new first();
// System.out.println();
obj.nik();
try{
System.out.println("harsh bhaiya mja nhi aaya");
obj.nik(1);}
catch(MyMagicExcep e) {
System.out.println("harsh bhaiya mja nhi aaya");
}
obj.nik();
}
}```
When I want just to add more context to any exception that has happened (including parsing errors and even out of memory) I write code as follows
try {
new JsonSlurper().parseText(response)
} catch (any) {
throw new IllegalStateException("Cannot parse response:\n$response", any)
}
This works fine, but I may end up with OutOfMemoryError being wrapped in IllegalStateException which doesn't sound right, as further there could be dedicated exception handling mechanism just for Error throwables.
Is there any way to just add more context to exception and still preserve its original type or category? I.e. when I get OOME, I want to rethrow Error, when I get some parsing exception, I want to rethrow some unchecked exception etc. And of course I don't want to do it manually for each category, as OOME is pretty unlikely and I don't want to produce special code for corner cases (while still I want to be technically correct).
You can definitely do this in groovy by using its metaprogramming features. In particular, for your case metaclasses provides everything you need. Using them you can dynamically add/attach a contextData object to the exception you want it to carry around:
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
Then to retrieve this contextData in other parts of the code, just inspect the exception object like this:
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
There I am using the argument contextDataHandler as a groovy Closure to handle contextData in a flexible manner.
The following is a full working demo of this:
import java.time.LocalDateTime
class ExceptionEnhancer {
static void main(String[] args) {
def logger = { println "${LocalDateTime.now()} - Context Data = [$it]" }
doSomethingWithContextData logger
}
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
public static void throwsBasicException() throws IOException {
throw new IOException();
}
}
Complete code on GitHub
Hope this helps.
I have a question , why does java keeps throwing that exception ! Is the problem with the stream ? because I handeled all IOExceptionS !
[[jio0yh.java:12: error: unreported exception IOException; must be
caught or declared to be thrown]]>>
That's the exception that I'm getting!
here is my code
import java.io.*;
public class jio0yh{
public static void main(String[]args){
FileInputStream OD=null;
try{
File f=new File("Binary.dat");
OD= new FileInputStream(f);
byte[]b=new byte[(int)f.length()];
OD.read(b);
for(int i=0;i<b.length;i++)
System.out.println(b[i]);
} catch(FileNotFoundException e){
System.out.println(e.getMessage());
} catch(IOException e){
System.out.println(e.getMessage());
OD.close();
}
}
}
The OD.close(); in your IOException catch block is also susceptible to throwing another IOException.
You should surround the final OD.close() in a finally block:
// ... Any previous try catch code
} finally {
if (OD != null) {
try {
OD.close();
} catch (IOException e) {
// ignore ... any significant errors should already have been
// reported via an IOException from the final flush.
}
}
}
Refer to the following for a more thorough explanation:
Java try/catch/finally best practices while acquiring/closing resources
I stumbled over this problem. Lets say i have an Func1 which parses some json string and returns the ServerState (Enum). For some reason the state cant be unknown by the Client or the JSON is bad for some reason.
How do i propagate the Exception from call Method ?
public static class ParseProgressFunction implements Func1<String, Observable<ServerState>> {
#Override
public Observable<ServerState> call(String progress) {
try {
final ServerState serverState = ServerParser.parseProgress(progress);
} catch (JSONException e) {
e.printStackTrace();
} catch (UnknownServerStateException e) {
e.printStackTrace();
}
}
}
This is the Idea i like to implement this:
#Override
public void onReceiveServerState(final Observable<String> state) {
state.flatMap(new ParseProgressFunction());
There must be some best practice, right ?
Happy Easter
As your function return an Observable, you can return a new error Observable with your exception.
return Observable.error(you exception);
I am looking for a way to catch all exceptions thrown by JUnit tests then re-throw them; to add more detail to the error message about the test state when the exception occurred.
JUnit catches errors thrown in org.junit.runners.ParentRunner
protected final void runLeaf(Statement statement, Description description,
RunNotifier notifier) {
EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
eachNotifier.fireTestStarted();
try {
statement.evaluate();
} catch (AssumptionViolatedException e) {
eachNotifier.addFailedAssumption(e);
} catch (Throwable e) {
eachNotifier.addFailure(e);
} finally {
eachNotifier.fireTestFinished();
}
}
This method is unfortunately is final so it cannot be overridden. Also as exceptions are being caught something like Thread.UncaughtExceptionHandler will not help. The only other solution I can think of is try/catch block around each test but that solution is not very maintainable. Could anyone point me to a better solution?
You could create a TestRule for this.
public class BetterException implements TestRule {
public Statement apply(final Statement base, Description description) {
return new Statement() {
public void evaluate() {
try {
base.evaluate();
} catch(Throwable t) {
throw new YourException("more info", t);
}
}
};
}
}
public class YourTest {
#Rule
public final TestRule betterException = new BetterException();
#Test
public void test() {
throw new RuntimeException();
}
}