Linux "launcher" script should export APP_HOME before starting the application


(Alex Sko) #1

the linux version of “launcher” script generated by Gradle does not export APP_HOME environment variable, which is inconsistent with the way the windows script (launcher.bat) works.

thus, I can’t use code like this to start Jetty and deploy my war file (unless I add “export APP_HOME” to the generated “launcher” file during the build):

package com;
  import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
  import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
  public class Launcher {
    private static final String WEB_APPLICATION_ROOT_CONTEXT = "/";
  private static final String WAR_FOLDER = "war";
  private static final String WAR_FILE_NAME = "my.war";
  private static final int SERVER_STARTUP_WAIT_INTERVAL_MSEC = 500;
    private int _portNumber;
  private boolean _needToOpenBrowser;
    private Launcher() {
  }
    public static void main(String[] args) {
    Launcher launcher = new Launcher();
    launcher.setNeedToOpenBrowser(LauncherParameterParser.needToOpenBrowser(args));
    launcher.setPortNumber(LauncherParameterParser.findPortNumberInArgs(args));
    launcher.go();
  }
    private void go() {
    try {
      startServer();
      openBrowserIfNeeded();
    } catch (Exception e) {
      System.out.println("Error starting server: " + e.toString());
    }
  }
    private void startServer() throws Exception {
    final Server server = new Server(_portNumber);
    server.setHandler(new WebAppContext(getWarFileAbsolutePath(), WEB_APPLICATION_ROOT_CONTEXT));
    System.out.println("Starting HTTP server on port " + _portNumber);
    server.start();
    while (!server.isStarted() || !server.getHandler().isStarted()) {
      try {
        Thread.sleep(SERVER_STARTUP_WAIT_INTERVAL_MSEC);
      } catch (InterruptedException e) {
        System.err.println("launcher process was interrupted while waiting for the server to start.");
      }
    }
    String uri = getURIString();
    System.out.println("=======================================================================");
    System.out.println("App is started as a WEB-server running on port " + _portNumber);
    System.out.println("Please OPEN your web browser with this URL: " + uri);
    System.out.println("=======================================================================");
  }
    private String getWarFileAbsolutePath() {
    // APP_HOME environment variable is set by the launcher script generated by Gradle.
    // it points to the root folder of the installed application.
    String appHome = System.getenv("APP_HOME");
    File folder = new File(appHome, WAR_FOLDER);
    File file = new File(folder, WAR_FILE_NAME);
    return file.getAbsolutePath();
  }
    private void openBrowserIfNeeded() throws IOException, URISyntaxException {
    if (_needToOpenBrowser) {
      openBrowser();
    } else {
      System.out.println("App launcher will open the browser automatically if you provide this parameter in the start script: " +
              LauncherParameterParser.PARAMETER_OPEN_PAGE_IN_WEB_BROWSER);
    }
  }
    private void openBrowser() throws URISyntaxException, IOException {
    Desktop desktop = Desktop.getDesktop();
    String uriString = getURIString();
    URI uri = new URI(uriString);
    desktop.browse(uri);
  }
    private String getURIString() {
    return "http://localhost:" + _portNumber + WEB_APPLICATION_ROOT_CONTEXT;
  }
    private void setNeedToOpenBrowser(boolean needToOpenBrowser) {
    this._needToOpenBrowser = needToOpenBrowser;
  }
    private void setPortNumber(int portNumber) {
    this._portNumber = portNumber;
  }
}

this is how I can make it work: export APP_HOME in “launcher” before starting the application:

export APP_HOME
  exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" com.Launcher "$@" $PD_ARGS

(Radim Kubacki) #2

Aside from your suggestion to enhance the way how the application is launched have you considered to use

Launcher.class.getProtectionDomain().getCodeSource().getLocation()

?