ikuraj / alloy4eclipse

Automatically exported from code.google.com/p/alloy4eclipse
0 stars 0 forks source link

Problems with A4's WorkerEngine with A4E installed in eclipse ganymede SR1 #78

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Install eclipse ganymede SR1
2. Install A4E (currently version 0.2.34)
3. Run a simple test, e.g.:

module foo
sig A {}
test1: check { no A }

What is the expected output? What do you see instead?
The progress view shows an A4E job in progress.
The job never finishes but we can manually cancel it.

The method:
fr.univartois.cril.alloyplugin.core.ExecutableCommand.execute(IReporter,
IProgressMonitor) is running in a worker thread and is spinning in the
while loop below:

// lines 153-159
WorkerEngine.run(task, maxHeapSize, maxStackSize,jniPath,
classPath.toString(), cb);
            // WorkerEngine.runLocally(task,cb);
            while (WorkerEngine.isBusy()) {
                if (monitor.isCanceled()) {
                    WorkerEngine.stop();
                }
            }

Original issue reported on code.google.com by nicolas....@gmail.com on 24 Dec 2008 at 5:43

GoogleCodeExporter commented 8 years ago
The problem seems to be about A4's WorkerEngine.

I can launch A4 from the fr.univartois.cril.alloyplugin.launch/alloy4.jar 
bundle.

java -jar alloy4.jar => this doesn't work.
Failed to load Main-Class manifest attribute from
alloy4.jar

But this works, kind of...
java -cp alloy4.jar edu.mit.csail.sdg.alloy4whole.SimpleGUI
alloy4.jar
Creating stream
Writing task
Writed task
Reading result

The GUI comes up with the title banner:

Alloy Analyzer 4.1.9 loading... please wait...

...and it never finishes.

If I replace the fr.univartois.cril.alloyplugin.launch/alloy4.jar file with 
this:
http://alloy.mit.edu/alloy4/alloy4.jar

then I have to make some fixes to make it run in A4E:

fr.univartois.cril.alloyplugin.core.ExecutableCommand.execute(IReporter,
IProgressMonitor)

// lines 153-159:
            WorkerEngine.run(task, maxHeapSize, maxStackSize,jniPath /* classPath.toString()
*/, cb);
            // WorkerEngine.runLocally(task,cb);
            while (WorkerEngine.isBusy()) {
                if (monitor.isCanceled()) {
                    WorkerEngine.stop();
                }
            }

With this, I can run A4 from Eclipse using a debug launch configuration.
I can launch a runtime eclipse with A4E but when I launch an A4 command,
the worker thread running the above loop will spin forever.
There is a subJVM process which doesn't seem to do anything.
Perhaps this subJVM process is the problem, i.e., it should have sent some 
output but
didn't for some reason.

What is unclear is why A4 runs fine when it is started as a Java application 
but it
doesn't run when it is started as an A4E plugin. The only difference is that the
above code runs in an 

As an A4E plugin, we get stuck here:
Thread [Worker-3] (Suspended (breakpoint at line 156 in ExecutableCommand)) 
    ExecutableCommand.execute(IReporter, IProgressMonitor) line: 156    
    AlloyLaunching.execCommand(IALSCommand, IReporter, IProgressMonitor) line: 256  
    AlloyLaunching.execCommand(IALSCommand, IProgressMonitor) line: 60  
    LaunchConfigurationDelegate.launch(ILaunchConfiguration, String, ILaunch,
IProgressMonitor) line: 66  
    LaunchConfiguration.launch(String, IProgressMonitor, boolean, boolean) line: 764    
    LaunchConfiguration.launch(String, IProgressMonitor, boolean) line: 614 
    DebugUIPlugin.buildAndLaunch(ILaunchConfiguration, String, IProgressMonitor) line: 880  
    DebugUIPlugin$8.run(IProgressMonitor) line: 1083    
    Worker.run() line: 55   

When I launch A4 from Eclipse as a Java application, the same WorkerEngine 
executes
at initialization in this context:

Thread [AWT-EventQueue-0] (Suspended (breakpoint at line 137 in WorkerEngine))  
    WorkerEngine.run(WorkerEngine$WorkerTask, int, int, String,
WorkerEngine$WorkerCallback) line: 137  
    SimpleGUI$9.callback(Object) line: 1787 
    SimpleGUI.<init>(String[]) line: 1799   
    SimpleGUI.<init>(String[], SimpleGUI$1) line: 165   
    SimpleGUI$7.run() line: 1707    
    InvocationEvent.dispatch() line: not available  
    EventQueue.dispatchEvent(AWTEvent) line: not available  
    EventDispatchThread.pumpOneEventForFilters(int) line: not available 
    EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: not
available   
    EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: not
