In our Java EE 6 application we're calling an action of a CDI Bean to search for a person. Inside this action there is a call to a webservice.
If the services throws an exception (not catched in CDI Bean action) the action is executed a second time. (If there is no exception the action is executed only one time).
Suddenly after the second action call, which throws the same exception, or ExceptionHandler gets called.
Why is the action called twice inside the invoke application phase and how can we get rid of the second call?
Related
I want to mock out a situation where if the service is called with a specific set of inputs, it should return a value, but if it's called with any other inputs throw an exception. So I've got:
doThrow(new ValidationException()).when(mockService).thing(any(), any());
when(mockService.thing(EXPECTED_PARAM_1, EXPECTED_PARAM_2).thenReturn(mockResult);
But when I go to run my test it throws the ValidationException on that second line where I'm creating the mock. It seems as though that second line is being treated as if I was actually calling the service, and since I'm mocking it with params that fit the any() any() it's throwing the exception rather than setting up the additional mock.
Thanks!
It turns out when.thenReturn actually calls the method it's mocking exactly once when the mock is first setup. Since the previous mock setup the default scenario where anytime the method is called it should thrown the exception, the second mock when it does its initial single call triggers the first mock and throws.
The solution to this scenario is to switch the second mock to use doReturn.when instead, as it never actually calls the method.
Update: I think is down to a Windsor configuration, does any one have any idea as to what I have not configured correctly with Windsor?
I am currently using Envers within a C# WebApi project. Windsor is used for IoC.
I have a custom RevisionEntity which add a User property to audit the user who has made the data change.
To ensure all configurations were correct I started off with a "simple string here" being added in the NewRevision method;
public class AuditRevisionListener : IRevisionListener
{
public void NewRevision(object revisionEntity)
{
((AuditRevision)revisionEntity).User = "Simple string here";
}
}
and all persisted as expected.
Next step is to achieve a full User object to which I need to obtain the UserService;
public class AuditRevisionListener : IRevisionListener
{
public void NewRevision(object revisionEntity)
{
var userServices = (IUserServices)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUserServices));
var user = userServices.GetRequestingUser();
((AuditRevision)revisionEntity).User = user;
}
}
However, the DependencyResolver.GetService is throwing the error;
"Cannot access a disposed object. Object name: 'Scope cache was already disposed. This is most likely a bug in the calling code.'. "
UPDATE
I have now created a demo project available at https://github.com/ScottFindlater/WindsorEnversIssue
On first setting up the solution all will run fine because the custom Envers RevisionListener is not performing any dependency resolving.
Run the solution which performs a GET to the HomeController, which simply loads one User and modifies another;
Dependency resolving is shown to be working as there is an ActionFilter called DependencyResolverDoesWork which successfully resolves the UserServices.
Envers is shown to be working as the UserAudit table is populated.
To “turn on” the dependency resolving in the customer RevisionListener navigate to; Domain NHibernate project, Auditing folder, AuditRevisionListener class, NewRevision method and uncomment the 2 lines of code.
Full rebuild and then run the solution again and the project will run time exception in the WindsorDependencyResolver class, GetService method with “Cannot access a disposed object”, and clicking the View Detail Action expands this message to “{"Cannot access a disposed object.\r\nObject name: 'Scope cache was already disposed. This is most likely a bug in the calling code.'."}”.
The comment posted by Roger, thank you so much, which suggests changing the LifeStyle to Singleton does work. However, this demo has been purposefully kept simple and the use of PerWebRequest LifeStyle is needed because the ApplicationServices in the real project has contextual related data injected such as requesting user which is used to enforce security.
I am so stuck now and any pointers/ answers as to what I have setup wrong will be gratefully received. In addition, I know this has been posted at SO and Envers forum, I WILL update an answer on both.
I think is down to a Windsor configuration, does any one have any idea as to what I have not configured correctly with Windsor?
I haven't tried to run your sample, but I think this is down to an interplay between the two http modules defined in your web.config (https://github.com/ScottFindlater/WindsorEnversIssue/blob/master/API%20Endpoints/Web.config)
Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule - Controls the lifetime of "per web request" components
APIEndpoints.HttpModules.NHibernateSessionCoordinator - Opens a session and begins a transaction at the beginning of each web request, then commits the transaction and disposes the session at the end of the web request
It is at the point where you commit your transaction - at the end of the request, triggered by NHibernateSessionCoordinator, that any changes you've made to objects within your NHibernate ISession actually get written to the database. This is the point at which Envers does its stuff and, in turn, at which you attempt to resolve IUserService from your Windsor container. The exception is thrown because IUserService is registered with the "per web request" lifestyle and Windsor is treating the current web request as complete and has disposed any objects tied to the request.
Have you tried reversing the order in which the HttpModules are defined, e.g. NHibernateSessionCoordinator before PerWebRequestLifestyleModule? This will result in your NHibernate transaction being committed before per web request components are disposed.
I have a spring mvc portlet that remotely calls an ejb 3. Now when the ejb throws an exception, on the portal side I just see 'EJB Exception'. I do not have access to the actual ejb 3 logs. So what can I do so that the whole exception stack trace is available on the portal side?
You can catch the EJBException (note that it's a RuntimeException, so, your code is not 'required' to catch it) and then call the getCausedByException method, to have access to the original exception. With it, you can do whatever you want, including rethrow it.
I am using Castle's DynamicProxy to intercept method calls. Before executing the target with
invocation.Proceed();
I check if the result is already in the cache. If so I do not want to call invocation.Proceed . However I do want to execute other interceptors for instance if there is a timing interceptor registered but because I am not calling invocation.Proceed if I found the results in the cache it never get's called. Is there a way around this? Or would I just have to add the timing interceptor to the caching interceptor as well?
Put caching interceptor last in the pipeline.
I have just implemented exception handling for a unique-constraint of a JPA entity. It is working as I want it to, but when triggered dumps the handled exceptions to the container logfile.
A JPA entity is managed by a SLSB (Service Façade). The Service Façade is called from another SLSB, which provides remoting capabilities based on JAX-RS.
In the Service Façade, the EntityManager operations are wrapped in a try-catch-block, detecting the cause of the unique-constraint-violation. It then throws a custom checked ApplicationException.
The REST-Bean catches the ApplicationException and throws a custom unchecked BadRequestException.
An ExceptionMapper outputs the BadRequestException to the remote client.
This is all working well. The part that I don't understand is: the (handled) exceptions get logged in the container's logfile (complete with a long stacktrace):
[#|2010-09-29T18:49:39.185+0200|WARNING|glassfish3.0.1|org.eclipse.persistence.session.file:/Users/hank/NetBeansProjects/CoreServer/build/classes/_coreServerPersistenceUnit|_ThreadID=30;_ThreadName=Thread-1;|
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry....
....
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry....
and from throwing the BadRequestException:
[#|2010-09-29T18:49:39.336+0200|WARNING|glassfish3.0.1|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=30;_ThreadName=Thread-1;|A system exception occurred during an invocation on EJB ShopperResource method public javax.ws.rs.core.Response mvs.gateway.ShopperResource.create(javax.xml.bind.JAXBElement)
javax.ejb.EJBException
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5119)
....
Caused by: mvs.api.exception.BadRequestException: mvs.api.exception.MvsCause: Field 'MSISDN' must be unique!
Is this how it should be? I thought since I handle the exceptions, they wouldn't be dumped to the log?
The exceptions are logged because you have exception logging enabled.
Exceptions get logged by default when your log level is WARNING or greater. If you set your log level to SEVERE or OFF then they will not be logged.
i.e.
"eclipselink.logging.level"="SEVERE"
You can also set the "eclipselink.logging.exceptions"="false" property to disable just exception logging.
See,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Logging
It's the database layer that does the logging of the exceptions. The time you catch them they are already written to the log.