0

I have a java program that does some preparation and then invokes Jekyll on the content it's prepared. Jekyll is a Ruby program installed on the local PC as a gem. On windows and linux, no problem, but when running on OSX, under the eclipse debugger, Jekyll doesn't run. Presumably this is because of interactive shell issues (Jekyll runs fine from the terminal).

Here's my java code:

  DefaultExecutor exec = new DefaultExecutor(); // from org.apache.commons.exec
  exec.setExitValue(0);
  MyFilterHandler pumpHandler = new MyFilterHandler();
  exec.setWorkingDirectory(new File("/Users/grahamegrieve/temp/igs/swissnoso/temp/pages"));

  ProcessBuilder processBuilder = new ProcessBuilder(new String("bash -c jekyll build --destination /Users/grahamegrieve/temp/igs/swissnoso/output"));
  Map<String, String> env = processBuilder.environment();
  Map<String, String> vars = new HashMap<>();
  vars.putAll(env);
  String path = "/Users/grahamegrieve/.gem/ruby/3.1.0/bin:/Users/grahamegrieve/.gem/ruby/3.1.0/bin:/opt/homebrew/opt/ruby/bin:/Users/grahamegrieve/.nvm/versions/node/v17.4.0/bin:/opt/homebrew/bin:/opt/homebrew/sbin:"+env.get("PATH");
  vars.put("PATH", path);
  exec.execute(org.apache.commons.exec.CommandLine.parse("bash -c -i jekyll build --destination /Users/grahamegrieve/temp/igs/swissnoso/output"), vars);

this results in the following output from the process:

A subcommand is required.

followed by Jekyll's standard documentation - so Jekyll is running but not getting the parameters. The same thing happens in terminal:

➜  ~ bash -c jekyll build --destination /Users/grahamegrieve/temp/igs/swissnoso/output  
A subcommand is required. 
jekyll 4.2.1 -- Jekyll is a blog-aware, static site generator in Ruby

Usage:

  jekyll <subcommand> [options]

In the terminal, I can do this:

➜  ~ bash -c 'jekyll build --destination /Users/grahamegrieve/temp/igs/swissnoso/output'
Configuration file: none
            Source: /Users/grahamegrieve
       Destination: /Users/grahamegrieve/temp/igs/swissnoso/output
 Incremental build: disabled. Enable with --incremental
      Generating... 

so the parameters work fine when the entire command is wrapped in ''. But putting '' (or "") in the java code results in

Jekyll: bash: jekyll build --destination /Users/grahamegrieve/temp/igs/swissnoso/output: No such file or directory

As far as I can tell, that means there is no file with the name 'Jekyll build ...'.

So I don't know how to invoke Jekyll from my java code on OSX. Is it possible?

Grahame Grieve
  • 3,538
  • 3
  • 15
  • 17
  • Alternatively - or as well. What's the Java equivalent of this on the command line: visdiff /Users/grahamegrieve/temp/sdc.output.html /Users/grahamegrieve/temp/sdc.target.html - visdiff is a symlink to VisualDiffer. Or alternatively, what's any java code to compare two files visually. I suppose this might be a different question, but it seems tightly linked - about multiple parameters.... – Grahame Grieve Feb 10 '22 at 04:08
  • Well, this works for diff: Process p = Runtime.getRuntime().exec(new String[]{"opendiff", file1, file2}); – Grahame Grieve Feb 10 '22 at 05:31

1 Answers1

0

The answer is over here: execute shell command with org.apache.commons.exec.DefaultExecutor

It's to do with the way CommandLine works, and interacts with Bash.

DefaultExecutor exec = new DefaultExecutor(); // from org.apache.commons.exec
  exec.setExitValue(0);
  MyFilterHandler pumpHandler = new MyFilterHandler();
  exec.setWorkingDirectory(new File("/Users/grahamegrieve/temp/igs/swissnoso/temp/pages"));

  ProcessBuilder processBuilder = new ProcessBuilder(new String("bash -c jekyll build --destination /Users/grahamegrieve/temp/igs/swissnoso/output"));
  Map<String, String> env = processBuilder.environment();
  Map<String, String> vars = new HashMap<>();
  vars.putAll(env);
  String path = "/Users/grahamegrieve/.gem/ruby/3.1.0/bin:/Users/grahamegrieve/.gem/ruby/3.1.0/bin:/opt/homebrew/opt/ruby/bin:/Users/grahamegrieve/.nvm/versions/node/v17.4.0/bin:/opt/homebrew/bin:/opt/homebrew/sbin:"+env.get("PATH");
  vars.put("PATH", path);
  CommandLine cmd = new CommandLine("bash").addArgument("-c").addArgument("Jekyll build --destination /Users/grahamegrieve/temp/igs/swissnoso/output", false);
  exec.execute(cmd, vars);

Grahame Grieve
  • 3,538
  • 3
  • 15
  • 17