available   
    EventDispatchThread.pumpEvents(int, Conditional) line: not available    
    EventDispatchThread.pumpEvents(Conditional) line: not available 
    EventDispatchThread.run() line: not available   

and a few times more in a similar context as this:

Thread [Thread-3] (Suspended (breakpoint at line 137 in WorkerEngine))  
    WorkerEngine.run(WorkerEngine$WorkerTask, int, int, String,
WorkerEngine$WorkerCallback) line: 137  
    SimpleGUI$9.callback(Object) line: 1787 
    SimpleGUI$9.done() line: 1792   
    WorkerEngine$3.run() line: 193  
    Thread.run() line: not available    

Then, when running a command, the WorkerEngine is invoked in an AWT thread like 
this:

Thread [AWT-EventQueue-0] (Suspended (breakpoint at line 137 in WorkerEngine))  
    WorkerEngine.run(WorkerEngine$WorkerTask, int, int, String,
WorkerEngine$WorkerCallback) line: 137  
    SimpleGUI.doRun(Integer) line: 982  
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available
[native method] 
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available   
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available   
    Method.invoke(Object, Object...) line: not available    
    SimpleGUI$2.run(Object) line: 582   
    SimpleGUI$2.run() line: 588 
    SimpleGUI$2(Runner).actionPerformed(ActionEvent) line: 50   
    JMenuItem(AbstractButton).fireActionPerformed(ActionEvent) line: not available  
    AbstractButton$Handler.actionPerformed(ActionEvent) line: not available 
    DefaultButtonModel.fireActionPerformed(ActionEvent) line: not available 
    DefaultButtonModel.setPressed(boolean) line: not available  
    JMenuItem(AbstractButton).doClick(int) line: not available  
    WindowsMenuItemUI(BasicMenuItemUI).doClick(MenuSelectionManager) line: not available    
    BasicMenuItemUI$Handler.mouseReleased(MouseEvent) line: not available   
    JMenuItem(Component).processMouseEvent(MouseEvent) line: not available  
    JMenuItem(JComponent).processMouseEvent(MouseEvent) line: not available 
    JMenuItem(Component).processEvent(AWTEvent) line: not available 
    JMenuItem(Container).processEvent(AWTEvent) line: not available 
    JMenuItem(Component).dispatchEventImpl(AWTEvent) line: not available    
    JMenuItem(Container).dispatchEventImpl(AWTEvent) line: not available    
    JMenuItem(Component).dispatchEvent(AWTEvent) line: not available    
    LightweightDispatcher.retargetMouseEvent(Component, int, MouseEvent) line: not
available   
    LightweightDispatcher.processMouseEvent(MouseEvent) line: not available 
    LightweightDispatcher.dispatchEvent(AWTEvent) line: not available   
    JFrame(Container).dispatchEventImpl(AWTEvent) line: not available   
    JFrame(Window).dispatchEventImpl(AWTEvent) line: not available  
    JFrame(Component).dispatchEvent(AWTEvent) line: not available   
    EventQueue.dispatchEvent(AWTEvent) line: not available  
    EventDispatchThread.pumpOneEventForFilters(int) line: not available 
    EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: not
available   
    EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: not
available   
    EventDispatchThread.pumpEvents(int, Conditional) line: not available    
    EventDispatchThread.pumpEvents(Conditional) line: not available 
    EventDispatchThread.run() line: not available   

Perhaps, there is something different about AWT vs. Eclipse's worker threads 
that
causes the WorkerEngine to run properly in the former but not in the latter.

Original comment by nicolas....@gmail.com on 24 Dec 2008 at 6:06

GoogleCodeExporter commented 8 years ago
Nicolas,

Here is my configuration:

Mandriva Linux 2009 

java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode)

Eclipse SDK
Version: 3.4.1
Build id: M20080911-1700

A4E 0.2.34

Your sample problem work fine for me.

I guess you run A4E on Windows?

Original comment by daniel.l...@gmail.com on 24 Dec 2008 at 8:35

GoogleCodeExporter commented 8 years ago
Regarding comment #1, a few explanations:

- since I built myself the alloy4.jar from Eclipse, I did not make it a self
executable jar file. That's my fault :)

- The output of your command line A4 is interesting: you have

But this works, kind of...
java -cp alloy4.jar edu.mit.csail.sdg.alloy4whole.SimpleGUI
alloy4.jar
Creating stream
Writing task
Writed task
Reading result

The alloy4.jar line is the value of the classpath provided to the WorkerEngine.

AFAIK, that classpath is correct.

The main issue to make A4 subVM process work fine under Eclipse is a classapth 
problem.

When running A4 from the command line, the subVM uses the java.class.path 
property.

When running A4 within Eclipse, you can no longer use that information. You 
need to
find all the classes necessary in the classpath of the subVM to create the 
classpath
to give to the new JVM. Here is the code that does that in ExecutableCommand:

