Why doesn't Apache CXF write a custom exception to response? - java

while implementing a SSL-secured WebService with Apache CXF v2.7.3 I wanted to test how a custom exception class (e.g. MyException) is handled by the client.
Therefore I have the following server-side method:
#WebMethod
public void foo() throws MyException {
throw new MyException("test!");
}
I have also configured to log in- and outgoing messages in the cxf.xml via:
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<jaxws:inInterceptors>
<ref bean="logInbound"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="logOutbound"/>
</jaxws:outInterceptors>
Calling this function with a client results in following console-output
INFO: Inbound Message
----------------------------
ID: 1
Address: https://localhost:8443/WebApp/services/ClientService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[184], content-type=[text/xml; charset=UTF-8], host=[localhost:8443], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 2.7.3]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:foo xmlns:ns2="http://services.client.test.cloud.org/"/></soap:Body></soap:Envelope>
--------------------------------------
18.02.2013 22:49:02 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
INFO: Application {http://services.client.test.cloud.org/}ClientService#{http://services.client.test.cloud.org/}foo has thrown exception, unwinding now: org.cloud.test.client.exception.MyException: test!
18.02.2013 22:49:02 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
INFO: Application {http://services.client.test.cloud.org/}ClientService#{http://services.client.test.cloud.org/}foo has thrown exception, unwinding now: java.lang.NullPointerException: null
The client gets a "Error reading XMLStreamReader." due to a "Unexpected EOF". I guess, that no response is written by the server. Do you know why 2 exceptions are thrown and why there isn't any response to the client?
I already searched for exceptions not redirected to the client in Apache CXF-applications, but could not find any solution.
Thanks in advance!

Related

Catch error java response from endpoint in Mule

I have an engine set up that validates an xml at a given endpoint.
localhost/rules/my-rule, if the xml file is consistent it returns the xml content. If not however, an exception is thrown:
GeneralException: Combination missmatch
Which is an exception I declared. It's a normal Java Exception.
When I post a faulty file with a tool like postman I get this result:
Can't invoke perform method on "class %rule class%" with request data of
"%data sent to endpoint%"
(reason: ch.package.GeneralException: Combination missmatch). Combination missmatch
Which would be perfect. However upon sending it with mule I get:
Route 0: Caught exception in Exception Strategy: HTTP POST on resource 'http://localhost/rules/my-rule/executions' failed: bad request (400).
Why can't I just get the error message? There isn't more insight when looking at the log:
org.mule.runtime.core.internal.message.ErrorBuilder$ErrorImplementation
{ description=HTTP POST on resource
'http://localhost/rules/my-rule/executions'
failed: bad request (400). detailedDescription=HTTP POST on resource
'http://localhost/rules/my-rule/executions'
failed: bad request (400). errorType=HTTP:BAD_REQUEST
cause=org.mule.extension.http.api.request.validator.ResponseValidatorTypedException
errorMessage=
org.mule.runtime.core.internal.message.DefaultMessageBuilder$MessageImplementation
{
payload=org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamProvider#3239ebf7
mediaType=text/plain; charset=UTF-8
attributes=org.mule.extension.http.api.HttpResponseAttributes {
Status Code=400 Reason Phrase= Headers=[
content-type=text/plain
transfer-encoding=chunked
date=Wed, 03 Jul 2019 07:16:19 GMT
connection=close ] } attributesMediaType=/ } childErrors=[] }] }
My flow configutation:
<scatter-gather doc:name="Distribute workload" doc:id="15151949-c61d-4629-9fd4-0a4e16d62eec" >
<route >
<!--Access to localhost/rules/my-rule>
<flow-ref doc:name="CategoryToType" doc:id="e5d39afa-3b2a-45ef-81c0-afce77a76aef" name="validateCategoryToType" />
</route>
</scatter-gather>
<error-handler>
<on-error-propagate enableNotifications="true" logException="true" doc:name="On Error Propagate" doc:id="16001c58-7609-42a6-9bfa-1cd756998f27" >
<logger level="INFO" doc:name="Logger" doc:id="8ec2af18-3e45-4d15-a373-5e9af74723d7" message='#[error]'/>
</on-error-propagate>
</error-handler>
<sub-flow name="validateCategoryToType" doc:id="da38db3a-7d51-4fd1-bd06-9e58b872d468" >
<foreach doc:name="For Each" doc:id="ff9944ba-5f87-4a5a-9392-a4b27c2f5fb0" collection="payload.Kunden" rootMessageVariableName="Kunden">
<ee:transform doc:name="Transform Message" doc:id="f33fa5ea-0b4d-4ac5-a247-90fd6978248d">
<ee:message>
<ee:set-payload>
<!--Some transformy stuff-->
</ee:set-payload>
</ee:message>
</ee:transform>
<http:request method="POST" doc:name="Request" doc:id="53df928a-4fd1-4125-88e0-be73b006beee" config-ref="HTTP_Request_configuration" path="/rules/my-rule/execution>
<http:headers><![CDATA[#[output application/java
---
{
"Content-Type" : "application/xml",
"Accept" : "application/xml"
}]]]></http:headers>
</http:request>
<logger level="INFO" doc:name="Logger" doc:id="cc02312e-b71b-461c-bba0-077bfb1e9b7e" message="#[payload]" />
</foreach>
</sub-flow>
Use Global error handler, i have composed HTTP error request for you. You can expand it to other error types like API tool kit etc..
Also, extend further error messages by creating variables and capture postman payload into a variable
<on-error-propagate type="HTTP:BAD_REQUEST"
enableNotifications="true" logException="true" doc:name="On Error Propagate"
doc:id="73b29eaf-ebcd-4857-baea-4c2fb963b055">
<set-variable value="#[400]" doc:name="HTTP Status - 400"
doc:id="4017a80c-f968-4f09-8fbb-eaa4ce5d1413" variableName="httpStatus" />
<set-variable
value="Service is unable to handle request"
doc:name="errorMessage" doc:id="9ab2b50b-7aad-4460-b276-f5d50ffd1efe"
variableName="errorMessage" />
<ee:transform doc:name="Transform Message" doc:id="df98f927-584c-454e-971e-79d2ff1e842d" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
error: {
errorCode: error.errorType.identifier,
errorDateTime: now() as String { format: "yyyy-MM-dd'T'HH:mm:ss" },
errorDescription: error.description
}]]></ee:set-payload>
</ee:message>
</ee:transform>
<ee:transform doc:name="Transform Message" doc:id="6e6c0017-2b23-4bfa-83ef-2f77cc25aa08" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
</on-error-propagate>

