| /* |
| * 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 |
| } |
| } |
| } |