StringBuffer classPath = new StringBuffer();
            classPath.append(FileLocator.toFileURL(
                    Activator.getDefault().getBundleContext().getBundle()
                            .getEntry("/alloy4.jar")).getFile());
            classPath.append(System.getProperty("path.separator"));
            classPath.append(FileLocator.toFileURL(
                    AlloyPlugin.getDefault().getBundleContext().getBundle()
                            .getEntry("/")).getFile());
            classPath.append(System.getProperty("path.separator"));
            URL url = AlloyPlugin.getDefault().getBundleContext().getBundle()
                    .getEntry("/bin");
            if (url != null) {
                classPath.append(FileLocator.toFileURL(url).getFile());
            }

Maybe the problem is related to my use of / and /bin that should be \ and \bin 
under
windows.

I just changed that code by

StringBuffer classPath = new StringBuffer();
            classPath.append(FileLocator.toFileURL(
                    Activator.getDefault().getBundleContext().getBundle()
                            .getEntry(File.separator+"alloy4.jar")).getFile());
            classPath.append(File.pathSeparator);
            classPath.append(FileLocator.toFileURL(
                    AlloyPlugin.getDefault().getBundleContext().getBundle()
                            .getEntry(File.separator)).getFile());
            classPath.append(File.pathSeparator);
            URL url = AlloyPlugin.getDefault().getBundleContext().getBundle()
                    .getEntry(File.separator+"bin");
            if (url != null) {
                classPath.append(FileLocator.toFileURL(url).getFile());
            }

on HEAD. 

Nicolas, could you give it a try?

Original comment by daniel.l...@gmail.com on 24 Dec 2008 at 9:02

GoogleCodeExporter commented 8 years ago
Checked in a partial fix for
fr.univartois.cril.alloyplugin.core.ExecutableCommand.execute(IReporter,
IProgressMonitor)

The problem is that the A4 WorkerEngine needs to wrap the argument to the
-Djava.library.path=... argument otherwise, if that path contains spaces, Java 
will
automatically add quotes around it,i.e., "-Djava.library.path=...." and then 
Java
won't recognize this argument. The argument needs to be: 
-Djava.library.path="...."

Still, there is more to this...

a) whatever standard output the subJVM command produces goes to ... nowhere.

b) I can copy/paste/edit the command being executed to make sure that it is of 
the form:

java ... -Djava.library.path="..." -cp "...." 
edu.mit.csail.sdg.alloy4.WorkerEngine
"2008/10/27 23:45 EDT" 880

This produces interesting output on my machine (windows, unfortunately):

java.io.FileNotFoundException: \tmp\debugError.txt (The system cannot find the 
path
specified)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.PrintStream.<init>(Unknown Source)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.log(WorkerEngine.java:549)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.main(WorkerEngine.java:379)
java.io.FileNotFoundException: \tmp\debugError.txt (The system cannot find the 
path
specified)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.PrintStream.<init>(Unknown Source)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.log(WorkerEngine.java:549)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.main(WorkerEngine.java:384)
java.io.FileNotFoundException: \tmp\debugError.txt (The system cannot find the 
path
specified)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.PrintStream.<init>(Unknown Source)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.log(WorkerEngine.java:549)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.main(WorkerEngine.java:389)
java.io.FileNotFoundException: \tmp\debugError.txt (The system cannot find the 
path
specified)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.PrintStream.<init>(Unknown Source)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.log(WorkerEngine.java:549)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.main(WorkerEngine.java:394)
java.io.FileNotFoundException: \tmp\debugError.txt (The system cannot find the 
path
specified)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.PrintStream.<init>(Unknown Source)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.log(WorkerEngine.java:549)
        at edu.mit.csail.sdg.alloy4.WorkerEngine.main(WorkerEngine.java:406)

Original comment by nicolas....@gmail.com on 27 Dec 2008 at 12:47

GoogleCodeExporter commented 8 years ago
SVN commit 744 adds a workaround to this problem, a preference option to 
execute A4
tasks locally instead of as a sub-process.

Original comment by nicolas....@gmail.com on 27 Dec 2008 at 2:54

GoogleCodeExporter commented 8 years ago
Nicolas,

the /tmp/debugError.txt file was the only way for me to check where the subJVM 
was up to.

I am disabling all those debug messages in a new alloy4.jar file.

Original comment by le.ber...@free.fr on 27 Dec 2008 at 8:46

GoogleCodeExporter commented 8 years ago
Nicolas,

I just checked your code for running the code locally. It is great!

Original comment by daniel.l...@gmail.com on 27 Dec 2008 at 8:57

GoogleCodeExporter commented 8 years ago
Daniel's fix works with A4 version 4.1.9

Original comment by nicolas....@gmail.com on 27 Dec 2008 at 11:12