Even after renderResponse set in the beforePhase of the InvokeApplication PhaseListener - events are still broadcasted in myfaces - jsf-2.2

We are using myfaces on websphere liberty profile server.
We have a phaseListener that is setup against InvokeApplication phase - so when there is a exception in beforePhase, we set the renderResponse on facesContext, thinking that it will skip further processing and will not broadcast the events on InvokeApplication, but it does.
LifecycleImpl.java - line # 191 onwards –
if (shouldRenderResponse(context, currentPhaseId, true))
{
skipFurtherProcessing = true;
}
if (executor.execute(context))
{
return true;
}
Now the above code clearly doesn't skip the executor.execute(context) even when renderResponse was executed.
But Mojarra 2.2.11 - behaves differently - it will skip if renderResponse is called in beforePhase.
com.sun.faces.lifecycle.Phase - line # 99 onwards:
Phase.java
handleBeforePhase(context, listeners, event);
if (!shouldSkip(context)) {
execute(context);
}
"shouldSkip" method impl in Phase.java
private boolean shouldSkip(FacesContext context) {
if (context.getResponseComplete()) {
return (true);
} else if (context.getRenderResponse() &&
!PhaseId.RENDER_RESPONSE.equals(this.getId())) {
return (true);
} else {
return (false);
}
}
Now either Mojarra is wrong or Myfaces implementation is wrong. In our case (ie myfaces implementation), what should be the mechanism to skip the events if render response is set on the before phase in INVOKE APPLICATION .

Related

Writing blocking operations in reactor tests with Spring and State Machine

I'm completely new to reactor programming and I'm really struggling with migrating old integration tests since upgrading to the latest Spring Boot / State Machine.
Most Integration tests have the same basic steps :
Call a method that returns a Mono and starts a state Machine and returns an object containing a generated unique id as well as some other infos related to the initial request.
With the returned object call a method that verifies if a value has been updated in the database (using the information of the object retried in step 1)
Poll at a fixed interval the method that checks in the database if value has changed until either the value has changed or a predefined timeout occurs.
Check another table in the database if another object has been updated
Below an example:
#Test
void testEndToEnd() {
var instance = ServiceInstance.buildDefault();
var updateRequest = UpdateRequest.build(instance);
// retrieve an update Response related to the request
// since a unique id is generated when triggering the update request
// before starting a stateMachine that goes through different steps
var updateResponse = service.updateInstance(updateRequest).block();
await().alias("Check if operation was successful")
.atMost(Duration.ofSeconds(120))
.pollInterval(Duration.ofSeconds(2))
.until(() -> expectOperationState(updateResponse, OperationState.SUCCESS))
// check if values are updated in secondary table
assertValuesInTransaction(updateResponse);
}
This was working fine before but ever since the latest update where it fails with the exception :
java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread parallel-6
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:83)
at reactor.core.publisher.Mono.block(Mono.java:1710)
I saw that a good practice to test reactor methods using StepVerifier but I do not see how I can reproduce the part done with Awaitability to poll to see if the value has changed in the DB since the method that checks in the DB returns a Mono and not a flux that keeps sending values.
Any idea on how to accomplish this or to make the spring stack accept blocking operations?
Thanks
My current stack :
Spring Boot 3.0.1
Spring State Machine 3.0.1
Spring 6
Junit 5.9.2
So as discussed in comments here is an example with comments. I used flatMap to subscribe to what expectOperationState returns. Also there is Mono.fromCallable used which check the value from some method and if it fails to emit anything in 3 seconds - the timeout exception is thrown. Also we could try to get rid of this boolean value from expectOperationState and refactor the code to just return Mono<Void> with completed signal but this basically shows how you can achieve what you want.
class TestStateMachine {
#Test
void testUntilSomeOperationCompletes() {
final Service service = new Service();
final UpdateRequest updateRequest = new UpdateRequest();
StepVerifier.create(service.updateInstance(updateRequest)
.flatMap(updateResponse -> expectOperationState(updateResponse, OperationState.SUCCESS))
)
.consumeNextWith(Assertions::assertTrue)
.verifyComplete();
}
private Mono<Boolean> expectOperationState(final UpdateResponse updateResponse, final OperationState success) {
return Mono.fromCallable(() -> {
while (true) {
boolean isInDb = checkValueFromDb(updateResponse);
if (isInDb) {
return true;
}
}
})
.publishOn(Schedulers.single())
//timeout if we not receive any value from callable within 3 seconds so that we do not check forever
.timeout(Duration.ofSeconds(3));
}
private boolean checkValueFromDb(final UpdateResponse updateResponse) {
return true;
}
}
class Service {
Mono<UpdateResponse> updateInstance(final UpdateRequest updateRequest) {
return Mono.just(new UpdateResponse());
}
}
Here is an example without using Mono<Boolean> :
class TestStateMachine {
#Test
void test() {
final Service service = new Service();
final UpdateRequest updateRequest = new UpdateRequest();
StepVerifier.create(service.updateInstance(updateRequest)
.flatMap(updateResponse -> expectOperationState(updateResponse, OperationState.SUCCESS).timeout(Duration.ofSeconds(3)))
)
.verifyComplete();
}
private Mono<Void> expectOperationState(final UpdateResponse updateResponse, final OperationState success) {
return Mono.fromCallable(() -> {
while (true) {
boolean isInDb = checkValueFromDb(updateResponse);
if (isInDb) {
//return completed Mono
return Mono.<Void>empty();
}
}
})
.publishOn(Schedulers.single())
//timeout if we not receive any value from callable within 3 seconds so that we do not check forever
.timeout(Duration.ofSeconds(3))
.flatMap(objectMono -> objectMono);
}
private boolean checkValueFromDb(final UpdateResponse updateResponse) {
return true;
}
}

