<code>phylip</code> (<code>phy</code>),
<br/>
<code>jalview</code> (<code>jvp, jar</code>).
+ </p>
<p>
For example, to open a FASTA file, append another FASTA file and then save the concatenation as a Stockholm file, do
<pre>
</p>
<p>
- <em>Important!</em> If you use <code>--output</code> or any other argument that outputs a file, then it will be assumed you want to run Jalview in headless mode (as if you had specified <code>--headless</code>). To use Jalview with <code>--output</code> and not assume headless mode, use the <code>--gui</code> or <code>--noheadless</code> argument (the order doesn't matter).
+ <em>Important!</em> If you use <code>--output</code> or any other argument that outputs a file, then it will be assumed you want to run Jalview in headless mode (as if you had specified <code>--headless</code>). To use Jalview with <code>--output</code> and not assume headless mode, use the <code>--gui</code> argument (the order doesn't matter).
</p>
+ <p>
+ If you would like to output an alignment file directly to standard output (often referred to as STDOUT), then use the filename <code>-</code> (a single hyphen). In this case any messages that would normally appear on STDOUT will be diverted to STDERR to avoid invalidating the output file.
+ </p>
+ <p>
+ For example, to open a Stockholm file and pipe it to another command as a Block file, do
+ <pre>
+ jalview --open alignment1.stk --output - --format blc | another_command
+ </pre>
+ or equivalently
+ <pre>
+ jalview alignment1.stk --output=[format=blc]- | another_command
+ </pre>
+ </p>
+
<h3><a name="format"></a><code>--format</code></h3>
<p>
<tr valign="top"><td><code>‑‑help‑all</code></td><td>Help for all arguments</td></tr>
<tr valign="top">
- <td><code>‑‑headless / ‑‑noheadless</code></td>
- <td>Run Jalview in headless (/ or not in headless) mode. In headless mode, no GUI interface will be created and Jalview will quit after all arguments have been processed.
+ <td><code>‑‑headless</code></td>
+ <td>Run Jalview in headless mode. In headless mode, no GUI interface will be created and Jalview will quit after all arguments have been processed.
<br/>
- If you use a command line argument to specify an output file of some kind (<code>--output</code>, <code>--image</code> or <code>--structureimage</code>) then <strong>headless mode will be assumed</strong>. If you don't want this behaviour use <code>--noheadless</code> or <code>--gui</code>.
+ If you use a command line argument to specify an output file of some kind (<code>--output</code>, <code>--image</code> or <code>--structureimage</code>) then <strong>headless mode will be assumed</strong>. If you don't want this behaviour use <code>--gui</code>.
</td>
</tr>
<code>phylip</code> (<code>phy</code>),
<br/>
<code>jalview</code> (<code>jvp, jar</code>).
+ <br/>
+ To output directly to STDOUT (console output) use the filename <code>-</code> (a single hyphen). In this case all STDOUT messages will instead go to STDERR. If no <code>format</code> is supplied then Fasta will be assumed.
</td>
<td><code>format=<em>name</em></code></td>
<td align="center">✓</td>
*/
package jalview.bin;
-import java.util.Locale;
-
import java.awt.HeadlessException;
+import java.util.Locale;
public class HiDPISetting
{
}
} catch (NumberFormatException e)
{
- System.err.println(setHiDPIScalePropertyName + " property give ("
- + setHiDPIScaleProperty + ") but not parseable as integer");
- jalview.bin.Console.errPrintln(setHiDPIScalePropertyName + " property give ("
- + setHiDPIScaleProperty + ") but not parseable as integer");
++ jalview.bin.Console.errPrintln(setHiDPIScalePropertyName
++ + " property give (" + setHiDPIScaleProperty
++ + ") but not parseable as integer");
}
}
if (setHiDPI && setHiDPIScale > 0)
try
{
int existingPropertyVal = Integer.parseInt(existingProperty);
- System.out.println("Existing " + scalePropertyName + " is "
- + existingPropertyVal);
- jalview.bin.Console.outPrintln("Existing " + scalePropertyName + " is "
- + existingPropertyVal);
++ jalview.bin.Console.outPrintln("Existing " + scalePropertyName
++ + " is " + existingPropertyVal);
if (existingPropertyVal > 1)
{
setHiDPIScale(existingPropertyVal);
}
} catch (NumberFormatException e)
{
- System.out.println("Could not convert property " + scalePropertyName
- + " vale '" + existingProperty + "' to number");
- jalview.bin.Console.outPrintln("Could not convert property " + scalePropertyName
- + " vale '" + existingProperty + "' to number");
++ jalview.bin.Console.outPrintln(
++ "Could not convert property " + scalePropertyName
++ + " vale '" + existingProperty + "' to number");
}
}
dpi = screenInfo.getScreenResolution();
} catch (HeadlessException e)
{
- jalview.bin.Console.errPrintln("Cannot get screen resolution: " + e.getMessage());
+ if (isLinux)
+ {
- System.err
- .println("Cannot get screen resolution: " + e.getMessage());
++ jalview.bin.Console.errPrintln(
++ "Cannot get screen resolution: " + e.getMessage());
+ }
}
// try and get screen size height and width
mindimension = Math.min(height, width);
} catch (HeadlessException e)
{
- jalview.bin.Console.errPrintln(
- "Cannot get screen size height and width:" + e.getMessage());
+ if (isLinux)
+ {
- System.err.println("Cannot get screen size height and width:"
- + e.getMessage());
++ jalview.bin.Console
++ .errPrintln("Cannot get screen size height and width:"
++ + e.getMessage());
+ }
}
// attempt at a formula for scaling based on screen dpi and mindimension.
{
private final static String startClass = "jalview.bin.Jalview";
- private static boolean checkJVMSymlink(String testBin)
- {
- File testBinFile = new File(testBin);
- if (!testBinFile.exists())
- {
- return false;
- }
- File targetFile = null;
- try
- {
- targetFile = testBinFile.getCanonicalFile();
- } catch (IOException e)
- {
- return false;
- }
- if (targetFile != null && ("java".equals(targetFile.getName())
- || "java.exe".equals(targetFile.getName())))
- {
- return true;
- }
- return false;
- }
+ private final static String headlessProperty = "java.awt.headless";
/**
* main method for jalview.bin.Launcher. This restarts the same JRE's JVM with
{
if (!LaunchUtils.checkJavaVersion())
{
- System.err.println("WARNING - The Java version being used (Java "
- + LaunchUtils.getJavaVersion()
- + ") may lead to problems. This installation of Jalview should be used with Java "
- + LaunchUtils.getJavaCompileVersion() + ".");
- jalview.bin.Console.errPrintln("WARNING - The Java version being used (Java "
- + LaunchUtils.getJavaVersion()
- + ") may lead to problems. This installation of Jalview should be used with Java "
- + LaunchUtils.getJavaCompileVersion() + ".");
- }
- final String appName = ChannelProperties.getProperty("app_name");
- final String javaBinDir = System.getProperty("java.home")
- + File.separator + "bin" + File.separator;
- String javaBin = null;
- if (javaBin == null && checkJVMSymlink(javaBinDir + appName))
- {
- javaBin = javaBinDir + appName;
- }
- if (javaBin == null && checkJVMSymlink(javaBinDir + "Jalview"))
- {
- javaBin = javaBinDir + "Jalview";
++ jalview.bin.Console
++ .errPrintln("WARNING - The Java version being used (Java "
++ + LaunchUtils.getJavaVersion()
++ + ") may lead to problems. This installation of Jalview should be used with Java "
++ + LaunchUtils.getJavaCompileVersion() + ".");
}
- if (javaBin == null)
- {
- javaBin = "java";
- }
-
- List<String> command = new ArrayList<>();
- command.add(javaBin);
-
- String memSetting = null;
-
- boolean isAMac = System.getProperty("os.name").indexOf("Mac") > -1;
-
- for (String jvmArg : ManagementFactory.getRuntimeMXBean()
- .getInputArguments())
- {
- command.add(jvmArg);
- }
- command.add("-cp");
- command.add(ManagementFactory.getRuntimeMXBean().getClassPath());
String jvmmempc = null;
String jvmmemmax = null;
boolean debug = false;
boolean wait = true;
boolean quiet = false;
+ boolean headless = false;
+ boolean gui = false;
+ boolean stdout = false;
// must set --debug before --launcher...
boolean launcherstop = false;
boolean launcherprint = false;
boolean launcherwait = false;
ArrayList<String> arguments = new ArrayList<>();
+ String previousArg = null;
for (String arg : args)
{
if (arg.equals("--debug"))
{
quiet = true;
}
+ if (arg.equals("--headless"))
+ {
+ headless = true;
+ }
+ if (arg.equals("--gui"))
+ {
+ gui = true;
+ }
+ if (arg.equals("--output=-")
+ || (arg.equals("-") && "--output".equals(previousArg)))
+ {
+ stdout = true;
+ }
if (debug && arg.equals("--launcherprint"))
{
launcherprint = true;
{
wait = false;
}
+ previousArg = arg;
// Don't add the --launcher... args to Jalview launch
if (arg.startsWith("--launcher"))
{
arguments.add(arg);
}
}
+ if (gui)
+ {
+ // --gui takes precedence over --headless
+ headless = false;
+ }
+
+ final String appName = ChannelProperties.getProperty("app_name");
+
+ // if we're using jalview.bin.Launcher we always assume a console is in use
+ final String javaBin = LaunchUtils.findJavaBin(true);
+
+ List<String> command = new ArrayList<>();
+ command.add(javaBin);
+
+ String memSetting = null;
+
+ for (String jvmArg : ManagementFactory.getRuntimeMXBean()
+ .getInputArguments())
+ {
+ command.add(jvmArg);
+ }
+ command.add("-cp");
+ command.add(ManagementFactory.getRuntimeMXBean().getClassPath());
// use saved preferences if no cmdline args
boolean useCustomisedSettings = LaunchUtils
boolean memSet = false;
boolean dockIcon = false;
boolean dockName = false;
+ boolean headlessProp = false;
for (int i = 0; i < command.size(); i++)
{
String arg = command.get(i);
{
dockName = true;
}
+ else if (arg.startsWith("-D" + headlessProperty + "="))
+ {
+ headlessProp = true;
+ }
}
if (!memSet)
}
}
- if (isAMac)
+ if (LaunchUtils.isMac)
{
if (!dockIcon)
{
+ appName);
}
}
+ if (headless && !headlessProp)
+ {
+ System.setProperty(headlessProperty, "true");
+ command.add("-D" + headlessProperty + "=true");
+ }
String scalePropertyArg = HiDPISetting.getScalePropertyArg();
if (scalePropertyArg != null)
{
- sysout(debug, quiet, "Running " + startClass + " with scale setting "
+ syserr(debug, quiet, "Running " + startClass + " with scale setting "
+ scalePropertyArg);
command.add(scalePropertyArg);
}
if ((Boolean.parseBoolean(System.getProperty("launcherprint", "false"))
|| launcherprint))
{
- sysout(debug, quiet,
+ syserr(debug, quiet,
"LAUNCHER COMMAND: " + String.join(" ", builder.command()));
}
- sysout(debug, quiet,
+ syserr(debug, quiet,
"Running " + startClass + " with "
+ (memSetting == null ? "no memory setting"
: ("memory setting " + memSetting)));
if (Boolean.parseBoolean(System.getProperty("launcherstop", "false"))
|| (debug && launcherstop))
{
- sysout(debug, quiet,
+ syserr(debug, quiet,
"System property 'launcherstop' is set and not 'false'. Exiting.");
System.exit(0);
}
Process process = builder.start();
if (wait || launcherwait)
{
- sysout(debug, quiet, "Launching application process");
+ syserr(debug, quiet, "Launching application process");
process.waitFor();
}
else
{
int waitInt = 0;
- sysout(debug, quiet,
+ syserr(debug, quiet,
"Wait time for application process is " + waitInt + "ms");
process.waitFor(waitInt, TimeUnit.MILLISECONDS);
}
- sysout(debug, quiet, "Launcher process ending");
+ syserr(debug, quiet, "Launcher process ending");
} catch (IOException e)
{
if (e.getMessage().toLowerCase(Locale.ROOT).contains("memory"))
{
- System.err.println("Caught a memory exception: " + e.getMessage());
- jalview.bin.Console.errPrintln("Caught a memory exception: " + e.getMessage());
++ jalview.bin.Console
++ .errPrintln("Caught a memory exception: " + e.getMessage());
// Probably the "Cannot allocate memory" error, try without the memory
// setting
ArrayList<String> commandNoMem = new ArrayList<>();
}
final ProcessBuilder builderNoMem = new ProcessBuilder(
commandNoMem);
- System.err.println("Command without memory setting: "
+ jalview.bin.Console.errPrintln("Command without memory setting: "
+ String.join(" ", builderNoMem.command()));
try
{
}
}
- private static void sysout(boolean debug, boolean quiet, String message)
+ private static void syserr(boolean debug, boolean quiet, String message)
{
if (debug && !quiet)
{
- System.out.println("LAUNCHERDEBUG - " + message);
+ jalview.bin.Console.errPrintln("LAUNCHERDEBUG - " + message);
}
}
Opt.UNARY, Opt.BOOTSTRAP),
HEADLESS(Type.CONFIG,
"Run Jalview in headless mode. No GUI interface will be created and Jalview will quit after all arguments have been processed. "
- + "Headless mode is assumed if an output file is to be generated, this can be overridden with --noheadless or --gui.",
- Opt.BOOLEAN, Opt.BOOTSTRAP),
+ + "Headless mode is assumed if an output file is to be generated, this can be overridden with --gui.",
+ Opt.UNARY, Opt.BOOTSTRAP),
GUI(Type.CONFIG,
"Do not run Jalview in headless mode. This overrides the assumption of headless mode when an output file is to be generated.",
Opt.UNARY, Opt.BOOTSTRAP),
+ "clustal (aln),\n" + "phylip (phy),\n"
+ "jalview (jvp, jar).",
Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS, Opt.ALLOWALL,
- Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.PRIMARY),
+ Opt.REQUIREINPUT, Opt.OUTPUTFILE, Opt.STDOUT, Opt.PRIMARY),
FORMAT(Type.OUTPUT,
"Sets the format for the preceding --output file. Valid formats are:\n"
+ "fasta,\n" + "pfam,\n" + "stockholm,\n" + "pir,\n"
*/
OUTPUTFILE("output file --headless will be assumed unless --gui used"),
/*
+ * A STDOUT Arg can take an output filename that can be '-' to mean print to STDOUT.
+ */
+ STDOUT("allows the output filename '" + ArgParser.STDOUTFILENAME
+ + "' to mean output to STDOUT"),
+ /*
* A STORED Arg resets and creates a new set of "opened" linkedIds
*/
STORED(null),
private Set<Type> argsTypes = new HashSet<>();
+ private boolean outputToStdout = false;
+
public static BootstrapArgs getBootstrapArgs(String[] args)
{
List<String> argList = new ArrayList<>(Arrays.asList(args));
{
if (argFiles.contains(inArgFile))
{
- System.err.println(
+ jalview.bin.Console.errPrintln(
"Looped argfiles detected: '" + inArgFile.getPath() + "'");
return;
}
}
}
- if (ArgParser.argMap.containsKey(argName) && val == null)
- {
- val = "true";
- }
-
Arg a = ArgParser.argMap.get(argName);
if (a != null)
if (a == null || !a.hasOption(Opt.BOOTSTRAP))
{
- // not a valid bootstrap arg
+ // not a bootstrap arg
+
+ // make a check for an output going to stdout
+ if (a != null && a.hasOption(Opt.OUTPUTFILE)
+ && a.hasOption(Opt.STDOUT))
+ {
+ if (val == null && i + 1 < args.size())
+ {
+ val = args.get(i + 1);
+ }
+ if (val.startsWith("[") && val.indexOf(']') > 0)
+ {
+ val = val.substring(val.indexOf(']') + 1);
+ }
+
+ if (ArgParser.STDOUTFILENAME.equals(val))
+ {
+ this.outputToStdout = true;
+ }
+ }
+
continue;
}
}
else
{
+ if (val == null)
+ {
+ val = "true";
+ }
+
add(a, type, val);
}
}
}
else if (this.contains(Arg.HEADLESS))
{
- // --headless, --noheadless specified => use value
+ // --headless has been specified on the command line => headless
isHeadless = this.getBoolean(Arg.HEADLESS);
}
else if (this.argsHaveOption(Opt.OUTPUTFILE))
}
return isHeadless;
}
+
+ public boolean outputToStdout()
+ {
+ return this.outputToStdout;
+ }
}
import java.net.URL;
import java.util.Properties;
+ import jalview.bin.Console;
+
public class LaunchUtils
{
+ // setting these is LaunchUtils so don't need to import Platform
+ public final static boolean isMac = System.getProperty("os.name")
+ .indexOf("Mac") > -1;
+
+ public final static boolean isWindows = System.getProperty("os.name")
+ .indexOf("Win") > -1;
+
+ private static boolean isJS = /** @j2sNative true || */
+ false;
+
public static void loadChannelProps(File dir)
{
ChannelProperties.loadProps(dir);
return null;
} catch (IOException e)
{
- System.err.println(e.getMessage());
+ jalview.bin.Console.errPrintln(e.getMessage());
return null;
}
}
public static int getJavaCompileVersion()
{
- if (Platform.isJS())
+ if (LaunchUtils.isJS)
{
return -1;
}
null);
if (JCV == null)
{
- System.out.println(
+ Console.errPrintln(
"Could not obtain JAVA_COMPILE_VERSION for comparison");
return -2;
}
JAVA_COMPILE_VERSION = Integer.parseInt(JCV);
} catch (MalformedURLException e)
{
- System.err.println("Could not find " + buildDetails);
+ jalview.bin.Console.errPrintln("Could not find " + buildDetails);
return -3;
} catch (IOException e)
{
- System.err.println("Could not load " + buildDetails);
+ jalview.bin.Console.errPrintln("Could not load " + buildDetails);
return -4;
} catch (NumberFormatException e)
{
- System.err.println("Could not parse JAVA_COMPILE_VERSION");
+ jalview.bin.Console.errPrintln("Could not parse JAVA_COMPILE_VERSION");
return -5;
}
public static int getJavaVersion()
{
- if (Platform.isJS())
+ if (LaunchUtils.isJS)
{
return -1;
}
String JV = System.getProperty("java.version");
if (JV == null)
{
- System.out.println("Could not obtain java.version for comparison");
+ Console.errPrintln("Could not obtain java.version for comparison");
return -2;
}
if (JV.startsWith("1."))
: Integer.parseInt(JV.substring(0, JV.indexOf(".")));
} catch (NumberFormatException e)
{
- System.err.println("Could not parse java.version");
+ jalview.bin.Console.errPrintln("Could not parse java.version");
return -3;
}
return JAVA_VERSION;
public static boolean checkJavaVersion()
{
- if (Platform.isJS())
+ if (LaunchUtils.isJS)
{
return true;
}
if (java_compile_version <= 0 || java_version <= 0)
{
- System.out.println("Could not make Java version check");
+ Console.errPrintln("Could not make Java version check");
return true;
}
// Warn if these java.version and JAVA_COMPILE_VERSION conditions exist
return true;
}
+
+ public static String findJavaBin(boolean winConsole)
+ {
+ return findJavaBin(System.getProperty("java.home"), winConsole, true);
+ }
+
+ /*
+ * Returns a string path to the most likely java binary wanted to run this
+ * installation of Jalview.
+ *
+ * @param winConsole whether to use java.exe (console) in preference to javaw.exe
+ * (only affects Windows).
+ * @param javaHome Try this javaHome dir (defaults to the running java.home).
+ * @param generic Return a generic java command if not found.
+ */
+ public static String findJavaBin(String javaHome, boolean winConsole,
+ boolean generic)
+ {
+ String javaBin = null;
+ final String javaExe = winConsole ? "java.exe" : "javaw.exe";
+ final String java = "java";
+
+ if (javaHome != null)
+ {
+ // property "channel.app_name" is set by install4j when launching getdown
+ String propertyAppName = System.getProperty("channel.app_name");
+ final String appName = (propertyAppName != null
+ && propertyAppName.length() > 0) ? propertyAppName
+ : ChannelProperties.getProperty("app_name");
+
+ final String javaBinDir = javaHome + File.separator + "bin"
+ + File.separator;
+
+ // appName and "Jalview" will not point to javaw.exe or java.exe but in
+ // this case that's okay because the taskbar display name problem doesn't
+ // manifest in Windows. See JAL-3820, JAL-4189.
+ for (String name : new String[] { appName, "Jalview", java, javaExe })
+ {
+ if (LaunchUtils.checkJVMSymlink(javaBinDir + name, winConsole))
+ {
+ javaBin = javaBinDir + name;
+ break;
+ }
+ }
+ }
+
+ if (javaBin == null && generic)
+ {
+ javaBin = LaunchUtils.isWindows ? javaExe : java;
+ }
+
+ return javaBin;
+ }
+
+ /*
+ * checkJVMSymlink returns true if the path in testBin *is* a java binary, or
+ * points to a java binary.
+ * @param testBin The binary or symbolic link to check
+ * @param winConsole whether we are in/want a Windows console (only relevant for Windows,
+ * determines whether we use java.exe or javaw.exe)
+ */
+ private static boolean checkJVMSymlink(String testBin, boolean winConsole)
+ {
+ File testBinFile = new File(testBin);
+ if (!testBinFile.exists())
+ {
+ return false;
+ }
+ File targetFile = null;
+ try
+ {
+ targetFile = testBinFile.getCanonicalFile();
+ } catch (IOException e)
+ {
+ return false;
+ }
+ final String javaExe = winConsole ? "java.exe" : "javaw.exe";
+ if (targetFile != null && ("java".equals(targetFile.getName())
+ || javaExe.equals(targetFile.getName())))
+ {
+ return true;
+ }
+ return false;
+ }
}