Java - Access to a local variable from anonymous class - java

The problem in found = true; line
public boolean containsBlock(String nodeName, ASTNode node)
{
boolean found = false;
if(nodeName.equals("if"))
{
node.accept(new ASTVisitor()
{
public boolean visit(IfStatement s)
{
found = true;
return false;
}
});
}
return found;
}
I know that I will be able to access this if I make found a class global variable, but I don't want to do this. Maybe there is another way? I just need to let the other code know that something was found
UPD:
Is that code better and will return the right
public boolean containsBlock(Text nodeName, ASTNode node)
{
final AtomicBoolean flag = new AtomicBoolean(false);
Thread thread = new Thread(new Runnable()
{
#Override
public void run()
{
if(nodeName.matches("if"))
{
node.accept(new ASTVisitor()
{
public boolean visit(IfStatement s)
{
flag.set(true);
return false;
}
});
}
else
throw new RuntimeException("Unknown NodeName: " + nodeName);
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return flag.get();
}

When you pass a ASTVisitor instance to the ASTNode instance (using the accept method), it doesn't execute your visit method immediately. Therefore, there's no point to attempt to change a local variable of your containsBlock method from within the visit method.
visit will most likely be executed after your containsBlock method has returned, at which point your local found variable will no longer be in the call stack.

Related

One method to capture most of the try catch statements

In my UI java test framework I have lots of methods that are doing try catch around element actions like click, send keys etc and return true when action is successful and false when any exception occurs. I was wondering is there any smarter way to pass the method as parameter and in that one method surround that code with try catch statement. So that code could be simpler and cleaner to read (may be Java 8 functional interfaces).
public boolean expandPanel(String panelHeading) {
boolean panelFound = false;
try {
getElement(PanelHeadings.fromString(panelHeading)).click();
panelFound = true;
} catch (Exception e) {
panelFound = false;
}
return panelFound;
}
I did try creating an actions class and defining different methods for click, sendKeys etc. But is there a way if i can just have one try catch method and pass code or behaviour to that method.
public boolean expandPanel(String panelHeading) {
return actions.click(getElement(PanelHeadings.fromString(panelHeading)));
}
public class WebElementActions {
public Boolean click(WebElement element) {
try {
element.click();
return true;
} catch (Exception e) {
log.error(e.getMessage());
return false;
}
}
}
You could do something like
public boolean executeSafely(Runnable action) {
try {
action.run();
return true;
} catch (Exception x) {
return false;
}
}
And then call it with return executeSafely(element::click).

Context Sensitive help for AbstractGraphicalEditPart(GMF)

the problem is simple: To add Context Sensitive Help i followed the standard steps, but once i try to link the BLOCKS to the CONTEXT IDs with SetHelp() from IWorkbenchHelpSystem. The frist argument should be either a Control(swt) or IAction.
void setHelp(Control control, String helpContextId);. How can i refer to Control from a damos.dml.Block object type ?
org.eclipselabs.damos.dml.blockTypes
FYI
I've tried and visited all the content of these sites
http://rajakannappan.blogspot.com/2009/05/context-sensitive-help-in-eclipse.html
https://help.eclipse.org/2019-03/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fua_help_context.htm&cp=2_0_19_1_2
https://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fextension-points%2Forg_eclipse_ui_commands.html
The display and search methods are working correctly but I just need to set the help and not display it so that only upon calling Help (F1 or ctrl+F1) the context help is shown.
Thanks.
After trying I thought maybe this workaround would get me the same result but NADA.
private Block getBlock() {
EObject semanticElement = resolveSemanticElement();
if (semanticElement instanceof Block) {
Block block = (Block) semanticElement;
PlatformUI.getWorkbench().getHelpSystem().search(block.getType().getName());
//PlatformUI.getWorkbench().getHelpSystem().setHelp(?, Activator.HELP_VIEW); Cannot cast block directly to Control
PlatformUI.getWorkbench().getHelpSystem().displayHelp(Activator.HELP_VIEW);
return block;
} else {
return null;
}
}
#Override
protected NodeFigure createMainFigure() {
blockFigure = new BlockFigure();
// OB: java.awt.event.KeyEvent.VK_F1 is wrong, use SWT.F1
blockFigure.setFocusTraversable(true);
blockFigure.setRequestFocusEnabled(true);
blockFigure.addMouseListener(new MouseListener.Stub() {
#Override
public void mousePressed(final MouseEvent me) {
blockFigure.requestFocus();
}
});
blockFigure.addKeyListener(new KeyListener.Stub() {
#Override
public void keyReleased(KeyEvent ke) {
}
#Override
public void keyPressed(KeyEvent ke) {
if (ke.keycode == SWT.F1) {
PlatformUI.getWorkbench().getHelpSystem().search(getBlock().getType().getName());
PlatformUI.getWorkbench().getHelpSystem().displayHelp(Activator.HELP_VIEW);
}
}
});
return blockFigure;
}
Any help is appreciated!
public String getSelection() {
String blockName = "SelectBlock";
EObject element = null;
EditPart part = getDiagramEditPart();
EditPartViewer viewer = part.getViewer();
List selectedList = viewer.getSelectedEditParts();
try {
GraphicalEditPart editPart = (GraphicalEditPart) selectedList.get(0);
BlockEditPart blockPart = (BlockEditPart) editPart;
viewer.getProperty("BlockFigure");
NodeImpl node = (NodeImpl) blockPart.getModel();
element = node.getElement();
} catch (IndexOutOfBoundsException e) {
// TODO: handle exception
e.printStackTrace();
}
ISelection selection1 = viewer.getSelection();// EURêKA
if (element instanceof Block) {
Control control2 = getGraphicalViewer().getControl();
blockName = ((Block) element).getType().getName();
return blockName;
// return part.getParent().getSelected();
}
return "SelectBlock";
}
i have the possiblity to select a block type CTRL+F1 and voila the Help Definition of said Block is shown.

Unexpected Behaviour with CompletableFuture

I am trying to create a simple example with async CompletableFuture's but I'm seeing some weird behaviour. The idea is that I kick off 2 async futures, one activates a boolean flag after a set time and the other polls that flag to release the value once thread 1 has changed that flag. Here's my code:
package completablefutures;
import java.util.concurrent.CompletableFuture;
public class CFMain throws InterruptedException {
public static void main(String... args) {
CF cf = new CF();
CompletableFuture.supplyAsync(cf::getCompletable).thenRun(() -> System.out.println("Post-future action"));
CompletableFuture.supplyAsync(cf::doSleep);
Thread.sleep(10000);
}
}
And the CF class:
package completablefutures;
public class CF {
private boolean valueIsSafe = false;
public boolean getCompletable() {
System.out.println("Fetching completable");
while(true) {
if(this.valueIsSafe) {
System.out.println("Completable fetched");
return true;
}
}
}
public boolean doSleep() {
System.out.println("Started sleeping");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.valueIsSafe = true;
System.out.println("Finished sleeping");
return true;
}
}
When I let the program run it's course, it prints this:
Fetching completable
Started sleeping
Finished sleeping
Process finished with exit code 0
i.e. the future never completes in the 10s allocated. So what's going on here?
You are accessing the valueIsSafe from multiple threads, you must define this variable as volatile.
private volatile boolean valueIsSafe = false;
Using the volatile keyword will prevent threads from caching this value and force them to read the raw memory on every access.
This is because you are not using a thread safe data type, you can change your code to use AtomicBoolean here is an example of your code using AtomicBoolean:
public class CF {
private AtomicBoolean valueIsSafe = new AtomicBoolean (false);
public boolean getCompletable() {
System.out.println("Fetching completable");
while(true) {
if(this.valueIsSafe.get()) {
System.out.println("Completable fetched");
return true;
}
//System.out.println("doing something");
}
}
public boolean doSleep() {
System.out.println("Started sleeping");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.valueIsSafe.set(true);
System.out.println("Finished sleeping");
return true;
}
}

Terminating thread from inside it's run method in Eclipse-RCP

I have done something like this in my code
public void doWork()
{
Job job = new Job("Job")
{
#Override
protected IStatus run(IProgressMonitor monitor) {
while (rsMemName.next()) {
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
try {
String memId = rsMemName.getString("id");
if (doMemberTasks(memId)==false)
{
cnn.rollback();
return;
}
} catch (Exception ex) {
ex.printStackTrace();
try {
cnn.rollback();
return;
} catch (SQLException e) {
e.printStackTrace();
}
}
});
}
}
}
job.schedule();
}
What i want to do is exit from the whole method if doMemberTasks(memId) returns false.
But it doesn't return from the method and keep looping on ResultSet. how can i terminate the thread from the run method?
Please give any suggestions how could i achieve that.....
Thanks in advance....
This is because return will return only from the thread run method. What you can do is set a variable(flag) probably static, and check its value after the run code to put another return statement.
Yeah your best bet would be to have a flag,
boolean doWork = true;
...
while( doWork && rsMemName.next(){
...
if (doMemberTasks(memId)==false)
{
cnn.rollback();
doWork = false;
return;
}

Thread not continue running

I have a following code as below:
new Thread(new Test1Runnable()).start(); // Line (a)
public class Test1Runnable implements Runnable {
public void run() {
Test2Runnable task1 = new Test2Runnable();
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
executor.submit(task1);
while(true) {
if(task1.isDone()) {
break;
}
// Thread.sleep(2000); // Line (b)
}
if(!task1.hasError()) { // Line (c)
executor.submit(new Test3Runnable());
}
} catch(Exception ex) {
if(executor != null) {
executor.shutdown();
}
}
}
}
public class Test2Runnable implements Runnable {
private Exception error;
private boolean done;
public void run() {
reset();
doRun();
done = true;
}
protected void doRun() {
try{
// ...
// ....
} catch(Exception ex) {
}
}
private void reset() {
error = null;
done = false;
}
public boolean isDone() {
return done;
}
public boolean hasError() {
return getError() != null || getNonSuccess() > 0;
}
public Exception getError() {
return error;
}
}
I have an issue when I run Test1Runnable at line (a) and comment Line (b) then the thread hang and not run to Line (c). If I uncomment line (b) or I add breakpoint at line (c) and activate remote debug the thread continue to run to the end as normal. Could anyone can give me some advice about this? Why the Thread not continue running? All threads run without any exception.
Looks like you have a race conditioin here, so result of the execution depends on timings, debug enabled, etc. The code posted is more or less fine, the error is likely to be in Test2Runnable class. I suppose there are some flags (isDone, hasError) that have visibility issues. Try to declare them volatile.
Please add Test2Runnable code here and I'll be able to give more precise answer.

Categories

Resources