Can we wrap an interceptor around a JAX-RS ExceptionMapper? - exception

In my application, I have exception mappers for handling different exceptions. I need to somehow enforce the developers to pass the exception message from the toResponse(Exception e) method into a #RequestScoped Bean attribute for further use in the response filter chain.
Perhaps the interceptor may do the trick. However, the interceptor simply isn't getting invoked. Can someone help me understand why this is happening? Making the mapper a stateless session bean did not help either.
#Provider
#Interceptors(XYZInterceptor.class)
//#Stateless
public class ABCExceptionMapper implements ExceptionMapper<ABCException> {
public Response toResponse(ABCException exception) {
// When building response I want to force the developers to set the exception message to an attribute in a #RequestScoped Bean
}
}

Related

ConnectionFactory exception Camel testing JMS

I'm doing my first steps with Camel and currently working on writing a simple junit test using jms as a transport.
Here is a code I wrote:
public class FirstMockTest extends CamelTestSupport {
#Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("jms:topic:quote")
.to("mock:quote");
}
};
}
#Test
public void testMessageCount() throws InterruptedException {
MockEndpoint mockEndpoint = getMockEndpoint("mock:quote");
mockEndpoint.setExpectedMessageCount(1);
template.sendBody("jms:topic:quote", "Camel rocks");
mockEndpoint.assertIsSatisfied();
}
}
Because of missing connectionFactory I got the following exception:
org.apache.camel.FailedToCreateRouteException: Failed to create route route1: Route(route1)[[From[jms:topic:quote]] -> [To[mock:quote]]] because of connectionFactory must be specified
I'm able to fix it adding the following lines to my route:
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory("vm://localhost?roker.persistent=false");
context.addComponent("jms", JmsComponent.jmsComponent(connectionFactory));
But I don't like I'm adding some components to my context inside the route. Also, If i want to have another route I will need to do it again.
Obviously, there should be another way to tell my test about connection factory.
Thank you in advance!
It's a good idea to define the JMS connection factory outside of your Camel context and, if possible, reuse it. How to do that depends on your component model / execution environment.
If you're using a Java SE version that supports CDI, that would be an obvious choice. You'd define your JMS connection factory as a named component once and inject it everywhere you need it. Have a look at http://camel.apache.org/cdi.html and for testing support at http://camel.apache.org/cdi-testing.html
If you're using Spring, define your connection factory as a spring bean and inject it wherever you need it.
If you're using Java EE on an application server, you'd usually define the JMS connection factory using the mechanisms of that app server. You'd then look up the JMS connection factory using JNDI.
If you're running in an OSGi container, you should define the JMS connection factory in its own bundle and export it as an OSGi service. In the bundle of your Camel context, import that OSGi servide and inject it into the Camel context.
In all above cases you should consider using a pooled JMS connection factory.
For CDI, Spring and OSGi, have a look at: http://activemq.apache.org/maven/5.14.5/apidocs/org/apache/activemq/jms/pool/PooledConnectionFactory.html
For Java EE the way how to set pooling parameters depends on your app server.
Note of caution: for Java SE CDI and Spring there should be only one Camel context per application (you can have many routes, though). So if the JMS connection factory is only used in that one Camel context, there is not much reuse. Despite that I still think it's preferable to define the JMS connection outside of the Camel context in a separate component. It's, well, cleaner.
Since you are writing a junit you can avoid creating a ConnectionFactory if you stub the jms endpoint. You can name the endpoint as stub:jms:topic:quote. Have a look at sample example at link https://github.com/camelinaction/camelinaction2/blob/master/chapter9/mock/src/test/java/camelinaction/FirstMockTest.java

Best practise to handle exceptions between actor and client in service fabric

I am wondering what the best practise approach is to throwing/handling exceptions between Actors and clients within the service fabric.
I noticed for example that when an exception was thrown from an Actor the client received a nested set of exceptions. The outer exception is of type System.AggregateException and merely indicates that "One or more errors occurred". But if you drill down to the actual inner exceptions, you see that the exception that was thrown from the Actor cannot be serialized.
Test method PoCSystem.Test.CommandHandlerTest.CommandHandler_When_ExpectExceptionThrown threw exception:
System.AggregateException: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. --->
System.AggregateException: One or more errors occurred. ---> System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]:
Type 'PoCActor.Interfaces.ConcurrencyException' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.
If you then mark the Exception with DataContract and DataMember attributes the Exception then complains that it is not compatible with serialization.
What is the best approach for error handling in the service fabric?
Consider using old-school .net serializability. From the "Exception" code snippet built in to visual studio:
[Serializable]
public class MyException : Exception
{
public MyException() { }
public MyException(string message) : base(message) { }
public MyException(string message, Exception inner) : base(message, inner) { }
protected MyException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}

