diff --git a/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java b/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java index f6901fc5af67..0b2702f7b899 100644 --- a/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java +++ b/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java @@ -30,60 +30,84 @@ import java.util.jar.Manifest; /** * @author anna * @since 12-Aug-2008 + * @noinspection SSBasedInspection */ public class CommandLineWrapper { - public static void main(String[] args) throws Exception { - final File jarFile = new File(args[0]); - final MainPair mainPair = args[0].endsWith(".jar") ? loadMainClassFromClasspathJar(jarFile, args) - : loadMainClassWithOldCustomLoader(jarFile, args); - String[] mainArgs = mainPair.getArgs(); - Class mainClass = mainPair.getMainClass(); - //noinspection SSBasedInspection - Class mainArgType = (new String[0]).getClass(); - Method main = mainClass.getMethod("main", new Class[]{mainArgType}); - ensureAccess(main); - main.invoke(null, new Object[]{mainArgs}); + private static class AppData { + private final List properties; + private final Class mainClass; + private final String[] args; + + private AppData(List properties, Class mainClass, String[] args) { + this.properties = properties; + this.mainClass = mainClass; + this.args = args; + } } - private static MainPair loadMainClassFromClasspathJar(File jarFile, String[] args) throws Exception { - String[] mainArgs; - final JarInputStream inputStream = new JarInputStream(new FileInputStream(jarFile)); - try { - final Manifest manifest = inputStream.getManifest(); - final String vmParams = manifest.getMainAttributes().getValue("VM-Options"); - if (vmParams != null) { - String[] properties = splitBySpaces(vmParams); - for (int i = 0; i < properties.length; i++) { - setProperty(properties[i]); + public static void main(String[] args) throws Exception { + File file = new File(args[0]); + AppData appData = args[0].endsWith(".jar") ? loadMainClassFromClasspathJar(file, args) : loadMainClassWithCustomLoader(file, args); + + List properties = appData.properties; + for (int i = 0; i < properties.size(); i++) { + String property = (String)properties.get(i); + if (property.startsWith("-D")) { + int p = property.indexOf('='); + if (p > 0) { + System.setProperty(property.substring(2, p), property.substring(p + 1)); + } + else { + System.setProperty(property.substring(2), ""); } } - String programParameters = manifest.getMainAttributes().getValue("Program-Parameters"); + } + + Method main = appData.mainClass.getMethod("main", new Class[]{String[].class}); + main.setAccessible(true); // need to launch package-private classes + main.invoke(null, new Object[]{appData.args}); + } + + private static AppData loadMainClassFromClasspathJar(File jarFile, String[] args) throws Exception { + List properties = Collections.EMPTY_LIST; + String[] mainArgs; + + JarInputStream inputStream = new JarInputStream(new FileInputStream(jarFile)); + try { + Manifest manifest = inputStream.getManifest(); + + String vmOptions = manifest != null ? manifest.getMainAttributes().getValue("VM-Options") : null; + if (vmOptions != null) { + properties = splitBySpaces(vmOptions); + } + + String programParameters = manifest != null ? manifest.getMainAttributes().getValue("Program-Parameters") : null; if (programParameters == null) { mainArgs = new String[args.length - 2]; System.arraycopy(args, 2, mainArgs, 0, mainArgs.length); } else { - mainArgs = splitBySpaces(programParameters); + List list = splitBySpaces(programParameters); + mainArgs = (String[])list.toArray(new String[list.size()]); } } finally { inputStream.close(); - //noinspection SSBasedInspection jarFile.deleteOnExit(); } - return new MainPair(Class.forName(args[1]), mainArgs); + return new AppData(properties, Class.forName(args[1]), mainArgs); } /** * The implementation is copied from copied from com.intellij.util.execution.ParametersListUtil.parse and adapted to old Java versions * @noinspection Duplicates */ - private static String[] splitBySpaces(String parameterString) { + private static List splitBySpaces(String parameterString) { parameterString = parameterString.trim(); - final ArrayList params = new ArrayList(); - final StringBuffer token = new StringBuffer(128); + List params = new ArrayList(); + StringBuffer token = new StringBuffer(128); boolean inQuotes = false; boolean escapedQuote = false; boolean nonEmpty = false; @@ -123,88 +147,49 @@ public class CommandLineWrapper { params.add(token.toString()); } - //noinspection SSBasedInspection - return (String[])params.toArray(new String[params.size()]); - } - - private static class MainPair { - private Class mainClass; - private String[] args; - - public MainPair(Class mainClass, String[] args) { - this.mainClass = mainClass; - this.args = args; - } - - public Class getMainClass() { - return mainClass; - } - - public String[] getArgs() { - return args; - } - } - - private static void ensureAccess(Object reflectionObject) { - // need to call setAccessible here in order to be able to launch package-private classes - // calling setAccessible() via reflection because the method is missing from java version 1.1.x - final Class aClass = reflectionObject.getClass(); - try { - final Method setAccessibleMethod = aClass.getMethod("setAccessible", new Class[]{boolean.class}); - setAccessibleMethod.invoke(reflectionObject, new Object[]{Boolean.TRUE}); - } - catch (Exception ignored) { } + return params; } /** * args: "classpath file" [ @vm_params "VM options file" ] "main class" [ args ... ] - * @noinspection Duplicates + * @noinspection Duplicates, ResultOfMethodCallIgnored */ - private static MainPair loadMainClassWithOldCustomLoader(File file, String[] args) throws Exception { - final List urls = new ArrayList(); - final StringBuffer buf = new StringBuffer(); - final BufferedReader reader = new BufferedReader(new FileReader(file)); + private static AppData loadMainClassWithCustomLoader(File classpathFile, String[] args) throws Exception { + List classpathUrls = new ArrayList(); + StringBuffer classpathString = new StringBuffer(); + BufferedReader classpathReader = new BufferedReader(new FileReader(classpathFile)); try { - while (reader.ready()) { - final String fileName = reader.readLine(); - if (buf.length() > 0) { - buf.append(File.pathSeparator); - } - buf.append(fileName); - File classpathElement = new File(fileName); - try { - //noinspection Since15, deprecation - urls.add(classpathElement.toURI().toURL()); - } - catch (NoSuchMethodError e) { - //noinspection deprecation - urls.add(classpathElement.toURL()); - } + String pathElement; + while ((pathElement = classpathReader.readLine()) != null) { + if (classpathString.length() > 0) classpathString.append(File.pathSeparator); + classpathString.append(pathElement); + classpathUrls.add(toUrl(new File(pathElement))); } } finally { - reader.close(); + classpathReader.close(); + classpathFile.delete(); } - if (!file.delete()) { - //noinspection SSBasedInspection - file.deleteOnExit(); - } - System.setProperty("java.class.path", buf.toString()); + System.setProperty("java.class.path", classpathString.toString()); int startArgsIdx = 2; + List properties = Collections.EMPTY_LIST; if (args.length >= 3 && "@vm_params".equals(args[1])) { startArgsIdx = 4; + File vmParamsFile = new File(args[2]); BufferedReader vmParamsReader = new BufferedReader(new FileReader(args[2])); try { + properties = new ArrayList(); String property; while ((property = vmParamsReader.readLine()) != null) { - setProperty(property); + properties.add(property); } } finally { vmParamsReader.close(); + vmParamsFile.delete(); } } @@ -212,46 +197,30 @@ public class CommandLineWrapper { String[] mainArgs = new String[args.length - startArgsIdx]; System.arraycopy(args, startArgsIdx, mainArgs, 0, mainArgs.length); - for (int i = 0; i < urls.size(); i++) { - URL url = (URL)urls.get(i); - urls.set(i, internFileProtocol(url)); - } - - ClassLoader loader = new URLClassLoader((URL[])urls.toArray(new URL[urls.size()]), null); - final String classLoader = System.getProperty("java.system.class.loader"); - if (classLoader != null) { + ClassLoader loader = new URLClassLoader((URL[])classpathUrls.toArray(new URL[classpathUrls.size()]), null); + String systemLoaderName = System.getProperty("java.system.class.loader"); + if (systemLoaderName != null) { try { - loader = (ClassLoader)Class.forName(classLoader).getConstructor(new Class[]{ClassLoader.class}).newInstance(new Object[]{loader}); - } - catch (Exception e) { - //leave URL class loader + loader = (ClassLoader)Class.forName(systemLoaderName).getConstructor(new Class[]{ClassLoader.class}).newInstance(new Object[]{loader}); } + catch (Exception ignored) { } } Class mainClass = loader.loadClass(mainClassName); Thread.currentThread().setContextClassLoader(loader); - return new MainPair(mainClass, mainArgs); + return new AppData(properties, mainClass, mainArgs); } - private static void setProperty(String property) { - if (property.startsWith("-D")) { - int p = property.indexOf('='); - if (p > 0) { - System.setProperty(property.substring(2, p), property.substring(p + 1)); - } - else { - System.setProperty(property.substring(2), ""); - } - } - } - - private static URL internFileProtocol(URL url) { + /** @noinspection Since15, deprecation */ + private static URL toUrl(File classpathElement) throws MalformedURLException { + URL url; try { - if ("file".equals(url.getProtocol())) { - return new URL("file", url.getHost(), url.getPort(), url.getFile()); - } + url = classpathElement.toURI().toURL(); } - catch (MalformedURLException ignored) { } + catch (NoSuchMethodError e) { + url = classpathElement.toURL(); + } + url = new URL("file", url.getHost(), url.getPort(), url.getFile()); return url; } } \ No newline at end of file