JAL-3631 JAL-3384 Install4j launch now redirects STDOUT/STDERR to ~/.jalview_develop...
authorBen Soares <b.soares@dundee.ac.uk>
Tue, 25 Jun 2024 22:13:55 +0000 (23:13 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Tue, 25 Jun 2024 22:13:55 +0000 (23:13 +0100)
16 files changed:
build.gradle
getdown/lib/getdown-core.jar
getdown/lib/getdown-launcher-local.jar
getdown/lib/getdown-launcher.jar
getdown/src/getdown/core/src/main/java/com/threerings/getdown/data/Application.java
getdown/src/getdown/core/src/main/java/jalview/util/ErrorLog.java
getdown/src/getdown/core/src/main/java/jalview/util/LaunchUtils.java
getdown/src/getdown/launcher/src/main/java/com/threerings/getdown/launcher/Getdown.java
getdown/src/getdown/launcher/src/main/java/com/threerings/getdown/launcher/GetdownApp.java
j11lib/getdown-core.jar
j8lib/getdown-core.jar
src/jalview/bin/Cache.java
src/jalview/bin/Jalview.java
src/jalview/util/ErrorLog.java
src/jalview/util/LaunchUtils.java
utils/install4j/install4j10_template.install4j

index 9738981..3625ffc 100644 (file)
@@ -3010,6 +3010,7 @@ task installerFiles(type: com.install4j.gradle.Install4jTask) {
     'INSTALLER_ICON': "${getdownImagesDir}/${install4j_installer_icon}",
     'INSTALLER_MAC_ICON': "${getdownImagesDir}/${install4j_installer_mac_icon}",
     'INSTALLER_WINDOWS_ICON': "${getdownImagesDir}/${install4j_installer_windows_icon}",
+    'LOG_FILE': "${install4jUnixApplicationFolder}.log",
   ]
 
   if (project.hasProperty("install4j_build_ids")) {
index 3174687..191df35 100644 (file)
Binary files a/getdown/lib/getdown-core.jar and b/getdown/lib/getdown-core.jar differ
index 85ed80e..7f40797 100644 (file)
Binary files a/getdown/lib/getdown-launcher-local.jar and b/getdown/lib/getdown-launcher-local.jar differ
index 6809084..bb2bf61 100644 (file)
Binary files a/getdown/lib/getdown-launcher.jar and b/getdown/lib/getdown-launcher.jar differ
index 74814c6..d210044 100644 (file)
@@ -1101,6 +1101,9 @@ public class Application
         if (System.getProperty("installer.template_version") != null) {
           args.add("-Dinstaller.template_version=" + System.getProperty("installer.template_version"));
         }
+        if (System.getProperty("installer.logfile") != null) {
+          args.add("-Dinstaller.logfile=" + System.getProperty("installer.logfile"));
+        }
         if (System.getProperty("installer.extrainfo") != null) {
           args.add("-Dinstaller.extrainfo=" + System.getProperty("installer.extrainfo"));
         }
@@ -2122,7 +2125,7 @@ public class Application
       try {
         config = Config.parseConfig(configFile, opts);
       } catch (IOException e) {
-        log.warning("Problem opening application config file", configFile);
+        log.warning("Problem opening application config file", "config", configFile);
         return false;
       }
       // get all types of local resource
@@ -2140,14 +2143,16 @@ public class Application
         log.warning("Problem opening application digest files", new File(applicationAppDir, Digest.digestFile(Digest.VERSION)));
         return false;
       }
+      log.info("New user, copying files from installation appdir to user appdir", "installation appdir", applicationAppDir, "user appdir", userAppDir);
       // copy getdown.txt, digest.txt and digest2.txt, getdown-launcher.jar, channel.props
       File getdownLauncher = new File(applicationAppDir, "getdown-launcher.jar");
       for (File from: new File[] {configFile, digest2.getFile(), digest.getFile(), getdownLauncher, new File(applicationAppDir, "channel.props")}) {
         try {
           File to = new File(userAppDir, from.getName());
           Files.copy(from.toPath(), to.toPath());
+          log.info("Copying file", "from", from, "to", to);
         } catch (IOException e) {
-          log.warning("Couldn't copy config/digest/getdown-launcher/channel file", from);
+          log.warning("Couldn't copy config/digest/getdown-launcher/channel file", "from", from);
         }
       }
       
@@ -2158,7 +2163,7 @@ public class Application
         try {
           actualHash = rsc.computeDigest(Digest.VERSION, md, null);
         } catch(IOException e) {
-          log.warning("Failed digest hash creation for resource", rsc);
+          log.warning("Failed digest hash creation for resource", "resource", rsc);
           continue;
         }
         if (digestHash == null || actualHash == null) {
@@ -2180,14 +2185,14 @@ public class Application
         }
         try {
           Files.copy(from.toPath(), to.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
-          log.info("Copying resource file", from, to);
+          log.info("Copying resource file", "from", from, "to", to);
           try {
             rsc.applyAttrs();
           } catch(IOException e2) {
-            log.error("Could not apply attributes to resource", rsc);
+            log.error("Could not apply attributes to resource", "resource", rsc);
           }
         } catch(IOException e) {
-          log.warning("Could not copy resource file", from, to);
+          log.warning("Could not copy resource file", "from", from, "to", to);
           continue;
         }
       }
index bbc758b..c204783 100644 (file)
@@ -111,11 +111,11 @@ public class ErrorLog
     {
       if (err)
       {
-        System.err.println("jalview.util.ErrorLog: " + message);
+        System.err.println(message);
       }
       else
       {
-        System.out.println("jalview.util.ErrorLog: " + message);
+        System.out.println(message);
 
       }
     }
index 58910a8..186745d 100644 (file)
@@ -53,6 +53,8 @@ public class LaunchUtils
   private static boolean isJS = /** @j2sNative true || */
           false;
 
+  public static final String LOGFILE_HANDOVER = "LOGFILE_HANDOVER";
+
   public static void loadChannelProps(File dir)
   {
     ChannelProperties.loadProps(dir);
@@ -593,88 +595,6 @@ public class LaunchUtils
     return exitValue;
   }
 
-  /*
-  public void invokeDirect() throws IOException
-  {
-    ClassPath classPath = PathBuilder.buildClassPath(this);
-    URL[] jarUrls = classPath.asUrls();
-  
-    // create custom class loader
-    URLClassLoader loader = new URLClassLoader(jarUrls,
-            ClassLoader.getSystemClassLoader())
-    {
-      @Override
-      protected PermissionCollection getPermissions(CodeSource code)
-      {
-        Permissions perms = new Permissions();
-        perms.add(new AllPermission());
-        return perms;
-      }
-    };
-    Thread.currentThread().setContextClassLoader(loader);
-  
-    log.info("Configured URL class loader:");
-    for (URL url : jarUrls)
-      log.info("  " + url);
-  
-    // configure any system properties that we can
-    for (String jvmarg : _jvmargs)
-    {
-      if (jvmarg.startsWith("-D"))
-      {
-        jvmarg = processArg(jvmarg.substring(2));
-        int eqidx = jvmarg.indexOf("=");
-        if (eqidx == -1)
-        {
-          log.warning("Bogus system property: '" + jvmarg + "'?");
-        }
-        else
-        {
-          System.setProperty(jvmarg.substring(0, eqidx),
-                  jvmarg.substring(eqidx + 1));
-        }
-      }
-    }
-  
-    // pass along any pass-through arguments
-    Map<String, String> passProps = new HashMap<>();
-    for (Map.Entry<Object, Object> entry : System.getProperties()
-            .entrySet())
-    {
-      String key = (String) entry.getKey();
-      if (key.startsWith(PROP_PASSTHROUGH_PREFIX))
-      {
-        key = key.substring(PROP_PASSTHROUGH_PREFIX.length());
-        passProps.put(key, (String) entry.getValue());
-      }
-    }
-    // we can't set these in the above loop lest we get a
-    // ConcurrentModificationException
-    for (Map.Entry<String, String> entry : passProps.entrySet())
-    {
-      System.setProperty(entry.getKey(), entry.getValue());
-    }
-  
-    // prepare our app arguments
-    String[] args = new String[_appargs.size()];
-    for (int ii = 0; ii < args.length; ii++)
-      args[ii] = processArg(_appargs.get(ii));
-  
-    try
-    {
-      log.info("Loading " + _class);
-      Class<?> appclass = loader.loadClass(_class);
-      Method main = appclass.getMethod("main",
-              EMPTY_STRING_ARRAY.getClass());
-      log.info("Invoking main({" + StringUtil.join(args, ", ") + "})");
-      main.invoke(null, new Object[] { args });
-    } catch (Exception e)
-    {
-      log.warning("Failure invoking app main", e);
-    }
-  }
-  */
-
   /**
    * Look for Implementation-Version in two jar manifests and compare according
    * to the getdown-launcher version spec (1.8.3-1.4.0_JVL or _FJVL) returns -1
index d366fed..aeb2dbd 100644 (file)
@@ -43,6 +43,8 @@ import com.threerings.getdown.net.HTTPDownloader;
 import com.threerings.getdown.tools.Patcher;
 import com.threerings.getdown.util.*;
 
+import jalview.util.LaunchUtils;
+
 import static com.threerings.getdown.Log.log;
 
 /**
@@ -1051,6 +1053,8 @@ public abstract class Getdown extends Thread
     protected abstract void exit (int exitCode);
 
     private static boolean _disposed = false;
+    
+    private static boolean _closed = false;
     /**
      * Copies the supplied stream from the specified input to the specified output. Used to copy
      * our child processes stderr and stdout to our own stderr and stdout.
@@ -1061,8 +1065,16 @@ public abstract class Getdown extends Thread
             BufferedReader reader = new BufferedReader(new InputStreamReader(in));
             String line;
             while ((line = reader.readLine()) != null) {
-                out.println(line);
-                out.flush();
+                if (!_closed) {
+                  out.println(line);
+                  out.flush();
+                }
+                // look for logfile handover
+                if (line.equals(LaunchUtils.LOGFILE_HANDOVER)) {
+                  out.flush();
+                  out.close();
+                  _closed = true;
+                }
                 // check for desktop creation line and end early
                 if (!_disposed && line.endsWith(": CREATED DESKTOP")) {
                   // pump the percent up to 100%
index b52363a..71a0402 100644 (file)
@@ -30,6 +30,7 @@ import com.samskivert.swing.util.SwingUtil;
 import com.threerings.getdown.data.Application;
 import com.threerings.getdown.data.Build;
 import com.threerings.getdown.data.EnvConfig;
+import com.threerings.getdown.data.EnvConfig.Note;
 import com.threerings.getdown.data.SysProps;
 import com.threerings.getdown.util.LaunchUtil;
 import com.threerings.getdown.util.StringUtil;
@@ -63,8 +64,9 @@ public class GetdownApp
    */
   public static Getdown start (String[] argv) throws Exception {
     jalview.util.ErrorLog.setHasConsole(false);
-    jalview.util.ErrorLog.setPrefix("GETDOWN - ");
+    jalview.util.ErrorLog.setPrefix("LAUNCHER - ");
     List<EnvConfig.Note> notes = new ArrayList<>();
+    boolean append = false;
     EnvConfig envc = EnvConfig.create(argv, notes, GetdownApp.class);
     if (envc == null) {
       if (!notes.isEmpty()) {
@@ -77,14 +79,26 @@ public class GetdownApp
       System.exit(EnvConfig.getRelaunched() ? 0 : -1);
     }
 
-    // pipe our output into a file in the application directory
+    // pipe our output into a file in the application directory, or other file
     if (!SysProps.noLogRedir()) {
-      File logFile = new File(envc.appDir, "launcher.log");
+      String logFileName = System.getProperty("installer.logfile");
+      File logFile;
+      if (logFileName != null) {
+        if (logFileName.startsWith("~/")) {
+          logFileName = System.getProperty("user.home") + File.separator + logFileName.substring(2);
+        }
+        logFile = new File(logFileName);
+        append = true;
+      } else {
+        logFile = new File(envc.appDir, "launcher.log");
+      }
       try {
         PrintStream logOut = new PrintStream(
-                new BufferedOutputStream(new FileOutputStream(logFile)), true);
+                new BufferedOutputStream(new FileOutputStream(logFile, append)), true);
         System.setOut(logOut);
         System.setErr(logOut);
+        log.info(Note.info("LAUNCHER starting to log"));
+        log.info(Note.info("Launcher logging to '" + logFile.getAbsolutePath() + "'"));
       } catch (IOException ioe) {
         log.warning("Unable to redirect output to '" + logFile + "': " + ioe);
       }
index 3174687..191df35 100644 (file)
Binary files a/j11lib/getdown-core.jar and b/j11lib/getdown-core.jar differ
index 3174687..191df35 100644 (file)
Binary files a/j8lib/getdown-core.jar and b/j8lib/getdown-core.jar differ
index 9d76cd2..d98395b 100755 (executable)
@@ -1238,14 +1238,16 @@ public class Cache
     sb.append("\n");
     appendIfNotNull(sb, "Channel: ",
             ChannelProperties.getProperty("channel"), "\n", null);
+    sb.append("Build Date: ");
+    sb.append(Cache.getDefault("BUILD_DATE", "unknown"));
+    sb.append("\n");
     if (extra)
     {
       appendIfNotNull(sb, "Preferences file: ", propertiesFile, "\n",
               "unknown");
+      appendIfNotNull(sb, "Log file: ",
+              System.getProperty("installer.logfile"), "\n", "unknown");
     }
-    sb.append("Build Date: ");
-    sb.append(Cache.getDefault("BUILD_DATE", "unknown"));
-    sb.append("\n");
     sb.append("Java version: ");
     sb.append(System.getProperty("java.version"));
     sb.append("\n");
index 8dfddcf..f8d5c66 100755 (executable)
@@ -21,6 +21,7 @@
 package jalview.bin;
 
 import java.awt.Color;
+import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -321,8 +322,43 @@ public class Jalview implements JalviewObjectI
 
     if (!Platform.isJS())
     {
-      // are we being --quiet ?
-      if (bootstrapArgs.contains(Arg.QUIET))
+      boolean usingLogfile = false;
+
+      // are we using a logfile?
+      String logFileName = System.getProperty("installer.logfile");
+      if (logFileName != null)
+      {
+        try
+        {
+          if (logFileName.startsWith("~/"))
+          {
+            logFileName = System.getProperty("user.home") + File.separator
+                    + logFileName.substring(2);
+          }
+          File logFile = new File(logFileName);
+
+          PrintStream logFilePrintStream = new PrintStream(
+                  new BufferedOutputStream(
+                          new FileOutputStream(logFile, true)),
+                  true);
+
+          Console.info(LaunchUtils.LOGFILE_HANDOVER);
+          System.setOut(logFilePrintStream);
+          System.setErr(logFilePrintStream);
+          Console.info(ChannelProperties.getProperty("app_name")
+                  .toUpperCase(Locale.ROOT) + " starting to log");
+          Console.info(ChannelProperties.getProperty("app_name")
+                  + " logging to " + logFileName);
+
+          usingLogfile = true;
+        } catch (FileNotFoundException e)
+        {
+          Console.errPrintln("Error opening logfile: " + e.getMessage());
+        }
+      }
+
+      // are we being --quiet ? (doesn't matter if using a logfile)
+      if (!usingLogfile && bootstrapArgs.contains(Arg.QUIET))
       {
         QUIET = true;
         OutputStream devNull = new OutputStream()
index bbc758b..c204783 100644 (file)
@@ -111,11 +111,11 @@ public class ErrorLog
     {
       if (err)
       {
-        System.err.println("jalview.util.ErrorLog: " + message);
+        System.err.println(message);
       }
       else
       {
-        System.out.println("jalview.util.ErrorLog: " + message);
+        System.out.println(message);
 
       }
     }
index 58910a8..186745d 100644 (file)
@@ -53,6 +53,8 @@ public class LaunchUtils
   private static boolean isJS = /** @j2sNative true || */
           false;
 
+  public static final String LOGFILE_HANDOVER = "LOGFILE_HANDOVER";
+
   public static void loadChannelProps(File dir)
   {
     ChannelProperties.loadProps(dir);
@@ -593,88 +595,6 @@ public class LaunchUtils
     return exitValue;
   }
 
-  /*
-  public void invokeDirect() throws IOException
-  {
-    ClassPath classPath = PathBuilder.buildClassPath(this);
-    URL[] jarUrls = classPath.asUrls();
-  
-    // create custom class loader
-    URLClassLoader loader = new URLClassLoader(jarUrls,
-            ClassLoader.getSystemClassLoader())
-    {
-      @Override
-      protected PermissionCollection getPermissions(CodeSource code)
-      {
-        Permissions perms = new Permissions();
-        perms.add(new AllPermission());
-        return perms;
-      }
-    };
-    Thread.currentThread().setContextClassLoader(loader);
-  
-    log.info("Configured URL class loader:");
-    for (URL url : jarUrls)
-      log.info("  " + url);
-  
-    // configure any system properties that we can
-    for (String jvmarg : _jvmargs)
-    {
-      if (jvmarg.startsWith("-D"))
-      {
-        jvmarg = processArg(jvmarg.substring(2));
-        int eqidx = jvmarg.indexOf("=");
-        if (eqidx == -1)
-        {
-          log.warning("Bogus system property: '" + jvmarg + "'?");
-        }
-        else
-        {
-          System.setProperty(jvmarg.substring(0, eqidx),
-                  jvmarg.substring(eqidx + 1));
-        }
-      }
-    }
-  
-    // pass along any pass-through arguments
-    Map<String, String> passProps = new HashMap<>();
-    for (Map.Entry<Object, Object> entry : System.getProperties()
-            .entrySet())
-    {
-      String key = (String) entry.getKey();
-      if (key.startsWith(PROP_PASSTHROUGH_PREFIX))
-      {
-        key = key.substring(PROP_PASSTHROUGH_PREFIX.length());
-        passProps.put(key, (String) entry.getValue());
-      }
-    }
-    // we can't set these in the above loop lest we get a
-    // ConcurrentModificationException
-    for (Map.Entry<String, String> entry : passProps.entrySet())
-    {
-      System.setProperty(entry.getKey(), entry.getValue());
-    }
-  
-    // prepare our app arguments
-    String[] args = new String[_appargs.size()];
-    for (int ii = 0; ii < args.length; ii++)
-      args[ii] = processArg(_appargs.get(ii));
-  
-    try
-    {
-      log.info("Loading " + _class);
-      Class<?> appclass = loader.loadClass(_class);
-      Method main = appclass.getMethod("main",
-              EMPTY_STRING_ARRAY.getClass());
-      log.info("Invoking main({" + StringUtil.join(args, ", ") + "})");
-      main.invoke(null, new Object[] { args });
-    } catch (Exception e)
-    {
-      log.warning("Failure invoking app main", e);
-    }
-  }
-  */
-
   /**
    * Look for Implementation-Version in two jar manifests and compare according
    * to the getdown-launcher version spec (1.8.3-1.4.0_JVL or _FJVL) returns -1
index e20aca9..ed4ef85 100644 (file)
@@ -75,6 +75,7 @@
       <variable name="INSTALLER_ICON" value="jalview_installer.png" />
       <variable name="INSTALLER_MAC_ICON" value="jalview_installer.icns" />
       <variable name="INSTALLER_WINDOWS_ICON" value="jalview_installer.ico" />
+      <variable name="LOG_FILE" value=".jalview.log" />
     </variables>
     <codeSigning macEnabled="true" macPkcs12File="${compiler:OSX_KEYSTORE}" macNotarize="true" appleId="${compiler:OSX_APPLEID}">
       <macAdditionalBinaries>
   </files>
   <launchers>
     <launcher name="Jalview User Launcher" id="2823" customizedId="JALVIEW" menuName="${compiler:JALVIEW_APPLICATION_NAME}" icnsFile="${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:MAC_ICONS_FILE}" customMacBundleIdentifier="true" macBundleIdentifier="${compiler:BUNDLE_ID}" fileset="734" addMacApplicationCategory="true" macApplicationCategory="public.app-category.education" useCustomMacosExecutableName="true" customMacosExecutableName="${compiler:JALVIEW_APPLICATION_NAME}">
-      <executable name="${compiler:EXECUTABLE_NAME}" iconSet="true" iconFile="${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}" stderrFile="~/.${compiler:UNIX_APPLICATION_FOLDER}-launcher.log" redirectStdout="true" stdoutFile="~/.${compiler:UNIX_APPLICATION_FOLDER}-launcher.log" executableMode="gui" changeWorkingDirectory="false" singleInstance="true" executionLevel="highestAvailable" checkConsoleParameter="true">
+      <executable name="${compiler:EXECUTABLE_NAME}" iconSet="true" iconFile="${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}" stderrFile="~/.${compiler:LOG_FILE}" redirectStdout="true" stdoutFile="~/.${compiler:LOG_FILE}" executableMode="gui" changeWorkingDirectory="false" singleInstance="true" executionLevel="highestAvailable" checkConsoleParameter="true">
         <versionInfo include="true" fileDescription="${compiler:sys.fullName}" legalCopyright="${compiler:COPYRIGHT_MESSAGE}" internalName="${compiler:INTERNAL_ID}" productName="${compiler:sys.fullName}" />
       </executable>
       <splashScreen width="640" height="480" bitmapFile="${compiler:JALVIEW_DIR}/${compiler:BACKGROUND}" textOverlay="true">
           <versionLine x="85" y="109" text="version ${compiler:sys.version}" />
         </text>
       </splashScreen>
-      <java mainClass="com.threerings.getdown.launcher.GetdownApp" vmParameters="-Duserdefaultappdir=true -Dpopulatedefaultappdir=true -Dappid=jalview -Dinstaller.template_version=${compiler:INSTALLER_TEMPLATE_VERSION} -Dinstaller.appdir=&quot;${launcher:sys.launcherDirectory}&quot; -Dinstaller.application_folder=&quot;${compiler:APPLICATION_FOLDER}&quot; -Dchannel.app_name=&quot;${compiler:JALVIEW_APPLICATION_NAME}&quot; -Dinstaller.icon=&quot;${compiler:PNG_ICON_FILE}&quot; -Dinstaller.mac_icons=&quot;${compiler:MAC_ICONS_FILE}&quot;" arguments="&quot;&quot; &quot;&quot;">
+      <java mainClass="com.threerings.getdown.launcher.GetdownApp" vmParameters="-Duserdefaultappdir=true -Dpopulatedefaultappdir=true -Dappid=jalview -Dinstaller.template_version=${compiler:INSTALLER_TEMPLATE_VERSION} -Dinstaller.appdir=&quot;${launcher:sys.launcherDirectory}&quot; -Dinstaller.application_folder=&quot;${compiler:APPLICATION_FOLDER}&quot; -Dchannel.app_name=&quot;${compiler:JALVIEW_APPLICATION_NAME}&quot; -Dinstaller.icon=&quot;${compiler:PNG_ICON_FILE}&quot; -Dinstaller.mac_icons=&quot;${compiler:MAC_ICONS_FILE}&quot; -Dinstaller.logfile=&quot;~/.${compiler:LOG_FILE}&quot;" arguments="&quot;&quot; &quot;&quot;">
         <classPath>
           <archive location="getdown-launcher.jar" failOnError="false" />
           <archive location="${compiler:GETDOWN_INSTALL_DIR}/getdown-launcher.jar" failOnError="false" />