How can I handle exception raised during Castle Windsor optional property injection?

Castle Windsor 3.2 provides a cool addition that is Diagnostic logging in the container. This helped me redirect the container logs to a log4net log file that's being used to store the application logs.
What I'd like to do now is to be able to actually catch the Exception the container detects while injecting my optional property.
In my specific situation, an Oracle database error ORA-28000: the account is locked was being raised while Castle tried to execute my code to inject the Database property in a BaseController class:
public class BaseController : Controller
{
/// <summary>
/// Repository interface injected by Castle Windsor IoC container.
/// See <see cref="MyProject.Widgets.CastleWindsor.Facilities.PersistenceFacility.Init()"/> for more information.
/// </summary>
public ILogRepository Database { get; set; }
}
This Database property is null when I'm inside an action method in an Controller that inherits from BaseController. This all happens because Castle Windsor "swallows" the exception. The only message the user gets is: Object reference not set to an instance of an object. OK but I'd like to show the real exception/reason to the user, that is, ORA-28000: the account is locked. This message gets logged by Castle Windsor thanks to the aforementioned Diagnostic logging. This is cool but I want to be able to really catch the exception inside the catch block:
public class SubCatListController : BaseController
{
public ActionResult SubCatList(string subcat)
{
try
{
var sub = Database.GetLogSubCategory(subcat);
}
catch(Exception e) // I'd like to get the real exception from Castle Windsor here...
{
Logger.Error(e.Message, e);
}
}
}
Is this scenario possible with property injection?
As Krzysztof Kozmic mentioned in his comment we should not have any code that tries to do external object initialization while injecting a property.
My problem as I describe in this subsequent comment was that I was trying to open a database connection while initializing the property.
I removed that code and now the exception is only raised in my own domain code when that injected property is used for the 1st time.
Today I hit this same problem: one thing that helped me figure out the error was to momentarily use Constructor injection instead, like this:
private OEVizion _database;
public ReportingPeriodsController(OEVizion database)
{
_database = database;
}
Doing this I was able to see what was the error: version mismatch between log4net - the one in the OEVizion class library and the one used in the .Web project.
After getting the EF context correctly initialized I got back to Property injection and I'm back in business. :D
When you have optional dependencies it is always better to use the Null Object pattern.
public BaseController() {
Database = NullLogRepository.Instance;
}
It prevent the NullReferenceException and you can provide behavior you expect (do nothing, throw specific exception, log to trace etc.)

Consume application/json in REST services using Jersey in Osgi