Performing Asynchronous operations on Vaadin UI

I have a Spring Boot project with Vaadin integration (v14). I want my application to do some background operation and represent the results on the Vaadin-based frontend. For this I have a view which is a Polymer template generated with Vaadin Designer (.js) and connected to a Java companion class. To this view I've just simply added a button initialized with the following listener:
_btnMyTriggerButton.addClickListener(event -> {
CompletableFuture<Void> c = CompletableFuture.supplyAsync(() -> {
for (int i = 0; i < 5; i++)
{
try
{
System.out.println("Waiting");
Thread.sleep(1000);
UI.getCurrent().access(() -> {
Notification.show("Waiting");
});
}
catch (InterruptedException e)
{
}
}
return "Waiting over. Greet!";
}).thenAccept(s -> {
System.out.println(s);
UI.getCurrent().access(() -> {
Notification.show(s);
});
});
I'm trying to access the UI as the documentation says. However when this is being executed it only reaches the first "Waiting", then stops. If I remove the UI interaction (Notification.show()) the output is printed to the backend as desired, but not when attempting do any interaction on the UI..
The structure of my java companion class is the following:
#Tag("my-view")
#JsModule("./my-view.js")
#Route("")
#Push(PushMode.AUTOMATIC)
public class MyView extends PolymerTemplate<MyView.MyModel>
{
#Id("trigger-button")
private Button _btnMyTriggerButton;
MyView() {
// listener initialization code described above
}
public interface MyModel extends TemplateModel
{
}
}
Do I miss something to achieve asynchronous behavior on this webpage?
Any help is appreciated.
The problem in this case is that the first callback terminates with a NullPointerException because UI.getCurrent() returns null when it's run from a background thread. CompletableFuture will just ignore the exception unless you explicitly handle it (e.g. using handle instead of thenAccept) or block on the result.
You can fix this by adding UI ui = UI.getCurrent(); in the beginning of the click listener and then referencing ui in both the supplyAsync and thenAccept callbacks instead of using UI.getCurrent() there.

Kotlin Coroutines remove exception handler from scope

In code below I am fetching some data. If error/exception was thrown I want the exception handler to catch it. Once done with fetching, I am posting the result using LiveData to whoever is observing.
What I am trying to achieve is that the exception handler to finish its job once I post the result. Which means, if the observer handling the result also throws an exception, I don't want the coroutine exception handler to catch it (Which is the case in code below).
fun loadPrerequisites(resultObserver: MutableLiveData<PrerequisiteDataHolder?>) {
val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
resultObserver.postValue(null)
}
scope.launch(Dispatchers.IO + exceptionHandler) {
val deferredCreationScheme = async {
fetchCreationScheme()
}
val creationScheme = deferredCreationScheme.await()
//TODO remove exception handler at this stage?
resultObserver.postValue(PrerequisiteDataHolder(creationScheme))
}
}
Is there a way to remove the exception handler before posting the result to the LiveData? Or must I introduce a new scope?
You seem to have misunderstood the purpose of the coroutine exception handler. It is the coroutine equivalent of uncaughtExceptionExceptionHandler in Java and its purpose is to inform you of an exception that has already broken its coroutine. You seem to want to use it to implement business logic-level exception handling.
The coroutine exception handler is not a replacement for the try-catch block, and the latter is what you should use in your case.
I think you don't need async in your code in the first place, I believe this is all you really need:
scope.launch(Dispatchers.IO) {
resultObserver.postValue(
try {
PrerequisiteDataHolder(fetchCreationScheme())
} catch (e: Exception) {
null
}
)
}
I typically use a helper function for code like this:
inline fun <T> tryOrNull(block: () -> T) = try {
block()
} catch (t: Throwable) {
null
}
Then your code becomes
scope.launch(Dispatchers.IO) {
tryOrNull { PrerequisiteDataHolder(fetchCreationScheme()) }
.also { resultObserver.postValue(it) }
}

Troubles registering custom metrics to Micrometer & Spring Boot 2

I'm having issues registering custom metrics to MeterRegistery.
What it looks like is that Spring manages register all its metrics (70 something) and then when the control comes back to me, I'm trying to register my own too:
public MetricsAwareActiveTasksRepository(ActiveTasksRepository activeTasksRepository, MeterRegistry meterRegistry) {
this.activeTasksRepository = activeTasksRepository;
this.createdTaskIdsCounter = meterRegistry.counter(CustomBusinessMetrics.CREATED_TASK_IDS_COUNTER);
this.autoStoppedTasksCounter = meterRegistry.counter(CustomBusinessMetrics.AUTO_STOPPED_TASKS_COUNTER);
}
Unfortunately at the point where my first metric is being registered, process hangs here in micrometer:
private Meter getOrCreateMeter(#Nullable DistributionStatisticConfig config,
BiFunction<Id, /*Nullable Generic*/ DistributionStatisticConfig, Meter> builder,
Id originalId, Id mappedId, Function<Meter.Id, ? extends Meter> noopBuilder) {
Meter m = meterMap.get(mappedId);
if (m == null) {
if (isClosed()) {
return noopBuilder.apply(mappedId);
}
synchronized (meterMapLock) {
m = meterMap.get(mappedId);
if (m == null) {
if (!accept(originalId)) {
//noinspection unchecked
return noopBuilder.apply(mappedId);
}
if (config != null) {
for (MeterFilter filter : filters) {
DistributionStatisticConfig filteredConfig = filter.configure(mappedId, config);
if (filteredConfig != null) {
config = filteredConfig;
}
}
}
m = builder.apply(mappedId, config);
meterMap = meterMap.plus(mappedId, m);
for (Consumer<Meter> onAdd : meterAddedListeners) {
onAdd.accept(m);
}
}
}
}
return m;
}
The last line that can be tracked from debugger is where synchronized block starts. From debugger I see that the main thread becomes ZOMBIE, and nothing more happens. Lock is not being released.
Did anyone have this kind of problems? Am I doing something wrong here?
BTW Here's config also:
#Bean
CloudWatchMeterRegistry cloudWatchMeterRegistry(CloudWatchConfigProperties config, AmazonCloudWatchAsync amazonCloudWatch) {
CloudWatchMeterRegistry meterRegistry = new CloudWatchMeterRegistry(config, Clock.SYSTEM, amazonCloudWatch);
meterRegistry.config().commonTags(commonTags());
return meterRegistry;
}
As you can see I also tried to register some "custom" metrics before Spring does and it succeeds, however it does not change the situation that later this is not possible.
Also after enabling DEBUG logger, the micrometer library says nothing, the last logs before actually hanging forever are the logs from spring bean lifecycle methods, like autowiring this particular constructor that registers new metrics.
Versions are: spring-boot: 2.0.2, micrometer 1.0.4
Thanks in advance for any ideas.

How to handle ViewExpiredException by showing JavaScript alert?

I've read the question Handle ViewExireException/ajax and display a Primefaces dialog and the answer from BalusC. I'd want to handle the ViewExpiredException by showing the alert with information to refresh the page. I've taken the suggestion from BalusC to user RequestContextto put JavaScript to execute, and I've removed the JSF redirection because I'm not using it:
#Override
public void handle() throws FacesException {
for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
Throwable t = context.getException();
if (t instanceof ViewExpiredException) {
ViewExpiredException vee = (ViewExpiredException) t;
try {
log.info("Catched ViewExpiredException for view {}", vee.getViewId());
RequestContext.getCurrentInstance().execute("handleViewExpired("+vee.getViewId()+")");
return;
} finally {
i.remove();
}
}
}
// At this point, the queue will not contain any ViewExpiredEvents.
// Therefore, let the parent handle them.
getWrapped().handle();
}
The problem is, I got NullPointerException when executing the handle method from wrapped handler. I've added the return clause, and after adding it, the effect was the same:
[30.01.13 15:45:59:140 CET] 0000002e ErrorPageWrit E An exception
occurred
javax.faces.FacesException: java.lang.NullPointerException at
org.apache.myfaces.shared_impl.context.ExceptionHandlerImpl.wrap(ExceptionHandlerImpl.java:241) at
org.apache.myfaces.shared_impl.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:156)
at
my.project.web.handler.ViewExpiredExceptionExceptionHandler.handle(ViewExpiredExceptionExceptionHandler.java:59)
at
org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:191)
at
org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
So, the parent handle method is executed, thought there should be the return from method (The info string is logged).
I'm using PrimeFaces 3.4 and MyFaces 2.0.7, everything on WebSphere 7.
I don't understand what is happening here. Is it possible to achieve what I want, and if so, what I'm doing wrong?
The best way was to handle that exception on client side. It's very simple few-liner and it's completly transparent:
var originalPrimeFacesAjaxResponseFunction = PrimeFaces.ajax.AjaxResponse;
PrimeFaces.ajax.AjaxResponse = function(data, status, xhr) {
var errorName = $(data.documentElement).find("error-name").text();
if (errorName == 'javax.faces.application.ViewExpiredException') {
alert('View has expired, redirection will follow');
window.location.reload();
} else {
originalPrimeFacesAjaxResponseFunction.apply(this, arguments);
}
};
No 2 new classes on server, no faces-config.xml changes, this is what I love in programming.

Resources