Can't detect PDE vs command line, PDE no longer passing --external

Two years ago I developed a sketch that could be run from PDE or from the command line (processing-java) – optionally with arguments. I wanted the sketch to know which way it had been run (PDE or command line).

With help from @koogs, I developed a method, which worked in 3.4 and back but no longer works.

boolean PDE;
void setup() {
  String cmd = System.getProperty("sun.java.command");
  println(cmd);
  if (cmd.contains("--external")) {
    PDE=true;
  } else {
    PDE=false;
  }
  println(PDE);
}

That worked up to 3.4 – When run from PDE the output contains “–external” and the flag is set.

processing.core.PApplet --location=1213,185 --external --display=1 --sketch-path=/Users/student/Downloads/Test Test

Now, in 3.5.3, that method isn’t working anymore. When run from PDE, the “external” flag is missing.

processing.core.PApplet --display=1 --sketch-path=/Users/student/Downloads/Test Test

Any idea why / how this might have happened? Is it a bug / regression, or a change in Processing, or the bundled Java? I’m not even sure where to start looking.

2 Likes

A (non) update: I have an issue open on this, but I have never managed to track down which commit changed this behavior, where in the source code. At some point may need to just remove this feature from the JavaDoc documentation if it can’t be fixed…

1 Like

I ran your sketch:

Detect command line invocation of a sketch? - Processing 2.x and 3.x Forum

Command-line (Windows 10) output:

I did remove the exit() and added a draw() with a red background:

image

That is all I did to explore this…

:slight_smile:

Thanks – what version of processing-java and Processing?

I have a few versions of Processing installed so may not be using the version I expect from the command line:

Processing 3.5.3 is what I use; others versions installed also.

Windows 10

I referenced this topic for the cd:

Update:

:slight_smile:

1 Like

This got me exploring…

A “workaround” may be to pass “external” (anything will work here) as an argument and check for that.

:slight_smile:

1 Like

Thanks. 0269 is the latest, I believe.

Interesting workaround idea – should work. I’ll look at it with my toolchain.

Thanks for bringing this to the topics!
I will be using processing command-line in the future.

This is my first pass at this and “green” background from command-line launch and “red” from PDE launch:

//https://forum.processing.org/two/discussion/23999/detect-command-line-invocation-of-a-sketch
// 2019-08-25
// Modified to check for external argument only!

/**
 * CommandLineDetect
 * 2017-09-21 Jeremy Douglass - Processing 3.3.6 
 * Was a sketch run from PDE, or from the command line?
 * If from the command line, what are its arguments and their values?
 * 
 * Invoke it:
 * 1. from the command line above the sketch folder, with no arguments:
 *     processing-java --sketch=`pwd`/CommandLineDetect --run
 * 2. ...or with arguments:
 *     processing-java --sketch=`pwd`/CommandLineDetect --run foo bar=baz lorem="ipsum dolor sit amet, consectetur adipiscing elit" etc 
 * 3. or form PDE
 *
 * The sketch relies on the --external flag to detect a PDE launch, as per:
 * - processing.github.io/processing-javadocs/core/processing/core/PApplet.html#main-java.lang.String:A-
 * 
 * The command line passes in a String[] of args. If you wish to arguments of the:
 *  -  form foo=bar
 *  -  lorem="ipsum dolor"
 * 
 * Related forum discussions:
 * -  forum.processing.org/two/discussion/23999/detect-command-line-invocation-of-a-sketch
 * -  forum.processing.org/two/discussion/23924/handling-command-line-arguments-in-a-sketch
 * -  forum.processing.org/two/discussion/6457/how-to-use-arguments-with-an-application-built-with-processing
 */
 
// Some editing by GLV.  See original (above) for the complete version.

boolean PDE;
StringDict argDict = new StringDict();
color setBack = 0;
String str1;

void setup() 
  {

// Local command-line arguments for testing:  
// String [] args = {"external", "foo", "bar=baz", "lorem=ipsum dolor sit amet, consectetur adipiscing elit", "etc"};
  
  println(args == null ? "null" : args);
  if (args == null) 
    str1 = "internal";
  else
    str1 = args[0];
  
  if (str1.equals("external")) 
    {
    PDE=true;
    setBack = color(0, 255, 0);
    } 
  else 
    {
    PDE=false;
    setBack = color(255, 0, 0);
    }
 
  // load command line arguments, load them
  if (args != null) 
    {
    for (String arg : args) 
      {
      String[] entry = split(arg, "=");
      if (entry.length == 1) 
        {
        argDict.set(entry[0], "");
        }
      if (entry.length == 2) 
        {
        argDict.set(entry[0], entry[1]);
        }
      }
    }
 
  // set default if specific arg not present
  if (!argDict.hasKey("xyzzy")) {
    println("Setting default for xyzzy");
    // ...do something
  }
 
  // demonstrate using arguments
  for (String arg : argDict.keyArray()) {
    switch(arg) {
      
    case "external":
      //arg external
      println("mode:", arg);
      break;
    //case "foo":
    //  // key only arg
    //  println("mode:", arg);
    //  // ...do something
    //  break;
    case "bar":
      // key=value arg
      println("Setting", arg, "=", argDict.get(arg));
      // ...do something
      break;
    case "lorem":
      // parsed value
      String parsed = join(sort(argDict.get(arg).split(" ")), " ");
      println("Sorting", arg, "=", parsed);
      // ...do something
      break;
    }
  }
  //exit();
}

void draw()
  {
  background(setBack);  
  }

:slight_smile:

2 Likes

Really glad that this is helpful and useful to you. Looking forward to what you do with it.

When I developed this it was for Edger, a Processing sketch that could be invoked in two ways –

  1. from PDE, where it created a user interface for researchers to processing sparse edglist files into network graphs
  2. from the command line, so a Jekyll static site generator could batch process hundreds of network graphs for a website without launching the graphical interface.

Because the command line was invoking a batch-process mode, I wanted to the PDE version to launch-and-wait (for user input), and the command line version to launch-and-run (with optional command-line arguments). That was the original use case for detecting “how was I launched?” When it could be done automatically, that was elegant. But you are right – explicitly passing it a flag “external” (or perhaps “batch” in my use-case) is a solid workaround.

1 Like

Hello!

Just a few minutes ago, I discovered that System.getProperty("sun.java.command").split(" ") returns an array of length one, where the first argument is the sketch class’s name. Only the PDE adds the --display and the --sketch-path flags in. This is perhaps a helpful discovery, since one can now simply check if the other two arguments .contain() those exact flags. We could also add an extra argument for when the sketch runs outside the PDE, and run it only with that argument outside the PDE.

- Processing 3.5.4.

1 Like