Mercurial > hg > release > icedtea6-1.10
changeset 1595:0b4d2e77cf97
2009-06-10 Omair Majid <omajid@redhat.com>
* rt/net/sourceforge/jnlp/JNLPFile.java
(needsNewJVM): New function. Returns true if the JNLP file requires
creating a new JVM.
(getNewVMArgs): New function. Returns arguments to pass to the new JVM.
* rt/net/sourceforge/jnlp/JREDesc.java
(getVMArgs): Fix javadoc to reflect that return value can be null.
* rt/net/sourceforge/jnlp/Launcher.java
(launchExternal): Modify to take in arguments to pass to the JVM and
arguments to pass to Netx. Try to use the local file to launch this
instance if possible.
(launchExternal): Delegate to new launchExternal.
(launchExternal): New method. Take in arguments to pass to the JVM and
arguments to pass to Netx. Launch Netx with the with the appropriate
arguments.
(launchApplication): If needed, launch a new JVM and pass along the Netx
arguments.
* rt/net/sourceforge/jnlp/Parser.java:
(getJRE): Call checkVMArgs to check 'java-vm-args' for security. If that
fails, assume 'java-vm-args' is null.
(checkVMArgs): New method. Check that the vmArgs variable contains safe
arguments only.
(getValidVMArguments): New method.
(getValidStartingVMArguments): New method.
* rt/net/sourceforge/jnlp/resources/Messages.properties: Add BXnofork.
* rt/net/sourceforge/jnlp/runtime/Boot/java:
Add -Xnofork to helpMessage
(main): Check for '-Xnofork'. Set initial arguments.
* rt/net/sourceforge/jnlp/runtime/JNLPRuntime.java:
Add forksAllowed to store whether creating a new JVM is allowed. Add
initialArguments to store the arguments to Netx.
(getForksAllowed): New function. Check if creating a new JVM is allowed.
(setForksAllowed): New function. Set whether creating a JVM is allowed.
(setInitialArguments): New function. Store the arguments passed to Netx.
(getInitialArguments): New function. Return the arguments passed to Netx.
author | Omair Majid <omajid@redhat.com> |
---|---|
date | Wed, 10 Jun 2009 12:00:53 -0400 |
parents | c68aaf028ad2 |
children | 0a1a8cd8eda3 |
files | ChangeLog rt/net/sourceforge/jnlp/JNLPFile.java rt/net/sourceforge/jnlp/JREDesc.java rt/net/sourceforge/jnlp/Launcher.java rt/net/sourceforge/jnlp/Parser.java rt/net/sourceforge/jnlp/resources/Messages.properties rt/net/sourceforge/jnlp/runtime/Boot.java rt/net/sourceforge/jnlp/runtime/JNLPRuntime.java |
diffstat | 8 files changed, 321 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Wed Jun 10 10:53:03 2009 -0400 +++ b/ChangeLog Wed Jun 10 12:00:53 2009 -0400 @@ -1,3 +1,40 @@ +2009-06-10 Omair Majid <omajid@redhat.com> + + * rt/net/sourceforge/jnlp/JNLPFile.java + (needsNewJVM): New function. Returns true if the JNLP file requires + creating a new JVM. + (getNewVMArgs): New function. Returns arguments to pass to the new JVM. + * rt/net/sourceforge/jnlp/JREDesc.java + (getVMArgs): Fix javadoc to reflect that return value can be null. + * rt/net/sourceforge/jnlp/Launcher.java + (launchExternal): Modify to take in arguments to pass to the JVM and + arguments to pass to Netx. Try to use the local file to launch this + instance if possible. + (launchExternal): Delegate to new launchExternal. + (launchExternal): New method. Take in arguments to pass to the JVM and + arguments to pass to Netx. Launch Netx with the with the appropriate + arguments. + (launchApplication): If needed, launch a new JVM and pass along the Netx + arguments. + * rt/net/sourceforge/jnlp/Parser.java: + (getJRE): Call checkVMArgs to check 'java-vm-args' for security. If that + fails, assume 'java-vm-args' is null. + (checkVMArgs): New method. Check that the vmArgs variable contains safe + arguments only. + (getValidVMArguments): New method. + (getValidStartingVMArguments): New method. + * rt/net/sourceforge/jnlp/resources/Messages.properties: Add BXnofork. + * rt/net/sourceforge/jnlp/runtime/Boot/java: + Add -Xnofork to helpMessage + (main): Check for '-Xnofork'. Set initial arguments. + * rt/net/sourceforge/jnlp/runtime/JNLPRuntime.java: + Add forksAllowed to store whether creating a new JVM is allowed. Add + initialArguments to store the arguments to Netx. + (getForksAllowed): New function. Check if creating a new JVM is allowed. + (setForksAllowed): New function. Set whether creating a JVM is allowed. + (setInitialArguments): New function. Store the arguments passed to Netx. + (getInitialArguments): New function. Return the arguments passed to Netx. + 2009-06-10 Omair Majid <omajid@redhat.com> * rt/net/sourceforge/jnlp/services/XBasicService.java
--- a/rt/net/sourceforge/jnlp/JNLPFile.java Wed Jun 10 10:53:03 2009 -0400 +++ b/rt/net/sourceforge/jnlp/JNLPFile.java Wed Jun 10 12:00:53 2009 -0400 @@ -17,12 +17,19 @@ package net.sourceforge.jnlp; -import java.io.*; -import java.net.*; -import java.util.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; -import net.sourceforge.jnlp.cache.*; -import net.sourceforge.jnlp.runtime.*; +import net.sourceforge.jnlp.cache.ResourceTracker; +import net.sourceforge.jnlp.cache.UpdatePolicy; +import net.sourceforge.jnlp.runtime.JNLPRuntime; /** * Provides methods to access the information in a Java Network @@ -520,4 +527,48 @@ } } + /** + * + * @return true if the JNLP file specifies things that can only be + * applied on a new vm (eg: different max heap memory) + */ + public boolean needsNewVM() { + + if (getNewVMArgs().size() == 0) { + return false; + } else { + return true; + } + } + + /** + * @return a list of args to pass to the new + * JVM based on this JNLP file + */ + public List<String> getNewVMArgs() { + + List<String> newVMArgs = new LinkedList<String>(); + + JREDesc[] jres = getResources().getJREs(); + for (int jreIndex = 0; jreIndex < jres.length; jreIndex++) { + String initialHeapSize = jres[jreIndex].getInitialHeapSize(); + if (initialHeapSize != null) { + newVMArgs.add("-Xms" + initialHeapSize); + } + + String maxHeapSize = jres[jreIndex].getMaximumHeapSize(); + if (maxHeapSize != null) { + newVMArgs.add("-Xmx" + maxHeapSize); + } + + String vmArgsFromJre = jres[jreIndex].getVMArgs(); + if (vmArgsFromJre != null) { + String[] args = vmArgsFromJre.split(" "); + newVMArgs.addAll(Arrays.asList(args)); + } + } + + return newVMArgs; + } + }
--- a/rt/net/sourceforge/jnlp/JREDesc.java Wed Jun 10 10:53:03 2009 -0400 +++ b/rt/net/sourceforge/jnlp/JREDesc.java Wed Jun 10 12:00:53 2009 -0400 @@ -121,6 +121,7 @@ /** * Returns the additional arguments to pass to the Java VM + * Can be null */ public String getVMArgs() { return vmArgs;
--- a/rt/net/sourceforge/jnlp/Launcher.java Wed Jun 10 10:53:03 2009 -0400 +++ b/rt/net/sourceforge/jnlp/Launcher.java Wed Jun 10 12:00:53 2009 -0400 @@ -17,16 +17,27 @@ package net.sourceforge.jnlp; -import java.applet.*; +import java.applet.Applet; import java.awt.Container; -import java.io.*; -import java.net.*; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.LinkedList; +import java.util.List; import java.util.jar.JarFile; -import java.lang.reflect.*; -import net.sourceforge.jnlp.cache.*; -import net.sourceforge.jnlp.runtime.*; -import net.sourceforge.jnlp.util.*; +import net.sourceforge.jnlp.cache.CacheUtil; +import net.sourceforge.jnlp.cache.ResourceTracker; +import net.sourceforge.jnlp.cache.UpdatePolicy; +import net.sourceforge.jnlp.runtime.AppThreadGroup; +import net.sourceforge.jnlp.runtime.AppletInstance; +import net.sourceforge.jnlp.runtime.ApplicationInstance; +import net.sourceforge.jnlp.runtime.JNLPClassLoader; +import net.sourceforge.jnlp.runtime.JNLPRuntime; +import net.sourceforge.jnlp.util.Reflect; /** * Launches JNLPFiles either in the foreground or background.<p> @@ -238,44 +249,67 @@ * application's output is sent to the system out and it's * standard input channel is closed. * + * @param vmArgs the arguments to pass to the new JVM. Can be empty but + * must not be null. * @param file the JNLP file to launch + * @param javawsArgs the arguments to pass to the javaws command. Can be + * an empty list but must not be null. * @throws LaunchException if there was an exception */ - public void launchExternal(JNLPFile file) throws LaunchException { - if (file.getSourceLocation() != null) - launchExternal(file.getSourceLocation()); - else if (file.getFileLocation() != null) - launchExternal(file.getFileLocation()); + public void launchExternal(List<String> vmArgs, JNLPFile file, List<String> javawsArgs) throws LaunchException { + List<String> updatedArgs = new LinkedList<String>(javawsArgs); + + if (file.getFileLocation() != null) + updatedArgs.add(file.getFileLocation().toString()); + else if (file.getSourceLocation() != null) + updatedArgs.add(file.getFileLocation().toString()); else launchError(new LaunchException(file, null, R("LSFatal"), R("LCExternalLaunch"), R("LNullLocation"), R("LNullLocationInfo"))); + + launchExternal(vmArgs, updatedArgs); + + } + + /** + * Launches the JNLP file in a new JVM instance. The launched + * application's output is sent to the system out and it's + * standard input channel is closed. + * + * @param url the URL of the JNLP file to launch + * @throws LaunchException if there was an exception + */ + public void launchExternal(URL url) throws LaunchException { + List<String> javawsArgs = new LinkedList<String>(); + javawsArgs.add(url.toString()); + launchExternal(new LinkedList<String>(), javawsArgs); } /** * Launches the JNLP file at the specified location in a new JVM * instance. The launched application's output is sent to the * system out and it's standard input channel is closed. - * - * @param location the URL of the JNLP file to launch + * @param vmArgs the arguments to pass to the jvm + * @param javawsArgs the arguments to pass to javaws (aka Netx) * @throws LaunchException if there was an exception */ - public void launchExternal(URL location) throws LaunchException { + public void launchExternal(List<String> vmArgs, List<String> javawsArgs) throws LaunchException { try { - URL cs = Launcher.class.getProtectionDomain().getCodeSource().getLocation(); - if (JNLPRuntime.isDebug()) - System.out.println("netx.jar path: "+cs.getPath()); - File netxFile = new File(cs.getPath()); - if (!netxFile.exists()) - throw launchError(new LaunchException(null, null, R("LSFatal"), R("LCExternalLaunch"), R("LNetxJarMissing"), R("LNetxJarMissingInfo"))); - - String command[] = { - "javaw", - "-jar", - netxFile.toString(), - "-jnlp", - location.toString(), - "-verbose", - }; + List<String> commands = new LinkedList<String>(); + + String pathToWebstartBinary = System.getProperty("java.home") + + File.separatorChar + + "bin" + + File.separatorChar + + "javaws"; + commands.add(pathToWebstartBinary); + // use -Jargument format to pass arguments to the JVM through the launcher + for (String arg: vmArgs) { + commands.add("-J" + arg); + } + commands.addAll(javawsArgs); + + String[] command = commands.toArray(new String[] {}); Process p = Runtime.getRuntime().exec(command); new StreamEater(p.getErrorStream()).start(); @@ -331,6 +365,15 @@ throw launchError(new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LNotApplication"), R("LNotApplicationInfo"))); try { + + if (JNLPRuntime.getForksAllowed() && file.needsNewVM()) { + List<String> netxArguments = new LinkedList<String>(); + netxArguments.add("-Xnofork"); + netxArguments.addAll(JNLPRuntime.getInitialArguments()); + launchExternal(file.getNewVMArgs(), netxArguments); + return null; + } + final int preferredWidth = 500; final int preferredHeight = 400; JNLPSplashScreen splashScreen = null;
--- a/rt/net/sourceforge/jnlp/Parser.java Wed Jun 10 10:53:03 2009 -0400 +++ b/rt/net/sourceforge/jnlp/Parser.java Wed Jun 10 12:00:53 2009 -0400 @@ -281,6 +281,11 @@ Version version = getVersion(node, "version", null); URL location = getURL(node, "href", base); String vmArgs = getAttribute(node, "java-vm-args",null); + try { + checkVMArgs(vmArgs); + } catch (IllegalArgumentException argumentException) { + vmArgs = null; + } String initialHeap = getAttribute(node, "initial-heap-size", null); String maxHeap = getAttribute(node, "max-heap-size", null); List resources = getResources(node, true); @@ -291,6 +296,8 @@ return new JREDesc(version, location, vmArgs, initialHeap, maxHeap, resources); } + + /** * Returns the JAR element at the specified node. * @@ -993,6 +1000,111 @@ else return new Version(version); } + + /** + * Check that the VM args are valid and safe + * @param vmArgs a string containing the args + * @throws ParseException if the VM arguments are invalid or dangerous + */ + private void checkVMArgs(String vmArgs) throws IllegalArgumentException { + if (vmArgs == null) { + return; + } + + List<String> validArguments = Arrays.asList(getValidVMArguments()); + List<String> validStartingArguments = Arrays.asList(getValidStartingVMArguments()); + + String[] arguments = vmArgs.split(" "); + boolean argumentIsValid = false; + for (String argument: arguments) { + argumentIsValid = false; + + if (validArguments.contains(argument)) { + argumentIsValid = true; + } else { + for (String validStartingArgument: validStartingArguments) { + if (argument.startsWith(validStartingArgument)) { + argumentIsValid = true; + break; + } + } + } + + if (!argumentIsValid) { + throw new IllegalArgumentException(argument); + } + } + + } + + /** + * Returns an array of valid (ie safe and supported) arguments for the JVM + * + * Based on http://java.sun.com/javase/6/docs/technotes/guides/javaws/developersguide/syntax.html + */ + private String[] getValidVMArguments() { + return new String[] { + "-d32", /* use a 32-bit data model if available */ + "-client", /* to select the client VM */ + "-server", /* to select the server VM */ + "-verbose", /* enable verbose output */ + "-version", /* print product version and exit */ + "-showversion", /* print product version and continue */ + "-help", /* print this help message */ + "-X", /* print help on non-standard options */ + "-ea", /* enable assertions */ + "-enableassertions", /* enable assertions */ + "-da", /* disable assertions */ + "-disableassertions", /* disable assertions */ + "-esa", /* enable system assertions */ + "-enablesystemassertions", /* enable system assertions */ + "-dsa", /* disable system assertione */ + "-disablesystemassertions", /* disable system assertione */ + "-Xmixed", /* mixed mode execution (default) */ + "-Xint", /* interpreted mode execution only */ + "-Xnoclassgc", /* disable class garbage collection */ + "-Xincgc", /* enable incremental garbage collection */ + "-Xbatch", /* disable background compilation */ + "-Xprof", /* output cpu profiling data */ + "-Xdebug", /* enable remote debugging */ + "-Xfuture", /* enable strictest checks, anticipating future default */ + "-Xrs", /* reduce use of OS signals by Java/VM (see documentation) */ + "-XX:+ForceTimeHighResolution", /* use high resolution timer */ + "-XX:-ForceTimeHighResolution", /* use low resolution (default) */ + }; + } + + /** + * Returns an array containing the starts of valid (ie safe and supported) + * arguments for the JVM + * + * Based on http://java.sun.com/javase/6/docs/technotes/guides/javaws/developersguide/syntax.html + */ + private String[] getValidStartingVMArguments() { + return new String[] { + "-ea", /* enable assertions for classes */ + "-enableassertions", /* enable assertions for classes */ + "-da", /* disable assertions for classes */ + "-disableassertions", /* disable assertions for classes */ + "-verbose", /* enable verbose output */ + "-Xms", /* set initial Java heap size */ + "-Xmx", /* set maximum Java heap size */ + "-Xss", /* set java thread stack size */ + "-XX:NewRatio", /* set Ratio of new/old gen sizes */ + "-XX:NewSize", /* set initial size of new generation */ + "-XX:MaxNewSize", /* set max size of new generation */ + "-XX:PermSize", /* set initial size of permanent gen */ + "-XX:MaxPermSize", /* set max size of permanent gen */ + "-XX:MaxHeapFreeRatio", /* heap free percentage (default 70) */ + "-XX:MinHeapFreeRatio", /* heap free percentage (default 40) */ + "-XX:UseSerialGC", /* use serial garbage collection */ + "-XX:ThreadStackSize", /* thread stack size (in KB) */ + "-XX:MaxInlineSize", /* set max num of bytecodes to inline */ + "-XX:ReservedCodeCacheSize", /* Reserved code cache size (bytes) */ + "-XX:MaxDirectMemorySize", + + }; + } /** * Returns the same result as getAttribute except that if strict
--- a/rt/net/sourceforge/jnlp/resources/Messages.properties Wed Jun 10 10:53:03 2009 -0400 +++ b/rt/net/sourceforge/jnlp/resources/Messages.properties Wed Jun 10 12:00:53 2009 -0400 @@ -130,6 +130,7 @@ BOStrict = Enables strict checking of JNLP file format. BOViewer = Shows the trusted certificate viewer. BOUmask = Sets the umask for files created by an application. +BXnofork = Do not create another JVM. BOHelp = Print this message and exit. # Cache
--- a/rt/net/sourceforge/jnlp/runtime/Boot.java Wed Jun 10 10:53:03 2009 -0400 +++ b/rt/net/sourceforge/jnlp/runtime/Boot.java Wed Jun 10 12:00:53 2009 -0400 @@ -24,6 +24,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import javax.net.ssl.HttpsURLConnection; @@ -116,6 +117,7 @@ + " -headless "+R("BOHeadless")+"\n" + " -strict "+R("BOStrict")+"\n" + " -umask=value "+R("BOUmask")+"\n" + + " -Xnofork "+R("BXnofork")+"\n" + " -help "+R("BOHelp")+"\n"; private static final String doubleArgs = "-basedir -jnlp -arg -param -property -update"; @@ -169,6 +171,10 @@ if (null != getOption("-noupdate")) JNLPRuntime.setDefaultUpdatePolicy(UpdatePolicy.NEVER); + if (null != getOption("-Xnofork")) { + JNLPRuntime.setForksAllowed(false); + } + // wire in custom authenticator try { SSLSocketFactory sslSocketFactory; @@ -183,12 +189,13 @@ e.printStackTrace(); } + JNLPRuntime.setInitialArgments(Arrays.asList(argsIn)); + // do in a privileged action to clear the security context of // the Boot13 class, which doesn't have any privileges in // JRE1.3; JRE1.4 works without Boot13 or this PrivilegedAction. AccessController.doPrivileged(new Boot()); - args = null; // might save a couple bytes... } /**
--- a/rt/net/sourceforge/jnlp/runtime/JNLPRuntime.java Wed Jun 10 10:53:03 2009 -0400 +++ b/rt/net/sourceforge/jnlp/runtime/JNLPRuntime.java Wed Jun 10 12:00:53 2009 -0400 @@ -21,6 +21,7 @@ import java.awt.*; import java.text.*; import java.util.*; +import java.util.List; import java.security.*; import javax.jnlp.*; @@ -96,7 +97,14 @@ /** set to true if this is a webstart application. */ private static boolean isWebstartApplication; + + /** set to false to indicate another JVM should not be spawned, even if necessary */ + private static boolean forksAllowed = true; + /** contains the arguments passed to the jnlp runtime */ + private static List<String> initialArguments; + + /** * Returns whether the JNLP runtime environment has been * initialized. Once initialized, some properties such as the @@ -429,6 +437,18 @@ } /** + * Returns true if the current runtime will fork + */ + public static boolean getForksAllowed() { + return forksAllowed; + } + + public static void setForksAllowed(boolean value) { + checkInitialized(); + forksAllowed = value; + } + + /** * Throws an exception if called when the runtime is * already initialized. */ @@ -491,6 +511,19 @@ } } + + public static void setInitialArgments(List<String> args) { + checkInitialized(); + SecurityManager securityManager = System.getSecurityManager(); + if (securityManager != null) + securityManager.checkPermission(new AllPermission()); + initialArguments = args; + } + + public static List<String> getInitialArguments() { + return initialArguments; + } + }