From 02724fc1db27fc0980f9e0229d470b4a577bc990 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 10 Apr 2014 19:07:06 +0200 Subject: [PATCH] try to start javafx without main (IDEA-101939) --- .../rt/execution/application/AppMain.java | 29 +++++++++++++++- .../src/META-INF/common-javaFX-plugin.xml | 1 + .../JavaFXApplicationMainMethodProvider.java | 34 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFXApplicationMainMethodProvider.java diff --git a/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java b/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java index 1319956e38cc..3673a930d742 100644 --- a/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java +++ b/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java @@ -33,6 +33,9 @@ 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 { @@ -110,7 +113,18 @@ public class AppMain { for (int j = 1; j < args.length; j++) { parms[j - 1] = args[j]; } - Method m = Class.forName(mainClass).getMethod("main", new Class[]{parms.getClass()}); + 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; @@ -123,6 +137,19 @@ public class AppMain { } } + 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 diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml index cdc1397b5aac..c03a5f4bff9c 100644 --- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml +++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml @@ -52,6 +52,7 @@ + diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFXApplicationMainMethodProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFXApplicationMainMethodProvider.java new file mode 100644 index 000000000000..aa767cc12921 --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/JavaFXApplicationMainMethodProvider.java @@ -0,0 +1,34 @@ +package org.jetbrains.plugins.javaFX; + +import com.intellij.codeInsight.runner.JavaMainMethodProvider; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiMethodUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames; + +public class JavaFXApplicationMainMethodProvider implements JavaMainMethodProvider { + @NonNls public static final String LAUNCH_MAIN = "launch"; + + @Override + public boolean isApplicable(PsiClass clazz) { + return InheritanceUtil.isInheritor(clazz, true, JavaFxCommonClassNames.JAVAFX_APPLICATION_APPLICATION); + } + + @Override + public boolean hasMainMethod(PsiClass clazz) { + return InheritanceUtil.isInheritor(clazz, true, JavaFxCommonClassNames.JAVAFX_APPLICATION_APPLICATION); + } + + @Override + public PsiMethod findMainInClass(PsiClass clazz) { + final PsiMethod[] launches = clazz.findMethodsByName(LAUNCH_MAIN, true); + for (PsiMethod launchMethod : launches) { + if (PsiMethodUtil.isMainMethod(launchMethod)) { + return launchMethod; + } + } + return null; + } +}