Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions SpecsUtils/src/pt/up/fe/specs/util/SpecsGraphviz.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,13 @@ public class SpecsGraphviz {
private static final Lazy<Boolean> IS_DOT_AVAILABLE = Lazy.newInstance(SpecsGraphviz::checkDot);

private static boolean checkDot() {
var result = SpecsSystem.runProcess(Arrays.asList("dot", "-?"), false, false);
return result.getReturnValue() == 0;
try {
var result = SpecsSystem.runProcess(Arrays.asList("dot", "-?"), false, false);
return result.getReturnValue() == 0;
} catch (RuntimeException e) {
// The launch itself failed, e.g. Graphviz is not installed
return false;
}
}

public static boolean isDotAvailable() {
Expand All @@ -47,9 +52,19 @@ public static void renderDot(File dotFile, DotRenderFormat format, File outputFi
var command = Arrays.asList("dot", format.getFlag(), dotFile.getAbsolutePath(), "-o",
outputFile.getAbsolutePath());

var result = SpecsSystem.runProcess(command, false, false);
if (result.getReturnValue() == 0) {
SpecsLogs.debug(() -> "Rendered dot file '" + dotFile.getAbsolutePath() + "' as " + format);
try {
var result = SpecsSystem.runProcess(command, false, false);
if (result.getReturnValue() == 0) {
SpecsLogs.debug(() -> "Rendered dot file '" + dotFile.getAbsolutePath() + "' as " + format);
}
} catch (RuntimeException e) {
// Only a missing Graphviz installation is skipped; any other
// failure is rethrown
if (!SpecsSystem.isLaunchFailure(e)) {
throw e;
}

SpecsLogs.msgInfo("Graphviz not available, could not render dot file '" + dotFile.getAbsolutePath() + "'");
}
}

Expand Down
43 changes: 21 additions & 22 deletions SpecsUtils/src/pt/up/fe/specs/util/SpecsSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,7 @@ public static <O, E> ProcessOutput<O, E> runProcess(ProcessBuilder builder,

Process process;
try {
// Experiment: Calling Garbage Collector before starting process in order to
// reduce memory required to fork VM
// http://www.bryanmarty.com/2012/01/14/forking-jvm/
long totalMemBefore = Runtime.getRuntime().totalMemory();
System.gc();
long totalMemAfter = Runtime.getRuntime().totalMemory();
SpecsLogs.msgLib("Preparing to run process, memory before -> after GC: "
+ SpecsStrings.parseSize(totalMemBefore) + " -> " + SpecsStrings.parseSize(totalMemAfter));
process = builder.start();
process = builder.start();

} catch (IOException e) {
throw new RuntimeException("Could not start process", e);
Expand Down Expand Up @@ -254,19 +246,6 @@ private static void processCommand(ProcessBuilder builder) {
newCommand.add("/c");
newCommand.addAll(builder.command());

builder.command(newCommand);
} else if (isLinux()) {
// Update command
List<String> newCommand = new ArrayList<>(4);
newCommand.add("bash");
// Same user
newCommand.add("-l");
// Command
newCommand.add("-c");
newCommand.add(builder.command().stream()
.map(arg -> arg.replace(" ", "\\ "))
.collect(Collectors.joining(" ")));

builder.command(newCommand);
}

Expand Down Expand Up @@ -599,6 +578,26 @@ public static boolean isCommandAvailable(List<String> command, File workingdir)

}

/**
* Checks if the throwable was caused by a failure to launch the process
* itself (e.g., command not found or not executable), as opposed to a
* failure after a successful launch.
*
* @param throwable
* @return
*/
public static boolean isLaunchFailure(Throwable throwable) {
for (Throwable currentThrowable = throwable; currentThrowable != null; currentThrowable = currentThrowable
.getCause()) {
if (currentThrowable instanceof IOException) {
return true;
}
}

return false;
}


/**
* Adds a path to the java.library.path property, and flushes the path cache so
* that subsequent System.load calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.io.File;
import java.util.List;

import pt.up.fe.specs.util.SpecsLogs;
import pt.up.fe.specs.util.SpecsSystem;

/**
Expand Down Expand Up @@ -45,7 +46,20 @@ public ProcessExecution(List<String> commandArgs, String workingFoldername) {
*/
@Override
public int run() {
return SpecsSystem.run(this.commandArgs, new File(this.workingFoldername));
try {
return SpecsSystem.run(this.commandArgs, new File(this.workingFoldername));
} catch (RuntimeException e) {
// Only a launch failure due to a missing command maps to a return
// code (the shell convention of 127, 'command not found'). Any
// other failure is not representable as an exit code and is
// rethrown, as the process may even have been running.
if (!SpecsSystem.isLaunchFailure(e)) {
throw e;
}

SpecsLogs.msgInfo("Could not run command '" + getCommandString() + "': " + e.getMessage());
return 127;
}
}

@Override
Expand Down
Loading