Mercurial > hg > release > icedtea6-1.10
changeset 2288:f4f7b88ae02c
Merge
author | andrew |
---|---|
date | Mon, 11 Oct 2010 21:06:13 +0100 |
parents | 420a4eede08d (current diff) 4698e476b886 (diff) |
children | 2c5c2c6f314a |
files | ChangeLog NEWS |
diffstat | 8 files changed, 229 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Oct 11 21:05:13 2010 +0100 +++ b/ChangeLog Mon Oct 11 21:06:13 2010 +0100 @@ -14,6 +14,26 @@ * patches/security/20101012/6990437.patch: Added. +2010-10-08 Omair Majid <omajid@redhat.com> + + * NEWS: Updated + * net/sourceforge/jnlp/Launcher.java: Add fileLock. + (launchApplication): Call markNetxRunning and install a shutdown hook for + markNetxStopped. + (markNetxRunning): New method. + (markNetxStopped): New method. + * net/sourceforge/jnlp/cache/CacheUtil.java + (R): New method. + (clearCache): New method. + (okToClearCache): New method. + * net/sourceforge/jnlp/resources/Messages.properties: Add BXclearcache and + CCannotClearCache. + * net/sourceforge/jnlp/runtime/Boot.java + (run): Clear the cache. + * net/sourceforge/jnlp/runtime/JNLPRuntime.java: Add NETX_RUNNING_FILE. + * net/sourceforge/jnlp/util/FileUtils.java + (recursiveDelete): New method. + 2010-10-05 Andrew John Hughes <ahughes@redhat.com> * patches/security/20100330/hotspot/original/6626217.patch:
--- a/NEWS Mon Oct 11 21:05:13 2010 +0100 +++ b/NEWS Mon Oct 11 21:06:13 2010 +0100 @@ -38,6 +38,7 @@ - S6650759: Inference of formal type parameter (unused in formal parameters) is not performed * Netx - A new man page for javaws. + - Add a new option -Xclearcache * Plugin - PR554: System.err writes content two times - PR556: Applet initialization code is prone to race conditions
--- a/netx/net/sourceforge/jnlp/Launcher.java Mon Oct 11 21:05:13 2010 +0100 +++ b/netx/net/sourceforge/jnlp/Launcher.java Mon Oct 11 21:06:13 2010 +0100 @@ -20,12 +20,17 @@ import java.applet.Applet; import java.awt.Container; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.URL; import java.net.UnknownHostException; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; import java.util.LinkedList; import java.util.List; import java.util.jar.JarFile; @@ -78,6 +83,9 @@ /** If the application should call System.exit on fatal errors */ private boolean exitOnFailure = true; + /** a lock which is held to indicate that an instance of netx is running */ + private FileLock fileLock; + /** * Create a launcher with the runtime's default update policy * and launch handler. @@ -127,6 +135,7 @@ this.handler = handler; this.updatePolicy = policy; + } /** @@ -385,6 +394,11 @@ if (!file.isApplication()) throw launchError(new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LNotApplication"), R("LNotApplicationInfo"))); + markNetxRunning(); + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { markNetxStopped(); } + }); + try { try { @@ -686,6 +700,69 @@ return null; // chose to continue, or no handler } + /** + * Indicate that netx is running by creating the {@link JNLPRuntime#INSTANCE_FILE} and + * acquiring a shared lock on it + */ + private void markNetxRunning() { + try { + String message = "This file is used to check if netx is running"; + + File netxRunningFile = new File(JNLPRuntime.NETX_RUNNING_FILE); + netxRunningFile.getParentFile().mkdirs(); + if (netxRunningFile.createNewFile()) { + FileOutputStream fos = new FileOutputStream(netxRunningFile); + try { + fos.write(message.getBytes()); + } finally { + fos.close(); + } + } + + if (!netxRunningFile.isFile()) { + if (JNLPRuntime.isDebug()) { + System.err.println("Unable to create instance file"); + } + fileLock = null; + return; + } + + FileInputStream is = new FileInputStream(netxRunningFile); + FileChannel channel = is.getChannel(); + fileLock = channel.tryLock(0, Long.MAX_VALUE, true); + if (fileLock != null && fileLock.isShared()) { + if (JNLPRuntime.isDebug()) { + System.out.println("Acquired shared lock on " + + JNLPRuntime.NETX_RUNNING_FILE + " to indicate javaws is running"); + } + } else { + fileLock = null; + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + + /** + * Indicate that netx is stopped by releasing the shared lock on + * {@link JNLPRuntime#INSTANCE_FILE}. + */ + private void markNetxStopped() { + if (fileLock == null) { + return; + } + try { + fileLock.release(); + fileLock.channel().close(); + fileLock = null; + if (JNLPRuntime.isDebug()) { + System.out.println("Release shared lock on " + JNLPRuntime.NETX_RUNNING_FILE); + } + } catch (IOException e) { + e.printStackTrace(); + } + } /**
--- a/netx/net/sourceforge/jnlp/cache/CacheUtil.java Mon Oct 11 21:05:13 2010 +0100 +++ b/netx/net/sourceforge/jnlp/cache/CacheUtil.java Mon Oct 11 21:06:13 2010 +0100 @@ -19,6 +19,7 @@ import java.io.*; import java.net.*; +import java.nio.channels.FileChannel; import java.util.*; import java.lang.reflect.*; import java.security.*; @@ -37,6 +38,10 @@ */ public class CacheUtil { + private static String R(String key) { + return JNLPRuntime.getMessage(key); + } + private static String R(String key, Object param) { return JNLPRuntime.getMessage(key, new Object[] {param}); } @@ -129,6 +134,72 @@ } /** + * Clears the cache by deleting all the Netx cache files + * + * Note: Because of how our caching system works, deleting jars of another javaws + * process is using them can be quite disasterous. Hence why Launcher creates lock files + * and we check for those by calling {@link #okToClearCache()} + */ + public static void clearCache() { + + if (!okToClearCache()) { + System.err.println(R("CCannotClearCache")); + return; + } + + File cacheDir = new File(JNLPRuntime.getBaseDir() + File.separator + "cache"); + if (!(cacheDir.isDirectory())) { + return; + } + + if (JNLPRuntime.isDebug()) { + System.err.println("Clearing cache directory: " + cacheDir); + } + try { + FileUtils.recursiveDelete(cacheDir, JNLPRuntime.getBaseDir()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Returns a boolean indicating if it ok to clear the netx application cache at this point + * @return true if the cache can be cleared at this time without problems + */ + private static boolean okToClearCache() { + File otherJavawsRunning = new File(JNLPRuntime.NETX_RUNNING_FILE); + try { + if (otherJavawsRunning.isFile()) { + FileOutputStream fis = new FileOutputStream(otherJavawsRunning); + try { + FileChannel channel = fis.getChannel(); + if (channel.tryLock() == null) { + if (JNLPRuntime.isDebug()) { + System.out.println("Other instances of netx are running"); + } + return false; + } + + if (JNLPRuntime.isDebug()) { + System.out.println("No other instances of netx are running"); + } + return true; + + } finally { + fis.close(); + } + } else { + if (JNLPRuntime.isDebug()) { + System.out.println("No instance file found"); + } + return true; + } + } catch (IOException e) { + return false; + } + } + + /** * Returns whether there is a version of the URL contents in the * cache and it is up to date. This method may not return * immediately.
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties Mon Oct 11 21:05:13 2010 +0100 +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties Mon Oct 11 21:06:13 2010 +0100 @@ -139,6 +139,7 @@ BOViewer = Shows the trusted certificate viewer. BOUmask = Sets the umask for files created by an application. BXnofork = Do not create another JVM. +BXclearcache= Clean the JNLP application cache. BOHelp = Print this message and exit. # Cache @@ -149,6 +150,7 @@ CChooseCache=Choose a cache directory... CChooseCacheInfo=Netx needs a location for storing cache files. CChooseCacheDir=Cache directory +CCannotClearCache=Can not clear cache at this time # Security SFileReadAccess=The application has requested read access to {0}. Do you want to allow this action?
--- a/netx/net/sourceforge/jnlp/runtime/Boot.java Mon Oct 11 21:05:13 2010 +0100 +++ b/netx/net/sourceforge/jnlp/runtime/Boot.java Mon Oct 11 21:06:13 2010 +0100 @@ -40,6 +40,7 @@ import net.sourceforge.jnlp.ParseException; import net.sourceforge.jnlp.PropertyDesc; import net.sourceforge.jnlp.ResourcesDesc; +import net.sourceforge.jnlp.cache.CacheUtil; import net.sourceforge.jnlp.cache.UpdatePolicy; import net.sourceforge.jnlp.security.VariableX509TrustManager; import net.sourceforge.jnlp.security.viewer.CertificateViewer; @@ -114,6 +115,7 @@ + " -strict "+R("BOStrict")+"\n" + " -umask=value "+R("BOUmask")+"\n" + " -Xnofork "+R("BXnofork")+"\n" + + " -Xclearcache "+R("BXclearcache")+"\n" + " -help "+R("BOHelp")+"\n"; private static final String doubleArgs = "-basedir -jnlp -arg -param -property -update"; @@ -202,6 +204,17 @@ JNLPRuntime.setSecurityEnabled(null == getOption("-nosecurity")); JNLPRuntime.initialize(true); + /* + * FIXME + * This should have been done with the rest of the argument parsing + * code. But we need to know what the cache and base directories are, + * and baseDir is initialized here + */ + if (null != getOption("-Xclearcache")) { + CacheUtil.clearCache(); + return null; + } + try { new Launcher().launch(getFile()); }
--- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Mon Oct 11 21:05:13 2010 +0100 +++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Mon Oct 11 21:06:13 2010 +0100 @@ -18,6 +18,7 @@ package net.sourceforge.jnlp.runtime; import java.io.*; +import java.nio.channels.FileLock; import java.awt.*; import java.text.*; import java.util.*; @@ -132,6 +133,15 @@ public static final String LOCKS_DIR = TMP_DIR + File.separator + USER + File.separator + "netx" + File.separator + "locks"; + /** + * The /tmp/$USER/netx/locks/netx_running file is used to indicate if any + * instances of netx are running (this file may exist even if no instances + * are running). All netx instances acquire a shared lock on this file. If + * this file can be locked (using a {@link FileLock}) in exclusive mode, then + * other netx instances are not running + */ + public static final String NETX_RUNNING_FILE = LOCKS_DIR + File.separator + "netx_running"; + /** the java.home directory */ public static final String JAVA_HOME_DIR = System.getProperty("java.home");
--- a/netx/net/sourceforge/jnlp/util/FileUtils.java Mon Oct 11 21:05:13 2010 +0100 +++ b/netx/net/sourceforge/jnlp/util/FileUtils.java Mon Oct 11 21:06:13 2010 +0100 @@ -17,6 +17,9 @@ package net.sourceforge.jnlp.util; import java.io.File; +import java.io.IOException; + +import net.sourceforge.jnlp.runtime.JNLPRuntime; /** * This class contains a few file-related utility functions. @@ -121,4 +124,36 @@ return prefix + OMITTED + suffix; } + /** + * Recursively delete everything under a directory. Works on either files or + * directories + * + * @param file the file object representing what to delete. Can be either a + * file or a directory. + * @param base the directory under which the file and its subdirectories must be located + * @throws IOException on an io exception or if trying to delete something + * outside the base + */ + public static void recursiveDelete(File file, File base) throws IOException { + if (JNLPRuntime.isDebug()) { + System.err.println("Deleting: " + file); + } + + if (!(file.getCanonicalPath().startsWith(base.getCanonicalPath()))) { + throw new IOException("Trying to delete a file outside Netx's basedir: " + + file.getCanonicalPath()); + } + + if (file.isDirectory()) { + File[] children = file.listFiles(); + for (int i = 0; i < children.length; i++) { + recursiveDelete(children[i], base); + } + } + if (!file.delete()) { + throw new IOException("Unable to delete file: " + file); + } + + } + }