diff options
author | Mike Rennie | 2012-07-17 19:53:04 +0000 |
---|---|---|
committer | Mike Rennie | 2013-03-19 19:42:59 +0000 |
commit | f0a9f2381f3f6035d31af09fcbe13927fc877cc2 (patch) | |
tree | 0bebf9bb30687dbcd2bc412ff988abba8b25cd4d | |
parent | 61b8e248c810b339961a99bb4ee1c04a0d8b1921 (diff) | |
download | eclipse.jdt.debug-f0a9f2381f3f6035d31af09fcbe13927fc877cc2.tar.gz eclipse.jdt.debug-f0a9f2381f3f6035d31af09fcbe13927fc877cc2.tar.xz eclipse.jdt.debug-f0a9f2381f3f6035d31af09fcbe13927fc877cc2.zip |
Bug 327193 - [patch] Launching command line exceeds the windows limit
3 files changed, 123 insertions, 12 deletions
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/Standard11xVMRunner.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/Standard11xVMRunner.java index ce13beb36..39bd4fd1c 100644 --- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/Standard11xVMRunner.java +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/Standard11xVMRunner.java @@ -40,11 +40,9 @@ public class Standard11xVMRunner extends StandardVMRunner { * @see org.eclipse.jdt.launching.IVMRunner#run(org.eclipse.jdt.launching.VMRunnerConfiguration, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) */ public void run(VMRunnerConfiguration config, ILaunch launch, IProgressMonitor monitor) throws CoreException { - if (monitor == null) { monitor = new NullProgressMonitor(); } - IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1); subMonitor.beginTask(LaunchingMessages.StandardVMRunner_Launching_VM____1, 2); subMonitor.subTask(LaunchingMessages.StandardVMRunner_Constructing_command_line____2); // @@ -81,14 +79,23 @@ public class Standard11xVMRunner extends StandardVMRunner { combinedPath[offset] = classPath[i]; offset++; } - + int cpidx = -1; if (combinedPath.length > 0) { + cpidx = arguments.size(); arguments.add("-classpath"); //$NON-NLS-1$ arguments.add(convertClassPath(combinedPath)); } arguments.add(config.getClassToLaunch()); String[] programArgs= config.getProgramArguments(); + + String[] envp = prependJREPath(config.getEnvironment()); + String[] newenvp = checkClasspath(arguments, classPath, envp); + if(newenvp != null) { + envp = newenvp; + arguments.remove(cpidx); + arguments.remove(cpidx); + } addArguments(programArgs, arguments); String[] cmdLine= new String[arguments.size()]; @@ -104,7 +111,7 @@ public class Standard11xVMRunner extends StandardVMRunner { Process p= null; File workingDir = getWorkingDir(config); - p= exec(cmdLine, workingDir); + p= exec(cmdLine, workingDir, envp); if (p == null) { return; } diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java index ec5d6ca09..e5adcb4ef 100644 --- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java @@ -204,23 +204,31 @@ public class StandardVMDebugger extends StandardVMRunner { addBootClassPathArguments(arguments, config); String[] cp= config.getClassPath(); + int cpidx = -1; if (cp.length > 0) { + cpidx = arguments.size(); arguments.add("-classpath"); //$NON-NLS-1$ arguments.add(convertClassPath(cp)); } - - arguments.add(config.getClassToLaunch()); addArguments(config.getProgramArguments(), arguments); - String[] cmdLine= new String[arguments.size()]; - arguments.toArray(cmdLine); //With the newer VMs and no backwards compatibility we have to always prepend the current env path (only the runtime one) //with a 'corrected' path that points to the location to load the debug dlls from, this location is of the standard JDK installation //format: <jdk path>/jre/bin String[] envp = prependJREPath(config.getEnvironment(), new Path(program)); + String[] newenvp = checkClasspath(arguments, cp, envp); + if(newenvp != null) { + envp = newenvp; + arguments.remove(cpidx); + arguments.remove(cpidx); + } + + String[] cmdLine= new String[arguments.size()]; + arguments.toArray(cmdLine); + // check for cancellation if (monitor.isCanceled()) { return; diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java index 1ede69a3b..5874fae84 100644 --- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java +++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java @@ -203,7 +203,6 @@ public class StandardVMRunner extends AbstractVMRunner { if (fileExists(exe)) { return exe.getAbsolutePath(); } - // not found abort(MessageFormat.format(LaunchingMessages.StandardVMRunner_Specified_executable__0__does_not_exist_for__1__4, new String[]{command, fVMInstance.getName()}), null, IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR); @@ -275,7 +274,7 @@ public class StandardVMRunner extends AbstractVMRunner { IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1); subMonitor.beginTask(LaunchingMessages.StandardVMRunner_Launching_VM____1, 2); - subMonitor.subTask(LaunchingMessages.StandardVMRunner_Constructing_command_line____2); + subMonitor.subTask(LaunchingMessages.StandardVMRunner_Constructing_command_line____2); String program= constructProgramString(config); @@ -290,7 +289,9 @@ public class StandardVMRunner extends AbstractVMRunner { addBootClassPathArguments(arguments, config); String[] cp= config.getClassPath(); + int cpidx = -1; if (cp.length > 0) { + cpidx = arguments.size(); arguments.add("-classpath"); //$NON-NLS-1$ arguments.add(convertClassPath(cp)); } @@ -299,11 +300,18 @@ public class StandardVMRunner extends AbstractVMRunner { String[] programArgs= config.getProgramArguments(); addArguments(programArgs, arguments); + String[] envp = prependJREPath(config.getEnvironment()); + + String[] newenvp = checkClasspath(arguments, cp, envp); + if(newenvp != null) { + envp = newenvp; + arguments.remove(cpidx); + arguments.remove(cpidx); + } + String[] cmdLine= new String[arguments.size()]; arguments.toArray(cmdLine); - String[] envp = prependJREPath(config.getEnvironment()); - subMonitor.worked(1); // check for cancellation @@ -332,6 +340,94 @@ public class StandardVMRunner extends AbstractVMRunner { } /** + * Returns the index in the given array for the CLASSPATH variable + * @param env the environment array or <code>null</code> + * @return -1 or the index of the CLASSPATH variable + * @since 3.6.200 + */ + int getCPIndex(String[] env) { + if(env != null) { + for (int i = 0; i < env.length; i++) { + if(env[i].regionMatches(true, 0, "CLASSPATH=", 0, 10)) { //$NON-NLS-1$ + return i; + } + } + } + return -1; + } + + /** + * Checks to see if the command / classpath needs to be shortened for Windows. Returns the modified + * environment or <code>null</code> if no changes are needed. + * + * @param args the raw arguments from the runner + * @param cp the raw classpath from the runner configuration + * @param env the current environment + * @return the modified environment or <code>null</code> if no changes were made + * @sine 3.6.200 + */ + String[] checkClasspath(List<String> args, String[] cp, String[] env) { + if(Platform.getOS().equals(Platform.OS_WIN32)) { + //count the complete command length + int size = 0; + for (String arg : args) { + if(arg != null) { + size += arg.length(); + } + } + //greater than 32767 is a no-go + //see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx + if(size > 32767) { + StringBuffer newcp = new StringBuffer(); + for (int i = 0; i < cp.length; i++) { + newcp.append(cp[i]); + newcp.append(File.pathSeparatorChar); + } + String[] newenvp = null; + int index = -1; + if(env == null) { + Map<String, String> nenv = DebugPlugin.getDefault().getLaunchManager().getNativeEnvironment(); + Entry<String, String> entry = null; + newenvp = new String[nenv.size()]; + int idx = 0; + for (Iterator<Entry<String, String>> i = nenv.entrySet().iterator(); i.hasNext();) { + entry = i.next(); + String value = entry.getValue(); + if(value == null) { + value = ""; //$NON-NLS-1$ + } + String key = entry.getKey(); + if(key.equalsIgnoreCase("CLASSPATH")) { //$NON-NLS-1$ + index = idx; + } + newenvp[idx] = key+'='+value+File.pathSeparatorChar; + idx++; + } + } + else { + newenvp = env; + index = getCPIndex(newenvp); + } + if(index < 0) { + newcp.insert(0, "CLASSPATH="); //$NON-NLS-1$ + String[] newenv = new String[newenvp.length+1]; + System.arraycopy(newenvp, 0, newenv, 0, newenvp.length); + newenv[newenvp.length] = newcp.toString(); + return newenv; + } + String oldcp = newenvp[index]; + if(!oldcp.endsWith(File.pathSeparator)) { + oldcp += File.pathSeparatorChar; + } + newcp.insert(0, oldcp); + newenvp[index] = newcp.toString(); + return newenvp; + } + } + return null; + } + + /** * Prepends the correct java version variable state to the environment path for Mac VMs * * @param env the current array of environment variables to run with |