MissingSessionUser Exception in Sockjs with Spring

I am trying to make a chat application with WebSocket. I am able to send a message to all the connected clients, and now I am trying to send a message to a single user.
script:
var socket = new SockJS("server endpoint");
subscribe:
stompClient.subscribe('/topic/chat', renderMessage);
connection:
stompClient.connect("guest", "guest", connectCallback, errorCallback);
where it's sent:
stompClient.send("/app/addMessage", {}, jsonstr);
and in my spring config:
<websocket:message-broker
application-destination-prefix="/app">
<websocket:stomp-endpoint path="/ws">
<websocket:sockjs />
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic" />
<websocket:client-inbound-channel>
<websocket:interceptors>
<bean class="com.websocket.interceptor.ConnectionInterceptor" />
</websocket:interceptors>
</websocket:client-inbound-channel>
</websocket:message-broker>
method that is trying to send to a single user:
#MessageMapping("/addMessage")
public void addChatMessage(ChatMessage chatMessage,
SimpMessageHeaderAccessor headerAccessor,Principal principal) throws Exception {
chatMessageList.add(chatMessage);
//trying to output the user but returns null
System.out.println(headerAccessor.getUser());
//returns null
System.out.println(principal.getName());
//not sending to the current user
template.convertAndSendToUser("user", "/topic/chat", chatMessageList);
}
and in my browser, I tried to open the console and I can see that the header is undefined:
connected to server undefined
>>> SUBSCRIBE
id:sub-0
destination:/topic/chat
stack trace:
Oct 13, 2014 9:53:36 AM org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler processHandlerMethodException
SEVERE: Unhandled exception
org.springframework.messaging.simp.annotation.support.MissingSessionUserException: No "user" header in message
at org.springframework.messaging.simp.annotation.support.PrincipalMethodArgumentResolver.resolveArgument(PrincipalMethodArgumentResolver.java:43)
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:81)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:128)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:97)
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:451)
at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:363)
at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:80)
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:409)
at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:345)
at org.springframework.messaging.support.ExecutorSubscribableChannel$1.run(ExecutorSubscribableChannel.java:70)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
How can I send to a single user? How can I get all the headers in my SimpMessageHeaderAccessor? And how headers actually work?
When you subscribe you need to use "/user/" prefix to make it recognized by Spring UserDestinationMessageHandler. So the code will be :
stompClient.subscribe('user/topic/chat', renderMessage);
See Spring Websocket user destinations.

Polling HTTP endpoint followed by jersey REST WS does not work in Mule 3.5

