mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
use classpath jar instead of custom class loaders for CommandLineWrapper (IDEA-133617; IDEA-130440)
This commit is contained in:
@@ -15,15 +15,15 @@
|
||||
*/
|
||||
package com.intellij.rt.execution;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
/**
|
||||
* @author anna
|
||||
@@ -31,98 +31,36 @@ import java.util.List;
|
||||
*/
|
||||
public class CommandLineWrapper {
|
||||
|
||||
/**
|
||||
* The VM property is needed to workaround incorrect escaped URLs handling in WebSphere,
|
||||
* see <a href="https://youtrack.jetbrains.com/issue/IDEA-126859#comment=27-778948">IDEA-126859</a> for additional details
|
||||
*/
|
||||
public static final String PROPERTY_DO_NOT_ESCAPE_CLASSPATH_URL = "idea.do.not.escape.classpath.url";
|
||||
|
||||
private static final String PREFIX = "-D";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final boolean notEscapeClasspathUrl = Boolean.valueOf(System.getProperty(PROPERTY_DO_NOT_ESCAPE_CLASSPATH_URL)).booleanValue();
|
||||
final List urls = new ArrayList();
|
||||
final File file = new File(args[0]);
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
final BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
final File jarFile = new File(args[0]);
|
||||
JarInputStream inputStream = null;
|
||||
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(notEscapeClasspathUrl ? classpathElement.toURL() : classpathElement.toURI().toURL());
|
||||
}
|
||||
catch (NoSuchMethodError e) {
|
||||
//noinspection deprecation
|
||||
urls.add(classpathElement.toURL());
|
||||
inputStream = new JarInputStream(new FileInputStream(jarFile));
|
||||
final Manifest manifest = inputStream.getManifest();
|
||||
final String vmParams = manifest.getMainAttributes().getValue("VM-Options");
|
||||
if (vmParams != null) {
|
||||
final HashMap vmOptions = new HashMap();
|
||||
parseVmOptions(vmParams, vmOptions);
|
||||
for (Iterator iterator = vmOptions.keySet().iterator(); iterator.hasNext(); ) {
|
||||
String optionName = (String)iterator.next();
|
||||
System.setProperty(optionName, (String)vmOptions.get(optionName));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException ignore) {}
|
||||
finally {
|
||||
reader.close();
|
||||
}
|
||||
if (!file.delete()) file.deleteOnExit();
|
||||
System.setProperty("java.class.path", buf.toString());
|
||||
|
||||
int startArgsIdx = 2;
|
||||
if (args[1].equals("@vm_params")) {
|
||||
startArgsIdx = 4;
|
||||
final File vmParamsFile = new File(args[2]);
|
||||
final BufferedReader vmParamsReader = new BufferedReader(new FileReader(vmParamsFile));
|
||||
try {
|
||||
while (vmParamsReader.ready()) {
|
||||
final String vmParam = vmParamsReader.readLine().trim();
|
||||
final int eqIdx = vmParam.indexOf('=');
|
||||
String vmParamName;
|
||||
String vmParamValue;
|
||||
|
||||
if (eqIdx > -1 && eqIdx < vmParam.length() - 1) {
|
||||
vmParamName = vmParam.substring(0, eqIdx);
|
||||
vmParamValue = vmParam.substring(eqIdx + 1);
|
||||
} else {
|
||||
vmParamName = vmParam;
|
||||
vmParamValue = "";
|
||||
}
|
||||
vmParamName = vmParamName.trim();
|
||||
if (vmParamName.startsWith(PREFIX)) {
|
||||
vmParamName = vmParamName.substring(PREFIX.length());
|
||||
System.setProperty(vmParamName, vmParamValue);
|
||||
}
|
||||
}
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
finally {
|
||||
vmParamsReader.close();
|
||||
}
|
||||
if (!vmParamsFile.delete()) vmParamsFile.deleteOnExit();
|
||||
jarFile.deleteOnExit();
|
||||
}
|
||||
|
||||
String mainClassName = args[startArgsIdx - 1];
|
||||
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) {
|
||||
try {
|
||||
loader = (ClassLoader)Class.forName(classLoader).getConstructor(new Class[]{ClassLoader.class}).newInstance(new Object[]{loader});
|
||||
}
|
||||
catch (Exception e) {
|
||||
//leave URL class loader
|
||||
}
|
||||
}
|
||||
|
||||
Class mainClass = loader.loadClass(mainClassName);
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
|
||||
String mainClassName = args[1];
|
||||
String[] mainArgs = new String[args.length - 2];
|
||||
System.arraycopy(args, 2, mainArgs, 0, mainArgs.length);
|
||||
Class mainClass = Class.forName(mainClassName);
|
||||
//noinspection SSBasedInspection
|
||||
Class mainArgType = (new String[0]).getClass();
|
||||
Method main = mainClass.getMethod("main", new Class[]{mainArgType});
|
||||
@@ -130,15 +68,24 @@ public class CommandLineWrapper {
|
||||
main.invoke(null, new Object[]{mainArgs});
|
||||
}
|
||||
|
||||
private static URL internFileProtocol(URL url) {
|
||||
try {
|
||||
if ("file".equals(url.getProtocol())) {
|
||||
return new URL("file", url.getHost(), url.getPort(), url.getFile());
|
||||
public static void parseVmOptions(String vmParams, Map vmOptions) {
|
||||
int idx = vmParams.indexOf(PREFIX);
|
||||
while (idx >= 0) {
|
||||
final int indexOf = vmParams.indexOf(PREFIX, idx + PREFIX.length());
|
||||
final String vmParam = indexOf < 0 ? vmParams.substring(idx) : vmParams.substring(idx, indexOf - 1);
|
||||
final int eqIdx = vmParam.indexOf('=');
|
||||
String vmParamName;
|
||||
String vmParamValue;
|
||||
if (eqIdx > -1 && eqIdx < vmParam.length() - 1) {
|
||||
vmParamName = vmParam.substring(0, eqIdx);
|
||||
vmParamValue = vmParam.substring(eqIdx + 1);
|
||||
} else {
|
||||
vmParamName = vmParam;
|
||||
vmParamValue = "";
|
||||
}
|
||||
vmOptions.put(vmParamName.trim().substring(PREFIX.length()), vmParamValue);
|
||||
idx = indexOf;
|
||||
}
|
||||
catch (MalformedURLException ignored) {
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
private static void ensureAccess(Object reflectionObject) {
|
||||
|
||||
+43
-20
@@ -20,6 +20,10 @@ import com.intellij.rt.execution.CommandLineWrapper;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public abstract class ForkedByModuleSplitter {
|
||||
protected final ForkedDebuggerHelper myForkedDebuggerHelper = new ForkedDebuggerHelper();
|
||||
@@ -79,26 +83,8 @@ public abstract class ForkedByModuleSplitter {
|
||||
builder.add("-classpath");
|
||||
if (myDynamicClasspath.length() > 0) {
|
||||
try {
|
||||
final File classpathFile = File.createTempFile("classpath", null);
|
||||
classpathFile.deleteOnExit();
|
||||
final PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(classpathFile), "UTF-8"));
|
||||
try {
|
||||
int idx = 0;
|
||||
while (idx < classpath.length()) {
|
||||
final int endIdx = classpath.indexOf(File.pathSeparator, idx);
|
||||
if (endIdx < 0) {
|
||||
writer.println(classpath.substring(idx));
|
||||
break;
|
||||
}
|
||||
writer.println(classpath.substring(idx, endIdx));
|
||||
idx = endIdx + File.pathSeparator.length();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
|
||||
builder.add(myDynamicClasspath);
|
||||
final File classpathFile = createClasspathJarFile(new Manifest(), classpath);
|
||||
builder.add(myDynamicClasspath + File.pathSeparator + classpathFile.getAbsolutePath());
|
||||
builder.add(CommandLineWrapper.class.getName());
|
||||
builder.add(classpathFile.getAbsolutePath());
|
||||
}
|
||||
@@ -172,4 +158,41 @@ public abstract class ForkedByModuleSplitter {
|
||||
|
||||
protected void sendTime(long time) {}
|
||||
protected void sendTree(Object rootDescription) {}
|
||||
|
||||
public static File createClasspathJarFile(Manifest manifest, String classpath) throws IOException {
|
||||
final Attributes attributes = manifest.getMainAttributes();
|
||||
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
|
||||
String classpathForManifest = "";
|
||||
int idx = 0;
|
||||
int endIdx = 0;
|
||||
while (endIdx >= 0) {
|
||||
endIdx = classpath.indexOf(File.pathSeparator, idx);
|
||||
String path = endIdx < 0 ? classpath.substring(idx) : classpath.substring(idx, endIdx);
|
||||
if (classpathForManifest.length() > 0) {
|
||||
classpathForManifest += " ";
|
||||
}
|
||||
try {
|
||||
//noinspection Since15
|
||||
classpathForManifest += new File(path).toURI().toURL().toString();
|
||||
}
|
||||
catch (NoSuchMethodError e) {
|
||||
classpathForManifest += new File(path).toURL().toString();
|
||||
}
|
||||
idx = endIdx + File.pathSeparator.length();
|
||||
}
|
||||
attributes.put(Attributes.Name.CLASS_PATH, classpathForManifest);
|
||||
|
||||
File jarFile = File.createTempFile("classpath", ".jar");
|
||||
ZipOutputStream jarPlugin = null;
|
||||
try {
|
||||
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(jarFile));
|
||||
jarPlugin = new JarOutputStream(out, manifest);
|
||||
}
|
||||
finally {
|
||||
if (jarPlugin != null) jarPlugin.close();
|
||||
}
|
||||
jarFile.deleteOnExit();
|
||||
return jarFile;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user