Redirecting in #PostConstruct method resulted in IllegalStateException - redirect

According to the answer of BalusC, I used
FacesContext.getCurrentInstance().getExternalContext().redirect(url);
in my #PostConstruct method to stop JSF from rendering the view and redirect users. However, when I try to run the code, I still ran into the java.lang.IllegalStateException exception at the above line.
WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:524)
at StudentManagedBean.CourseSummary.init(CourseSummary.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
UPDATE: I added the following line in my #PostConstruct method:
System.out.println("INIT " + FacesContext.getCurrentInstance().getExternalContext().isResponseCommitted());
and what I saw was INIT true. I wonder if the response is supposed to be committed BEFORE the #PostConstruct method is called?
I'd be very grateful if you could give me an advice.

As mentioned in my update, the following line printed INIT true:
System.out.println("INIT " + FacesContext.getCurrentInstance().getExternalContext().isResponseCommitted());
I finally found why the above situation occurred. On my page, before the ManagedBean X, which contains the redirect function, was referenced by UIComponent A, another ManagedBean Y was referenced beforehand by UIComponent B that is placed above UIComponent A in the page structure. As a consequence, the response was partially committed by ManagedBean Y, which makes it impossible for ManagedBean X to send a redirect request.

A redirect will not work here, because even though the response has been completed and finalized, JSF is not smart enough to avoid its typical routine of running through the lifecycle events anyway.
Instead you can try doing a Forward from a RequestDispatcher. A Forward is different from a redirect in the following ways:
Performed internally by the servlet
Browser is apathetic
original url stays intact
Here is some code that displays how this can be done...
RequestDispatcher dispatcher =
((ServletRequest) context.getExternalContext().getRequest())
.getRequestDispatcher("/j_spring_security_logout");
try {
dispatcher.forward((ServletRequest) context.getExternalContext().getRequest(),
(ServletResponse) context.getExternalContext().getResponse());
} catch (ServletException e) {
log.error("ServletException", e);
} catch (IOException e) {
log.error("IOException", e);
}
By doing this you are ending the execution of the FacesServlet prematurely and forwarding it onto a different servlet altogether. I imagine that from this other servlet it might be possible to redirect to the desired location.

Related

Vertx not able to handle internal code error to client automatically

I have a verticle which accepts REST request, get data from other verticle through event bus and respond back to client.
vertx.exceptionHandler(event -> logger.error("Vertx exception ", event));
router.get("/api/v1/:param").handler(this::routerHandler);
public void routerHandler(RoutingContext rc) {
vertx.eventBus().request("data", param,
result -> {
if (result.succeeded()) {
logger.info("Request handled successfully");
// intentionally creating exception body() will return String
JsonObject jsonObject = (JsonObject) result.result().body();
rc.response().end(jsonObject)
}else{
logger.error("Request failed");
}
}
When a exception is raised it is printed in exception handler that I setup in vertx instance but after that the vertx is not reporting back the exception immediately to client instead it waits for timeout(30 secs) to occur.
I tried attaching error handler to router object and failure handler to route object but nothing helps to report the exception immediately to client. I know I can have a try catch and report the error in catch block. But I want know if there is any other way to handle this like Servlet or Spring MVC reports back to client even though the exception is not handled in code.
router.errorHandler(500,routingContext -> {
System.out.println(routingContext.failed());
routingContext.response().end("Exception ");
});
router.route().handler(BodyHandler.create()).failureHandler(routingContext -> {
Uncaught exceptions are reported to the context exceptionHandler. By default it prints the exception to the console.
You can configure it but you will not get a reference to the corresponding HTTP request anyway (the exception may come from different things).
Most problems like this are usually found during unit/integration/acceptance testing.
And for the remainders you could set a timeout handler on your router definition to make sure the request is ended before the default 30 seconds.
If you don't want to miss any uncaught exception, you should switch to the Vert.x Rxified API. When using RxJava, any exception thrown will be reported to the subscriber.

How to configure Citrus LogginReporter to show full stack trace when there is an ActionTimeoutException?

While running test (with Citrus or not) an exception may occurs if the test expects a message on a queue but the message isn't received before the timeout expires.
In this case I'd like know which line throws the Exception.
Unfortunatelly citrus doesn't show this information.
Here's my code :
#Test
#CitrusTest
public void testFail() {
sequential().actions(
mycheckNoError1(),
mycheckNoError2(),
mycheckNoError3(), //this one fails , we want to know it and which line throws the ActionTimeoutException
mycheckNoError4()
);
}
protected AbstractActionContainer mycheckNoError3() {
AbstractActionContainer aCatch = catchException().exception(ActionTimeoutException.class)
.when(receive("for_soap_q")
.timeout(100L)
.validationCallback(validationCallbackFunc()
))
.addTestAction(timeoutException(Thread.currentThread().getStackTrace()));
return aCatch;
}
And here's the stacktrace of citrus, that doesn't show the line that throws the exception:
...
INFO .c.r.LoggingReporter|
ERROR .c.r.LoggingReporter| TEST FAILED MyTest.test <package.test> Nested exception is:
com.consol.citrus.exceptions.ActionTimeoutException: Action timed out while receiving JMS message on 'testQueue'
at com.consol.citrus.jms.endpoint.JmsConsumer.receive(JmsConsumer.java:95) ~[citrus-jms-2.7.5.jar:na]
at com.consol.citrus.jms.endpoint.JmsConsumer.receive(JmsConsumer.java:60) ~[citrus-jms-2.7.5.jar:na]
at com.consol.citrus.jms.endpoint.JmsSyncConsumer.receive(JmsSyncConsumer.java:60) ~[citrus-jms-2.7.5.jar:na]
...
The only way I found was to pass the stacktrace as parameter of a method timeoutException() I wrote:
private TestAction timeoutException(StackTraceElement[] methodName) {
System.out.println("++++++++++ timeout Exception at line " + methodName[1].getLineNumber() + " in method: [" + methodName[1].getMethodName() + "]");
return null;
}
But I guess there is a better way to do this.
Is there a way to configure properly citrus and/or override the LoggingReporter to show the line number that make the exception happen ?
(in this case, this is the line: when(receive("for_soap_q")...)
thanks.
You can overwrite the default Logging reporter by placing a bean named 'loggingReporter' in the Spring application context. In addition to that you can add custom reporters and test listeners when choosing different bean naming. Just add the custom listeners to the Spring application context and they will get test events and throwable errors for reporting.
Also make sure to use the TestRunner fluent API instead of the TestDesigner fluent API. Designer is slightly more straight forward but runner will execute the test actions immediately while building the test case with the fluent API. So you will get more detailed stack traces with correct line numbers and the ability to set breakpoints for better debugging.

Execution stops on Cookies.getCookie() call with no exceptions

I'm trying to read a Cookie value in my server side implementation class. After some debugging my code now looks like this:
logger.info("Initiating login");
String oracleDad;
try {
logger.info("inside try");
oracleDad = Cookies.getCookie("dad");
logger.info("Read dad from cookie: " + oracleDad);
} catch (Exception e) {
logger.error("Failed to read dad from cookie", e);
oracleDad = "gtmd";
}
When I execute this code my onFailure block is fired with a Status code Exception:
com.google.gwt.user.client.rpc.StatusCodeException: 500 The call
failed on the server; see server log for details
My logging output on the server looks like this:
[INFO] c.g.e.server.rpc.MyProjectImpl - Initiating login
[INFO] c.g.e.server.rpc.MyProjectImpl - inside try
How is it possible that neither logger, the INFO or the ERROR, fire after the Cookies.getCookie() call? I'd hoped that by adding the catch(Exception e) I'd get some error message explaining why the code fails. But execution just seems to stop silently.
I'm using com.google.gwt.user.client.Cookies. I thought client code can be run on the server, just not vice versa. Is that correct? Is there something else I'm missing?
I'm using com.google.gwt.user.client.Cookies. I thought client code can be run on the server, just not vice versa. Is that correct? Is there something else I'm missing?
No, that's not correct, yes there is something you are missing: Server code can't run on the client, and client code can't run on the server.
You are not getting an Exception. You are getting an Error or some other Throwable.
Try catching Throwable in your try/catch block, and you'll see that you are getting an error where the server JVM is unable to load the Cookies class, because something is wrong. The JVM thinks that a native library is missing (because it doesn't know what JSNI is or how to run it), so it throws an UnsatisfiedLinkError:
Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native.
In GWT, the Cookies class is meant to interact with the browser itself to see what cookies have been defined on the currently loaded page. To use cookies on a J2EE server, ask the HttpServletRequest object for the cookies it knows about, and their values.

How can I determine why onFailure is triggered in GWT-RPC?

I have a project that does 2 RPC calls and then saves the data that the user provided in tha datastore. The first RPC call works ok, but from the second I always recieve the onFailure() message. How can I determine why the onFailure() is triggered? I tried caught.getCause() but it doesn't return anything.
feedbackService.saveFeedback(email,studentName,usedTemplates,
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
caught.getCause();
Window.alert("Failure!");
}
public void onSuccess(String result) {
Window.alert("Saved!");
}
});
Throwable instance is instance of an Exception. You can check if it is a custom Exception like this:
if (caught instanceOf CustomException){
or if you want to show the message of exception you can use the getMessage():
Window.alert("Failure: " + caught.getMessage());
GWT-rpc is not not easy to ebug if an error occurs.
The easiest part is th check if the Exception is part of StatusCodeException.
A Statuscode of 404 means, you are pointing to a wrong endpoint
0 means, that
The searver is unreachable
You don't have permissions to check, if the server is available (X-domain-request)
You can use the Chrome-Web-Inspector to bedug GWT-RPC
You should be able to see all calls from the browser to you backend.
The most common failures are because of serialization of object. You have to ensure, that all dtransferred object implement java.io.Serializable
Most of the time it will just be a server side exception being raised which fires the onFailure() method.
Try putting breakpoints on your server side. That should help you pinpoint what's going wrong.

RequestFactory service inheritance on the client in GWT 2.4

GWT 2.4 brings service inheritance on the client (issue 6234, issue 6035).
I've been waiting for this future for a long time, as it saves a lot of duplicated code on the client. I've started implementing it, but so for with mixed success.
This is my code:
public interface BaseEntityRequest<T>
{
Request<Void> put(T entity);
Request<List<T>> getAllOrderBy(String propertyName);
Request<List<T>> getRangeAndFilter(int limit,int offset, QueryInfoProxy queryInfo);
}
#Service(value = EgdDao.class, locator = DaoServiceLocator.class)
public interface EgdRequest extends RequestContext, BaseEntityRequest<EgdProxy>
{
Request<Void> exportToExcel(QueryInfoProxy queryInfo, String userName);
}
So far getAllOrderBy and getRangeAndFilter work fine, but put(T entity) does not.
I get the following error in the console:
[ERROR] Unexpected error
java.util.NoSuchElementException
and this gets returned in the receiver onFailure ServerFailure message:
Error 500 INTERNAL_SERVER_ERROR
HTTP ERROR 500
Problem accessing /gwtRequest. Reason:
INTERNAL_SERVER_ERROR
The only cause, that I can see, for the put method not to work, when the others do, is that it uses the generic parameter T. When I move the put method in the EgdRequest interface (using EgdProxy as a parameter instead of T) it starts to work, so I know my server code is fine.
Does anybody have any idea how to implement this correctly?
Thanks!
It's a GWT bug. See http://code.google.com/p/google-web-toolkit/issues/detail?id=6794