I've a Remote SLSB that is deployed in OC4J.
This Session Bean uses TopLink which under some case throws oracle.toplink.essentials.exceptions.QueryException exception.
I am handling this exception this way:
public void slsbMethod()
{
try
{
// oracle.toplink.essentials.exceptions.QueryException throws here
}catch(Exception ex)
{
// do nothing
}
}
And I am calling this SLSB from a client that way:
try
{
fooBarService.slsbMethod()
}catch(Exception ex)
{
System.out.println("Exception calling the EJB server");
}
However I am handling this exception on the EJB, still I got the message Exception calling the EJB server printed!
How is this happening??
If the exception is coming from container-managed transaction code, then I would suggest using bean-managed transactions. With that, you can put the exception handling in the bean around the call to UserTransaction.commit. Alternatively, you could write an interceptor to begin the transaction, call InvocationContext.proceed(), and then commit the transaction and handle exceptions as you like. This is basically what the container is doing for you, but you can handle the commit exception as you like, and you can reuse the logic on other beans/methods.
Related
I saw many people wrote like:
try {
//something
}
catch (IOException e){
throw new SystemException("IO Error", e);
}
I got "Cannot instantiate the type SystemException" error and it seems SystemException is a abstract class, how can I able to throw it?
Yes, it is an abstract class and that means that it does not make sense to construct an object of type SystemException. It is recommended to use more meaningful exceptions types.
You have mentioned IOException in your code. This means an exception related to an I/O operation and the catcher can act accordingly (maybe a special log level, some I/O cleanup etc.).
In your particular case, I think you should change it to:
try {
//something
}
catch (IOException e) {
// log exception info and other context information here
// e.g. e.printStackTrace();
// just rethrowing the exception (call stack is still there)
throw e;
}
P.S. Quite offtopic, but coming from .NET world I have found about the subtle difference between throw ex; in C# vs. Java.
I have this scenario in which some tests can throw different exceptions.
#Test
public void addDevice(){
device.addDevice(); // this may throw exception 1
device.verifyStatus("Ready");
device.open(); // this may throw exception 2
device.verifyStatus("Open");
}
#Test
public void otherTest(){
device.act(); // this may throw exception 3
device.verifyStatus("Ready");
}
#After
public void tearDown(){
// handle the exception here
}
I want to handle those exceptions in the #After section without wrapping the test with try, catch.
Is that possible?
No, it is not possible.
You could wrap the test anyway with a try-catch-block. Then you could store the exception to a member variable instead of handling it.
In the #After method you can check whether the exception is null or not.
Due to your comment that you have hundreds of tests with this code I assume that this is set up logic which should actually be in an #Before method.
Thus, you could specify an external resource rule with a before and after method: https://github.com/junit-team/junit/wiki/Rules#externalresource-rules
In the before() method you perform the set up, catch and store the exceptions and in the after() method you handle them.
But does it make sense to handle the exception later? Can you run your test cases successfully if the set up fails?
I have an Entity Manager in my EJB
#PersistenceContext(unitName = "cnsbEntities")
private EntityManager em;
I populate an object and then I commit it in my DB, but if I have an exception, for duplicate ID, I can't catch it and I don't know why.
try{
em.merge(boelLog);
} catch (Exception e){
System.out.println("Generic Exception");
}
JPA uses transactions to send entity modifications to the database. You can specify those transactions manually through Bean Managed Transactions (BMT) or let the application server do it for you (Container Managed Transactions; the default).
So, you need to catch the exception at the end of the transaction, and not after calling merge() or persist() methods of EntityManager class. In your case, probably the transaction will end when you return from the last EJB object.
Example for Container Managed Transactions (the default):
#Stateless
public class OneEjbClass {
#Inject
private MyPersistenceEJB persistenceEJB;
public void someMethod() {
try {
persistenceEJB.persistAnEntity();
} catch(PersistenceException e) {
// here you can catch persistence exceptions!
}
}
}
...
#Stateless
public class MyPersistenceEJB {
// this annotation forces application server to create a new
// transaction when calling this method, and to commit all
// modifications at the end of it!
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void persistAnEntity() {
// merge stuff with EntityManager
}
}
It's possible to specify when a method call (or any method call of an object of an EJB) must, can or must not create a new transaction. This is done through the #TransactionAttribute annotation. By default, every method of an EJB is configured as REQUIRED (same as specifying #TransactionAttribute(TransactionAttributeType.REQUIRED)), that tells the application to reuse (continue) the transaction that is active when that method was called, and create a new transaction if needed.
More about transactions here: http://docs.oracle.com/javaee/7/tutorial/doc/transactions.htm#BNCIH
More about JPA and JTA here: http://en.wikibooks.org/wiki/Java_Persistence/Transactions
Using Groovy / Grails and log4j is there any way to ensure every exception thrown in the code is logged at error level.
Rather than having to find every catch block and explictly log it?
If not groovy / grails - a java suggestion will suffice.
Thanks
I don't believe there's any way to do this for handled exceptions, but you can do it for unhandled exceptions by adding the following to UrlMappings.groovy
"500"(controller: 'error')
Then create an ErrorController.groovy under grails-app/controllers
class ErrorController {
def index() {
Throwable exception = request?.exception?.cause
log.error 'something bad happened', exception
}
}
(version: Netty 4.0.4.Final)
If an exception rises in ChannelInboundHandler, I can handle it in exceptionCaught() method but if the exception rises in ChannelOutboundHandler, I can't. Because, exceptionCaught() is not a call. Why is this so?
There is only way to handle outbound exception by analize Future result like this:
channel.writeAndFlush(serverPacket).addListener(new ChannelFutureListener() {
#Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
future.cause().printStackTrace();
}
}
});
But it is very inconveniently.
It's by design... Outbound operations only are notified via the Future as otherwise we would need to do double notifications which has some performance penalty. If you want to to have it propagated to the exceptionCaught handler you can just add the ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE as Listener to the returned ChannelFuture.