blob: 3673a930d742482e57f7221b955906debbc64286 [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.rt.execution.application;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author ven
* @noinspection HardCodedStringLiteral
*/
public class AppMain {
private static final String PROPERTY_PORT_NUMBER = "idea.launcher.port";
private static final String PROPERTY_BINPATH = "idea.launcher.bin.path";
private static final String JAVAFX_LAUNCHER = "com.sun.javafx.application.LauncherImpl";
private static final String LAUNCH_APPLICATION_METHOD_NAME = "launchApplication";
private static native void triggerControlBreak();
static {
String binPath = System.getProperty(PROPERTY_BINPATH) + File.separator;
final String osName = System.getProperty("os.name").toLowerCase();
String arch = System.getProperty("os.arch").toLowerCase();
String libPath = null;
if (osName.startsWith("windows")) {
if (arch.equals("amd64")) {
libPath = binPath + "breakgen64.dll";
}
else {
libPath = binPath + "breakgen.dll";
}
} else if (osName.startsWith("linux")) {
if (arch.equals("amd64")) {
libPath = binPath + "libbreakgen64.so";
} else {
libPath = binPath + "libbreakgen.so";
}
} else if (osName.startsWith("mac")) {
if (arch.endsWith("64")) {
libPath = binPath + "libbreakgen64.jnilib";
} else {
libPath = binPath + "libbreakgen.jnilib";
}
}
try {
if (libPath != null) {
System.load(libPath);
}
}
catch (UnsatisfiedLinkError e) {
//Do nothing, unknown os or some other error => no ctrl-break is available
}
}
public static void main(String[] args) throws Throwable {
final int portNumber = Integer.getInteger(PROPERTY_PORT_NUMBER).intValue();
Thread t = new Thread(
new Runnable() {
public void run() {
try {
ServerSocket socket = new ServerSocket(portNumber);
Socket client = socket.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
while (true) {
String msg = reader.readLine();
if ("TERM".equals(msg)){
return;
}
else if ("BREAK".equals(msg)) {
triggerControlBreak();
}
else if ("STOP".equals(msg)) {
System.exit(1);
}
}
} catch (IOException ignored) {
} catch (IllegalArgumentException ignored) {
} catch (SecurityException ignored) {
}
}
}, "Monitor Ctrl-Break");
try {
t.setDaemon(true);
t.start();
} catch (Exception ignored) {}
String mainClass = args[0];
String[] parms = new String[args.length - 1];
for (int j = 1; j < args.length; j++) {
parms[j - 1] = args[j];
}
final Class appClass = Class.forName(mainClass);
Method m;
try {
m = appClass.getMethod("main", new Class[]{parms.getClass()});
}
catch (NoSuchMethodException e) {
if (!startJavaFXApplication(parms, appClass)) {
throw e;
}
return;
}
if (!Modifier.isStatic(m.getModifiers())) {
System.err.println("main method should be static");
return;
}
try {
ensureAccess(m);
m.invoke(null, new Object[]{parms});
} catch (InvocationTargetException ite) {
throw ite.getTargetException();
}
}
private static boolean startJavaFXApplication(String[] parms, Class appClass) throws NoSuchMethodException {
try {
//check in launch method for application class in the stack trace leads to this hack here
final Method launchApplication = Class.forName(JAVAFX_LAUNCHER).getMethod(LAUNCH_APPLICATION_METHOD_NAME,
new Class[]{appClass.getClass(), parms.getClass()});
launchApplication.invoke(null, new Object[] {appClass, parms});
return true;
}
catch (Throwable e) {
return false;
}
}
private static void ensureAccess(Object reflectionObject) {
// need to call setAccessible here in order to be able to launch package-local 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 e) {
// the method not found
}
}
}