Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>First off, let me say that anything this tricky is probably hard for a reason.</p> <p>This approach that may work for you if you really need it. As written, it assumes "java" is on the caller's path.</p> <p>Overview:</p> <ol> <li><p>Declare a Bootstrapper class as the main class in the jar's manifest. </p></li> <li><p>The bootstrapper spawns another process in which we call java (passing in any command-line arguments you want) on the "real" main class.</p></li> <li><p>Redirect the child processes System.out and System.err to the bootstrapper's respective streams</p></li> <li><p>Wait for the child process to finish</p></li> </ol> <p>Here's a <a href="http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html" rel="nofollow noreferrer">good background article</a>.</p> <p><strong>src/main/java/scratch/Bootstrap.java</strong> - this class is defined in pom.xml as the jar's mainclass: <code>&lt;mainClass&gt;scratch.Bootstrap&lt;/mainClass&gt;</code></p> <pre><code>package scratch; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; public class Bootstrap { class StreamProxy extends Thread { final InputStream is; final PrintStream os; StreamProxy(InputStream is, PrintStream os) { this.is = is; this.os = os; } public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { os.println(line); } } catch (IOException ex) { throw new RuntimeException(ex.getMessage(), ex); } } } private void go(){ try { /* * Spin up a separate java process calling a non-default Main class in your Jar. */ Process process = Runtime.getRuntime().exec("java -cp scratch-1.0-SNAPSHOT-jar-with-dependencies.jar -Xmx500m scratch.App"); /* * Proxy the System.out and System.err from the spawned process back to the user's window. This * is important or the spawned process could block. */ StreamProxy errorStreamProxy = new StreamProxy(process.getErrorStream(), System.err); StreamProxy outStreamProxy = new StreamProxy(process.getInputStream(), System.out); errorStreamProxy.start(); outStreamProxy.start(); System.out.println("Exit:" + process.waitFor()); } catch (Exception ex) { System.out.println("There was a problem execting the program. Details:"); ex.printStackTrace(System.err); if(null != process){ try{ process.destroy(); } catch (Exception e){ System.err.println("Error destroying process: "+e.getMessage()); } } } } public static void main(String[] args) { new Bootstrap().go(); } } </code></pre> <p><strong>src/main/java/scratch/App.java</strong> - this is the normal entry point for your program</p> <pre><code>package scratch; public class App { public static void main( String[] args ) { System.out.println( "Hello World! maxMemory:"+Runtime.getRuntime().maxMemory() ); } } </code></pre> <p>Calling: <code>java -jar scratch-1.0-SNAPSHOT-jar-with-dependencies.jar</code> Returns:</p> <pre><code>Hello World! maxMemory:520290304 Exit:0 </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload