try to start javafx without main (IDEA-101939)

This commit is contained in:
Anna Kozlova
2014-04-10 20:10:28 +02:00
parent b8249580db
commit 02724fc1db
3 changed files with 63 additions and 1 deletions
@@ -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
@@ -52,6 +52,7 @@
<completion.contributor implementationClass="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxCompletionContributor" language="XML" order="before xmlNonFirst"/>
<manifest.parser.provider implementation="org.jetbrains.plugins.javaFX.manifest.JavaFxManifestHeaderParsers"/>
<projectTemplate projectType="Java FX" templatePath="resources/projectTemplates/Java/JavaFX Application.zip" category="true"/>
<javaMainMethodProvider implementation="org.jetbrains.plugins.javaFX.JavaFXApplicationMainMethodProvider"/>
</extensions>
<actions>
@@ -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;
}
}