title: How to do you get output from Javascript into Java using ScriptEngine
body: <p>With this simple piece of applescript I can list the names of all songs within iTunes</p>
  
  <pre><code>tell application "iTunes"
      set mainLibrary to library playlist 1
      repeat with nexttrack in (get every track of mainLibrary)
          try
              name of nexttrack
          end try
      end repeat
  end tell
  </code></pre>
  
  <p>I then run it as Java 7 code using ScriptEngine, however it is only obvious how to get the result of the script which in this case is the name of the last  track only.</p>
  
  <pre><code>    StringBuilder script =new StringBuilder();
      script.append("tell application \"iTunes\"\n");
      script.append("set mainLibrary to library playlist 1\n");
      script.append("repeat with nexttrack in (get every track of mainLibrary)\n");
      script.append("try\n");
      script.append("name of nexttrack\n");
      script.append("end try\n");
      script.append("end repeat\n");
      script.append("end tell\n");
      ScriptEngineManager mgr = new ScriptEngineManager();
      ScriptEngine engine = mgr.getEngineByName("AppleScript");
      System.out.println(engine.eval(script.toString()));
  
  How do can I capture the name of all tracks , i.e all output from the script. I assume I have to redirect standard out to a Reader, but cannot see how to do it.
  </code></pre>
  
  <p><strong>Update:</strong></p>
  
  <pre><code>I found this article 
  </code></pre>
  
  <p><a href="http://www.informit.com/articles/article.aspx?p=696621&amp;seqNum=6" rel="nofollow">http://www.informit.com/articles/article.aspx?p=696621&amp;seqNum=6</a></p>
  
  <p>But updating by code to </p>
  
  <pre><code>StringBuilder script =new StringBuilder();
  script.append("tell application \"iTunes\"\n");
  script.append("set mainLibrary to library playlist 1\n");
  script.append("repeat with nexttrack in (get every track of mainLibrary)\n");
  script.append("try\n");
  script.append("name of nexttrack\n");
  script.append("end try\n");
  script.append("end repeat\n");
  script.append("end tell\n");
  ScriptEngineManager mgr = new ScriptEngineManager();
  ScriptEngine engine = mgr.getEngineByName("AppleScript");
  StringWriter sw = new StringWriter();
  PrintWriter pw = new PrintWriter(sw);
  StringWriter swError = new StringWriter();
  PrintWriter pwError = new PrintWriter(swError);
  engine.getContext().setWriter(pw);
  engine.getContext().setErrorWriter(pwError);
  
  System.out.println(engine.eval(script.toString()));
  System.out.println("************* engine:"+sw.getBuffer());
  System.out.println("************* engine error:"+swError.getBuffer());
  </code></pre>
  
  <p>Just outputs</p>
  
  <pre><code>See You on the Other Side (short)
  ************* engine:
  ************* engine error:
  </code></pre>
  
  <p>So you can clearly see the script works as the eval shows the name of the last track , but I'm getting nothing back from the redirected writers. Wondering does this actually work for applescript ?</p>
  
  <p><strong>Update 2</strong>
  I wrote a test in Javascript and found setting the writers DID WORK for that so Im thinking that either</p>
  
  <ol>
  <li>There is something broken in script engine for Applescript ( Im using a recent build 1.7.0_40-ea-b29) of the early access version of Java 7 on OSX)</li>
  <li>My Applescript is wrong, i.e rather than just <em>name of nexttrack</em> I should be doing something like <em>echo name of nexttrack</em> to actually make it go to to stdout.</li>
  </ol>
  
  <p>I'd like to think (2) was the problem, but I canot find any reference to outputting text in Applescript, <strong>echo</strong> is not a valid command and the <strong>print</strong> command does actually try to print to a printer rather than print to stdout as it would in Java or C.</p>
  
  <p><strong>Update 3</strong>
  So I couldn't get this working, and now wondering if Applescript only ever writes the return value. I found an example of using stdout ( or so i thought) but I think that was just a naming convention, and in fact all it does is continually append data to a variable, and eventually return that.</p>
  
  <p>So I did it get something working by using the following script stored in a file, and then used in Java with engine.eval(new java.io.FileReader("<em>filename</em>") </p>
  
  <pre><code>tell application "iTunes"
      set output to ""
      set mainLibrary to library playlist 1
      repeat with nexttrack in (get every track of mainLibrary)
          if (class of nexttrack is file track) then
              try
                  set trackname to name of nexttrack
                  set loc to location of nexttrack
                  set locpath to POSIX path of loc
                  set persistid to persistent ID of nexttrack
                  set nextline to trackname &amp; "::" &amp; locpath &amp; "::" &amp; persistid
                  set output to output &amp; "\n" &amp; nextline
              end try
          end if
      end repeat
      copy output to stdout
  end tell
  </code></pre>
  
  <p>but this doesnt actually resolve the original question, and the one problem with it is that if there is any error then I wont get anything back, whereas if it failed halfway through reading my iTuneslibrary and I was using stdout I would at least get half the data back.</p>