I have a requirement where i need to poll a rest service and then proxy the response from this web service on to a REST web service.
I am using Mule 3.5 and my flow looks like the below.
I get the below exception where the REST service is being invoked
********************************************************************************
Message : Failed to invoke JerseyResourcesComponent{TestFlow.component.1106552446}. Component that caused exception is: JerseyResourcesComponent{TestFlow.component.1106552446}. Message payload is of type: String
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. null (java.lang.NullPointerException)
org.mule.module.jersey.JerseyResourcesComponent:192 (null)
2. Failed to invoke JerseyResourcesComponent{TestFlow.component.1106552446}. Component that caused exception is: JerseyResourcesComponent{TestFlow.component.1106552446}. Message payload is of type: String (org.mule.component.ComponentException)
org.mule.component.AbstractComponent:144 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/component/ComponentException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.NullPointerException
at org.mule.module.jersey.JerseyResourcesComponent.getBaseUri(JerseyResourcesComponent.java:192)
at org.mule.module.jersey.JerseyResourcesComponent.doInvoke(JerseyResourcesComponent.java:146)
at org.mule.component.AbstractComponent.invokeInternal(AbstractComponent.java:122)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
After debugging i figured out it is because Mule expects the MuleMessage inbound property for contextPath to be populated however in this case it is null.
In JerseyResourcesComponent line 117 is returned as null and hence line 195 throws a NPE.
I wanted to know if this kind of requirement/pattern is invalid or is it some kind of limitation in the way Mule is handling its messaging infrastructure ?
The flow xml just in case you want to inspect it.
<flow name="TestFlow" doc:name="TestFlow">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="10" timeUnit="SECONDS" startDelay="10"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8080" doc:name="Order Generator" method="GET" contentType="application/json" path="order"/>
</poll>
<object-to-string-transformer doc:name="Object to String"/>
<jersey:resources doc:name="Tax Calculator">
<component class="org.nthdimenzion.TaxCalculator"/>
</jersey:resources>
<logger level="INFO" doc:name="Logger"/>
</flow>
PS : The work around i got was to use a java/spring component instead of a REST WS and then call the REST WS from the Java component.

How can I turn off extra logging?

I have a Java service that uses Spring and CXF. The code is from a previous developer and I'm providing maintenance, but I'm seeing this in the logs
--------------------------------------
Apr 16, 2013 1:44:11 PM org.apache.cxf.interceptor.AbstractLoggingInterceptor log
INFO: Inbound Message
----------------------------
ID: 33
Address: /MyApplication/endpoint
Encoding: UTF-8
Http-Method: POST
Content-Type: application/x-www-form-urlencoded
Headers: {content-type=[application/x-www-form-urlencoded], connection=[close], host= [localhost:8080], Content-Length=[11504], user-agent=[Apache-HttpClient/4.2.3 (java 1.5)], Content-Type=[application/x-www-form-urlencoded]}
Payload: {
"events" :
[ { event }, { event }, ... ]
}
And we have too many events, and the log is becoming unmanageable. Is there a way I can turn off this logging? These log calls are not created from inside the app, they are created by some kind of interceptor which I can't find. I did find this in the cxf-context.xml config file:
<cxf:bus>
<cxf:features>
<cxf:logging />
</cxf:features>
</cxf:bus>
But the logging still appears after I already commented these lines out of the config file.
Please help. Thanks
Since the application uses log4j, turn the 'org.apache.cxf' Logger level to ERROR. Add this line to log4j.properties:
log4j.logger.org.apache.cxf=ERROR

Namespace prefixes in SOAP envelope cause parsing error: "Server was unable to read request"

I have a client who is attempting to use our .Net WebService with their Java environment. They're using 'javax.xml.soap.*' which requires a namespace prefix. These same namespace prefixes cause parsing exceptions on our end.
SoapServerMessage.Exception : "Server was unable to read request."
We are using 'System.Web.Services.WebService'
Here is a request they are trying to pass through:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Header>
<ct:CredentialsSoapHeader xmlns:ct="http://ourwebsite.com/webservices/"
xsi:type="WebServiceKeyCredentials">
<Key>demoKey</Key>
<Password>demoPassword</Password>
</ct:CredentialsSoapHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ct1:GetUserID xmlns:ct1="http://ourwebsite.com/webservices/">
<EmailAddress>example#somewebsite.com</EmailAddress>
</ct1:GetUserID>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The generated response:
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: text/xml; charset=utf-8
ETag: ""
Server: Microsoft-IIS/7.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 17 Jan 2012 19:28:20 GMT
Content-Length: 0
As soon as I strip away the namespace prefix, the request works fine. I'm not very familiar with this system but I will try to provide any information as needed.
Thank you in advance for any help that can be provided!

Categories