I'm deploying some REST services in an Osgi bundle using Jersey. The services are notated like
#POST
#Path("/adduser")
#Consumes(MediaType.APPLICATION_XML+","+MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_XML)
public Message addUser(User user) {
...
}
The first problem I have is that the service doesn't accept both of the MIME types I put into the #Consumes notation but just the first one.
The second and worst is that receive the following exeception when I try to call to the services. I can #Consumes text/plain and I can #Produces application/xml for example but if I try to #Consumes an application/json or application/xml the server throw the exception.
The exception is throwed when I make the call with a wellformed json or xml using a REST client or an ajax call, if the service just receive text/plain or doesnt receive anything the response to the client is made correctly in xml so the serializer is working ok when I send POJO's but not receiving them.
javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.LinkageError: loader constraint violation: when resolving interface method "javax.xml.bind.Unmarshaller.unmarshal(Ljavax/xml/transform/Source;)Ljava/lang/Object;" the class loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) of the current class, org/glassfish/jersey/message/internal/XmlRootElementJaxbProvider, and the class loader (instance of <bootloader>) for resolved class, javax/xml/bind/Unmarshaller, have different Class objects for the type ject; used in the signature
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:353)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:96)
at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:79)
at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:42)
at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:49)
at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
at es.upm.cedint.gateway.api.corssupport.CORSFilter.doFilter(CORSFilter.java:164)
at es.upm.cedint.gateway.api.corssupport.CORSFilter.doFilter(CORSFilter.java:246)
at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:88)
at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:76)
at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:47)
at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
at es.upm.cedint.gateway.api.security.SecurityFilter.doFilter(SecurityFilter.java:87)
at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:88)
at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:76)
at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:47)
at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:48)
at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:39)
at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: org.glassfish.jersey.server.ContainerException: java.lang.LinkageError: loader constraint violation: when resolving interface method "javax.xml.bind.Unmarshaller.unmarshal(Ljavax/xml/transform/Source;)Ljava/lang/Object;" the class loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) of the current class, org/glassfish/jersey/message/internal/XmlRootElementJaxbProvider, and the class loader (instance of <bootloader>) for resolved class, javax/xml/bind/Unmarshaller, have different Class objects for the type ject; used in the signature
at org.glassfish.jersey.servlet.internal.ResponseWriter.rethrow(ResponseWriter.java:230)
at org.glassfish.jersey.servlet.internal.ResponseWriter.failure(ResponseWriter.java:212)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:401)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:243)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:322)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:211)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:979)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:344)
... 36 more
Caused by: java.lang.LinkageError: loader constraint violation: when resolving interface method "javax.xml.bind.Unmarshaller.unmarshal(Ljavax/xml/transform/Source;)Ljava/lang/Object;" the class loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) of the current class, org/glassfish/jersey/message/internal/XmlRootElementJaxbProvider, and the class loader (instance of <bootloader>) for resolved class, javax/xml/bind/Unmarshaller, have different Class objects for the type ject; used in the signature
at org.glassfish.jersey.message.internal.XmlRootElementJaxbProvider.readFrom(XmlRootElementJaxbProvider.java:140)
at org.glassfish.jersey.message.internal.AbstractRootElementJaxbProvider.readFrom(AbstractRootElementJaxbProvider.java:122)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:181)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:72)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:988)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:833)
at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:252)
at org.glassfish.jersey.server.internal.inject.EntityParamValueFactoryProvider$EntityValueFactory.get(EntityParamValueFactoryProvider.java:96)
at org.glassfish.jersey.server.internal.inject.AbstractHttpContextValueFactory.provide(AbstractHttpContextValueFactory.java:66)
at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:121)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:195)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:94)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:353)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:343)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:237)
... 45 more
Anyone have any idea of what could be wrong?
PD:I have #XMLRootElement at the begining of the User class that I want to serialize and the server I use is Jetty.
For the first question, I do not think you should have one function with two different signatures. I mean if you want to accept json or XML those are two different functions although they look the same from the java point of view. In your case I would create these three functions:
#POST
#Path("/adduser")
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
public Message addUserXML(User user) {
return addUserInternal(user);
}
#POST
#Path("/adduser")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_XML)
public Message addUserJSon(User user) {
return addUserInternal(user);
}
private Message addUserInternal(User user) {
...
}
As the second question: One of the worst thing that happened with Java 6 (in my opinion) is that they moved JAXB and other technologies into the JRE classpath. I guess you have also JAXB in one of your bundles. Jersey and the bundle that contains the REST API wire to different packages. One of them wires to the bundle that contains JAXB while the other wires to the boot classpath (package coming from JDK)
You can have two solutions (at least)
First solution
You exclude the JAXB packages from the boot classpath by configuring your OSGi environment.
Second solution
The packages coming from JDK have the version 0.0.0_jdkversion. The JAXB package coming from the bundle has a nicer and higher version like 2.1.1. You can edit the MANIFEST.MF of Jersey and your bundle to point to that version of the package.

Enterprise library exception handling problems with WCF services

my application consists of 3 layers and is very straightforward.
class library with all the business logic
WCF service that exposes the class library
asp.net web UI.
At the class library layer, I have an enterprise library exception handling policy defined so that it logs all exceptions to the database. In the underlying code, exceptions are thrown, and they coalesce up to the facade. In the facade, I trigger the EL policy to log the errors, and then I toggle a sucessStatus boolean in the response and have a method to convert all my exceptions to a friendly list so that the ultimate consumer can dig through this to get any idea of whats going on.
My facade in my class library sort of looks like this:
public SomeResponse DoSomething(SomeRequest request)
{
SomeResponse response = new SomeResponse();
try
{
response.data = SomeOperationThatWillThrowAnException;
}
catch (InvalidOperationException ex)
{
var exceptionManager = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();
exceptionManager.HandleException(ex, "StandardPolicy");
response.Errors.Add(Utility.ExceptionToError(ex));
response.SuccessStatus = false;
}
return response;
}
If I build a simple winform client and have it talk to my class library, this works.
However when I use the full stack, I get "fault exception was unhandled by user code". I can't seem to configure EL at the WCF layer in any way to keep this from happening.
My WCF service is just a simple wrapper for my class library facade.
public SomeResponse DoSomething(SomeRequest request)
{
return new MyFacade.DoSomething(request);
}
What I want is to have the class library handle the error silently, and not trigger any exceptions at the WCF or UI level. I want the consumer (in this case the ASP.NET webform UI) to have to check the response message contents to get a clue of what happened instead of having an exception stop execution dead in its tracks.
You likely have an error in your configuration file resulting in GetInstance() or HandleException() throwing an exception. Have you tried debugging the WCF service?