I saw this post on how to use org.awaitility.await()
I have this code:
public void bar() {
await().forever().pollInterval(5, SECONDS).until(foo());
}
private Callable<Boolean> foo() {
String a= "1";
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return true;
}
};
}
but when I debug it, i stop with breakpoint on
await().forever().pollInterval(5, SECONDS).until(foo());
but my breakpint on String a= "1"; and return true; never stops.
Am i missing something?
I have also tried this, with no print to the screen:
public ConfigActivityLog pollForVersionAwaitingJenkins() {
ConfigActivityLog[] dbConfigChangeWrapper = new ConfigActivityLog[1];
await().atLeast(1, MINUTES).pollInterval(5, SECONDS).until(foo());
return dbConfigChangeWrapper[0];
}
private Callable<Boolean> foo() {
System.out.println("in foo1");
return new Callable<Boolean>() {
public Boolean call() throws Exception {
System.out.println("in foo2");
return true;
}
};
}
Related
The use case is there is a set of methods which need to be executed based on whether the previous one has returned true or not.
For example:
class Test {
boolean method1() {...}
boolean method2() {...}
boolean method3() {...}
...
void callAll() {
if(method1()) {
if(method2() {
if(method3() {
...
}
}
} else {
error();
}
}
}
There has to be an else for all the ifs.
Is there a better way of handling this scenario?
I would just do it like this:
void callAll(){
if(method1() && method2() && method3()){
// all passed
} else {
error();
}
}
Java short-circuits the && logical operation so failure in a previous method here will prevent running the next one.
If in error() you need to know which of the methods failed, you could declare an error message field for storing the information within the class and set its value corresponding the failure:
private String errorMessage;
//...
boolean method2() {
// something went wrong
errorMessage = "Failed to do method2 stuff";
}
Are more elegant way to achieve the same would be to use the Chain of responsibility design pattern and encapsulate the boolean methods in their own handler objects. Doing this would however require more refactoring to the code you currently have and more information about your specific use case.
It's easy enough to write your own varargs method to do this:
public static void run(Supplier<Boolean>... methods) {
for (Supplier<Boolean> method : methods) {
if (!method.get()) return;
}
}
Sample usage:
run(this::method1, this::method2, this::method3);
You can use some form of Observable pattern for these kind of thins too. In most normal cases it seems a bit silly to implement it but otherwise a great way to decouple code from control structures if you have a lot of these. Note that ObservableBoolean is an Android class, but just showing the logic here:
ObservableBoolean a = new ObservableBoolean();
ObservableBoolean b = new ObservableBoolean();
public void call() {
a.addOnPropertyChangedCallback(new OnPropertyChangedCallback() {
#Override
public void onPropertyChanged(android.databinding.Observable sender, int propertyId) {
method2();
}
});
b.addOnPropertyChangedCallback(new OnPropertyChangedCallback() {
#Override
public void onPropertyChanged(android.databinding.Observable sender, int propertyId) {
//..you end the "chain" here
}
});
method1();
}
void method1() {
if(true) {
a.set(true);
}
else {
b.set(false);
}
}
void method2() {
if(true) {
b.set(true);
}
else {
b.set(false);
}
}
I use this technique - although some would find it odd.
boolean method1() {
System.out.println("method1");
return true;
}
boolean method2() {
System.out.println("method2");
return false;
}
boolean method3() {
System.out.println("method3");
return true;
}
void callAll() {
boolean success = method1();
success = success ? method2() : success;
success = success ? method3() : success;
if (success) {
System.out.println("Success");
} else {
System.out.println("Failed");
}
}
I could suggest you to use RX approach, with rxjava it should look like
public boolean test1() {
Log.d("TESTIT", "test1 called");
return true;
}
public boolean test2() {
Log.d("TESTIT", "test2 called");
return true;
}
public boolean test3() {
Log.d("TESTIT", "test3 called");
return false;
}
public boolean test4() {
Log.d("TESTIT", "test4 called");
return true;
}
public boolean elseMethod(boolean result) {
if (result) return true;
else {
Log.d("TESTIT", "ELSE");
}
return false;
}
public void chainedCallback() {
Observable.just(test1())
.filter(this::elseMethod)
.flatMap(aBoolean -> Observable.just(test2()))
.filter(this::elseMethod)
.flatMap(aBoolean -> Observable.just(test3()))
.filter(this::elseMethod)
.flatMap(aBoolean -> Observable.just(test4()))
.filter(this::elseMethod)
.subscribe();
}
call for chainedCallback() will print
test1 called
test2 called
test3 called
ELSE
You define a class that holds an action (calling one of the methods) and with a corresponding failure handler (the else block of an if call)
public static class ActionWithFailureHandler {
private Supplier<Boolean> action;
private Runnable failureHandler;
public ActionWithFailureHandler(Supplier<Boolean> action, Runnable failureHandler) {
this.action = action;
this.failureHandler = failureHandler;
}
//Getters for the instance variables
}
You make a list of the above and call each of the actions till one of the following happens
One of the actions fails (i.,e one of the method returns false). In that case, you need to execute the failureHandler corresponding to that action.
All actions pass. In this case, execute the successHandler (the logic that you execute when all methods return true).
private static void callAll(List<ActionWithFailureHandler> actionWithFailureHandlers, Runnable successHandler) {
actionWithFailureHandlers.stream()
.filter(actionWithFailureHandler -> !actionWithFailureHandler.getAction().get())
.findFirst() //Find first failing action
.map(ActionWithFailureHandler::getFailureHandler)
.orElse(successHandler)
.run(); //You might be running either the successHandler or the failureHandler for the first failed action
}
Driver code:
public static void main(String[] args) {
Test test = new Test();
List<ActionWithFailureHandler> actionWithFailureHandlers = com.google.common.collect.ImmutableList.of(
new ActionWithFailureHandler(test::method1, () -> System.out.println("Method 1 returned false")),
new ActionWithFailureHandler(test::method2, () -> System.out.println("Method 2 returned false")),
new ActionWithFailureHandler(test::method3, () -> System.out.println("Method 3 returned false"))
);
callAll(actionWithFailureHandlers, () -> System.out.println("All returned true"));
}
Exception firstly comes to my mind, but see the link below to learn more about its performance hit.
Original answer. I would do..
public class MyException extends Exception
{
}
public void doAll()
{
try
{
method1();
method2();
method3();
}catch (MyException e)
{
error();
}
}
And let's assume that method1, method2, and method3 throws MyException when it fails.
Though it does not fit your question, it is a good pattern to use Exceptions.
public class Helper
{
public Helper(Method m)
{
this.method=m;
}
public void Do() throws MyException
{
if(method.invoke()==false)
throw new MyException ();
}
}
Using this class,
public void doAll()
{
Helper [] helpers={new Helper(this::method1), new Helper(this::method2), new Helper (this::method3)};
try
{
for(Helper helper:helpers)
{
helper.Do();
}
}catch (MyException e)
{
error();
}
}
But
according to the comment of #dilix and the link, it can be a performance-expensive strategy.
So let's use them only for their purpose.
The code gives a boolean error when I try to run it. It says boolean can not be adressed with static. What could be the answer.?
package csd;
class Uti {
public static void main(String[] args) {
boolean result;
result = Sample.foo() && Sample.bar();
System.out.printf("result%b%n",result);
}
class Sample {
public static boolean foo() {
System.out.println("foo");
return true;
}
public static boolean bar() {
System.out.println("bar");
return false;
}
}
}
Error message:
Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method foo cannot be declared static; static methods can only be declared in a static or top level type
Making your Sample class static will resolve your error:
class Uti {
public static void main(String[] args)
{
boolean result;
result = Sample.foo() && Sample.bar();
System.out.printf("result%b%n",result);
}
static class Sample {
public static boolean foo() {
System.out.println("foo");
return true;
}
public static boolean bar()
{
System.out.println("bar");
return false;
}
}
}
Making it a top level class will also work:
class Sample {
public static boolean foo() {
System.out.println("foo");
return true;
}
public static boolean bar()
{
System.out.println("bar");
return false;
}
}
class Uti {
public static void main(String[] args)
{
boolean result;
result = Sample.foo() && Sample.bar();
System.out.printf("result%b%n",result);
}
}
Well there is a compilation error in your code, you can fix your problem by adding a static modifier to parent type like this in your code:
public static void main(String[] args)
{
boolean result;
result = Sample.foo() && Sample.bar();
System.out.printf("result%b%n",result);
}
static class Sample {
public static boolean foo() {
System.out.println("foo");
return true;
}
public static boolean bar()
{
System.out.println("bar");
return false;
}
}
I am new to Vertx.
I am playing with the API and I am trying to write a FileSizeHandler. I don't know if it is the correct way to do it but I would like to have your opinions.
In my code I would like to use the handler like this :
public class MyVerticle extends AbstractVerticle {
#Override
public void start() throws Exception {
getFileSize("./my_file.txt", event -> {
if(event.succeeded()){
Long result = event.result();
System.out.println("FileSize is " + result);
} else {
System.out.println(event.cause().getLocalizedMessage());
}
});
}
private void getFileSize(String filepath, Handler<AsyncResult<Long>> resultHandler){
resultHandler.handle(new FileSizeHandler(filepath));
}
}
Here is my FileSizeHandler class :
public class FileSizeHandler implements AsyncResult<Long> {
private boolean isSuccess;
private Throwable cause;
private Long result;
public FileSizeHandler(String filePath){
cause = null;
isSuccess = false;
result = 0L;
try {
result = Files.size(Paths.get(filePath));
isSuccess = !isSuccess;
} catch (IOException e) {
cause = e;
}
}
#Override
public Long result() {
return result;
}
#Override
public Throwable cause() {
return cause;
}
#Override
public boolean succeeded() {
return isSuccess;
}
#Override
public boolean failed() {
return !isSuccess;
}
}
What bothers me in the handler, is that I have to do it in the constructor of the class. Is there a better way to do it?
First of all, you called your class FileHandler, but it's not. It's a result.
You declare handler in Vert.x like that:
public class MyHandler implements Handler<AsyncResult<Long>> {
#Override
public void handle(AsyncResult<Long> event) {
// Do some async code here
}
}
Now, for what you do, there's vertx.fileSystem():
public class MyVerticle extends AbstractVerticle {
#Override
public void start() throws Exception {
vertx.fileSystem().readFile("./my_file.txt", (f) -> {
if (f.succeeded()) {
System.out.println(f.result().length());
}
else {
f.cause().printStackTrace();
}
});
}
}
EDIT:
Edited the question in response to #maress answer below.
I have a web service in java (async enabled), which when called performs a call to another service asynchronously. In my Controller I have this:
private boolean receivedEvent = false;
private final Object SYNC = new Object();
public Callable<String> doStuff()
{
callSomeAsyncFunction();
return new Callable<String> ()
{
#Override
public String call() throws Exception {
synchronized (SYNC)
{
while (receivedEvent == false)
{
SYNC.wait();
}
receivedEvent = false;
System.out.println("RETURN");
return "ok";
}
}
};
}
public void onMyEvent(MyEvent event)
{
synchronized (SYNC)
{
receivedEvent = true;
System.out.println("RECEIVED");
SYNC.notify();
}
}
EDIT: The notification never gets through. System.out.println("RETURN") is never called. The events are being received ('RECEIVED' is shown).
Now all I want to do is wait for the callSomeAsyncFunction() to finish executing. When done, it triggers an event on the handler public void onMyEvent(MyEvent event).
Any suggestions? I am not even sure if my approach makes sense at all.
Synchronize always on a final instance.
private MyEvent myEvent;
private final Object SYNC = new Object();
public Callable<String> doStuff()
{
callSomeAsyncFunction();
return new Callable<String> ()
{
#Override
public String call() throws Exception {
synchronized (SYNC)
{
while (myEvent == null)
{
SYNC.wait();
}
return "ok";
}
}
};
}
public void onMyEvent(MyEvent event)
{
synchronized (SYNC)
{
myEvent = event;
SYNC.notifyAll();
}
}
I have this Exception:
public class ErrorException extends Exception
{
private static final long serialVersionUID = 1L;
private String errorMessage = "";
private int errorCode = 0;
private String errorLevel = "";
private Window errorSource = null;
public String getErrorMessage()
{
return errorMessage;
}
public int getErrorCode()
{
return errorCode;
}
public String getErrorLevel()
{
return errorLevel;
}
public Window getErrorSource()
{
return errorSource;
}
public ErrorException(String message, int code, int level, Window source)
{
super();
errorMessage = message;
errorCode = code;
switch (level)
{
case 0:
{
errorLevel = "benignError";
}
case 1:
{
errorLevel = "criticalError";
}
case 2:
{
errorLevel = "terminalError";
}
}
errorSource = source;
}
}
And I have this method:
public static Element check(final Document document) throws ErrorException
{
try
{
chapter.resetLatch();
final SecondaryLoop loop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
new Thread()
{
#Override
public void run()
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
answer.getPreviousElement().takeFocus();
question.removeAnswer(answer);
question.rewriteLetters();
Utils.update(chapter);
loop.exit();
}
});
}
}.start();
loop.enter();
chapter.getLatch().await();
}
catch (InterruptedException e)
{
throw new ErrorException("blankElementDialogError", 8, 1, Main.getGui().getMasterWindow());
}
return new Element();
}
And I use it in this constructor code:
public ConfirmCloseDialog(final Document document, final int postOperation)
{
final CustomJButton doSave = new CustomJButton(Main.getString("doSave"), false);
doSave.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent arg0)
{
getConfirmCloseDialog().dispose();
new Thread()
{
#Override
public void run()
{
/*this method is the one above -->*/Element problem = BlankElementDialog.check(document);
if (problem == null)
{
new SaveChooser(document, postOperation);
}
else
{
new BlankElementDialog(problem);
}
}
}.start();
}
});
}
The code for the second part is not full, but there are no special constructs in the rest of the code (just some GUi objects being constructed and there is no try catch anywhere in the constructor).
However, Eclipse isn't forcing me to encapsulate the method call into try catch block, despite the fact that the method throws an Exception (ErorrException subclasses Exception).
And I know that Exception is checked exception, so it should force it, right?
Why?
What do I have to do so it would force it?
Even without any details Eclipse should notify, look at this:
Just restart the Eclipse should solve the issue.
public class TestClass {
public static void main(String[] args) {
method(2);//Notification here!
}
static void method(int a) throws myException {
}
}
class myException extends Exception {
}