mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
Cleanup (CommandLineWrapper refactoring and minor optimization)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user