# HG changeset patch
# User kcr
# Date 1448062917 28800
# Node ID 0c051b5cfd8c0b845ced568f30016983983aaf47
# Parent 4c14b9f7e3509a2438a5c21cae6a3c3b79ecf02f
imported patch 8090585-platform-startup
diff --git a/modules/graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java b/modules/graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java
--- a/modules/graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java
+++ b/modules/graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java
@@ -133,10 +133,25 @@
/**
* This method is invoked typically on the main thread. At this point,
* the JavaFX Application Thread has not been started. Any attempt
- * to call startup twice results in an exception.
+ * to call startup more than once results in all subsequent calls turning into
+ * nothing more than a runLater call with the provided Runnable being called.
* @param r
*/
public static void startup(final Runnable r) {
+ startup(r, false);
+ }
+
+ /**
+ * This method is invoked typically on the main thread. At this point,
+ * the JavaFX Application Thread has not been started. If preventDuplicateCalls
+ * is true, calling this method multiple times will result in an
+ * IllegalStateException. If it is false, calling this method multiple times
+ * will result in all subsequent calls turning into
+ * nothing more than a runLater call with the provided Runnable being called.
+ * @param r
+ * @param preventDuplicateCalls
+ */
+ public static void startup(final Runnable r, boolean preventDuplicateCalls) {
// NOTE: if we ever support re-launching an application and/or
// launching a second application in the same VM/classloader
@@ -146,10 +161,15 @@
}
if (initialized.getAndSet(true)) {
+ if (preventDuplicateCalls) {
+ throw new IllegalStateException("Toolkit already initialized");
+ }
+
// If we've already initialized, just put the runnable on the queue.
runLater(r);
return;
}
+
AccessController.doPrivileged((PrivilegedAction) () -> {
contextual2DNavigation = Boolean.getBoolean(
"com.sun.javafx.isContextual2DNavigation");
diff --git a/modules/graphics/src/main/java/javafx/application/Platform.java b/modules/graphics/src/main/java/javafx/application/Platform.java
--- a/modules/graphics/src/main/java/javafx/application/Platform.java
+++ b/modules/graphics/src/main/java/javafx/application/Platform.java
@@ -41,6 +41,64 @@
}
/**
+ * This method starts the JavaFX runtime. The specified Runnable will then be
+ * called on the JavaFX Application Thread. In general it is not necessary to
+ * explicitly call this method, since it is invoked as a consequence of
+ * how most JavaFX applications are built. However there are valid use cases
+ * for calling this method directly. Because this method starts the JavaFX
+ * runtime, there is not yet any JavaFX Application Thread, so it is normal
+ * that this method is called directly on the main thread of the application.
+ *
+ *
+ * This method may or may not return to the caller before the run method
+ * of the specified Runnable has been called. In any case, once this method
+ * returns, you may call {@link #runLater} with additional Runnables.
+ * Those Runnables will be called, also on the JavaFX Application Thread,
+ * after the Runnable passed into this method has been called.
+ *
+ *
+ * As noted, it is normally the case that the JavaFX Application Thread
+ * is started automatically. It is important that this method only be called
+ * when the JavaFX runtime has not yet been initialized. Situations where
+ * the JavaFX runtime is started automatically include:
+ *
+ *
+ *
+ * - For standard JavaFX applications that extend {@link Application}, and
+ * use either the Java launcher or one of the launch methods in the
+ * Application class to launch the application, the FX runtime is
+ * initialized automatically by the launcher before the Application
+ * class is loaded.
+ * - For Swing applications that use JFXPanel to display FX content, the
+ * FX runtime is initialized when the first JFXPanel instance is
+ * constructed.
+ * - For SWT application that use FXCanvas to display FX content, the FX
+ * runtime is initialized when the first FXCanvas instance is
+ * constructed.
+ *
+ *
+ * When an application does not follow any of these common approaches,
+ * then it becomes the responsibility of the developer to manually start the
+ * JavaFX runtime by calling this startup method.
+ *
+ *
+ * Calling this method when the JavaFX runtime is already running will result in an
+ * {@link IllegalStateException} being thrown - it is only valid to request
+ * that the JavaFX runtime be started once.
+ *
+ *
+ * @throws IllegalStateException if the JavaFX runtime is already running
+ *
+ * @param runnable the Runnable whose run method will be executed on the
+ * JavaFX Application Thread once it has been started.
+ *
+ * @since 9
+ */
+ public static void startup(Runnable runnable) {
+ PlatformImpl.startup(runnable, true);
+ }
+
+ /**
* Run the specified Runnable on the JavaFX Application Thread at some
* unspecified
* time in the future. This method, which may be called from any thread,
@@ -73,6 +131,9 @@
* runtime is initialized when the first JFXPanel instance is constructed.
* For SWT application that use FXCanvas to display FX content, the FX
* runtime is initialized when the first FXCanvas instance is constructed.
+ * For applications that do not follow any of these approaches, then it is
+ * necessary to manually start the JavaFX runtime by calling
+ * {@link #startup(Runnable)} once.
*
*
* @param runnable the Runnable whose run method will be executed on the
diff --git a/tests/system/src/test/java/com/sun/javafx/application/PlatformStartupCommon.java b/tests/system/src/test/java/com/sun/javafx/application/PlatformStartupCommon.java
new file mode 100644
--- /dev/null
+++ b/tests/system/src/test/java/com/sun/javafx/application/PlatformStartupCommon.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.application;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javafx.application.Platform;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+import junit.framework.AssertionFailedError;
+import util.Util;
+
+import static org.junit.Assert.*;
+import static util.Util.TIMEOUT;
+
+/**
+ * Test program for Platform startup.
+ * Each of the tests must be run in a separate JVM which is why each
+ * is in its own subclass.
+ */
+public class PlatformStartupCommon {
+
+ // Sleep time showing/hiding window in milliseconds
+ private static final int SLEEP_TIME = 1000;
+
+ // Used to start the toolkit before running any test
+ private final CountDownLatch startupLatch = new CountDownLatch(1);
+
+ private Stage mainStage;
+
+ private void createMainStage() {
+ mainStage = new Stage();
+ mainStage.setTitle("Primary stage");
+ Group root = new Group();
+ Scene scene = new Scene(root);
+ scene.setFill(Color.LIGHTYELLOW);
+ mainStage.setScene(scene);
+ mainStage.setX(0);
+ mainStage.setY(0);
+ mainStage.setWidth(210);
+ mainStage.setHeight(180);
+ }
+
+ private void doTestCommon(final boolean implicitExit) {
+ final Throwable[] testError = new Throwable[1];
+ final Thread testThread = Thread.currentThread();
+
+ // Start the Toolkit
+ assertFalse(Platform.isFxApplicationThread());
+ assertEquals(1, startupLatch.getCount());
+ Platform.setImplicitExit(implicitExit);
+ Platform.startup(() -> {
+ try {
+ assertTrue(Platform.isFxApplicationThread());
+ startupLatch.countDown();
+ assertEquals(0, startupLatch.getCount());
+ } catch (Throwable th) {
+ testError[0] = th;
+ testThread.interrupt();
+ }
+ });
+ assertFalse(Platform.isFxApplicationThread());
+
+ try {
+ if (!startupLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ throw new AssertionFailedError("Timeout waiting for Toolkit to start");
+ }
+
+ final CountDownLatch rDone = new CountDownLatch(1);
+ // Test that we can do a runLater that throws exception
+ Platform.runLater(() -> {
+ try {
+ throw new RuntimeException("this exception is expected");
+ } finally {
+ rDone.countDown();
+ }
+ });
+ if (!rDone.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ throw new AssertionFailedError("Timeout waiting for runLater with Exception");
+ }
+
+ // Create and show main stage
+ Util.runAndWait(() -> {
+ createMainStage();
+ mainStage.show();
+ });
+
+ // Hide the primary stage after a short delay
+ Thread.sleep(SLEEP_TIME);
+ Util.runAndWait(mainStage::hide);
+
+ // Test exit behavior after another short delay
+ Thread.sleep(SLEEP_TIME);
+
+ final CountDownLatch exitLatch = PlatformImpl.test_getPlatformExitLatch();
+
+ if (implicitExit) {
+ // Verify that that the runtime has exited
+ assertEquals(0, exitLatch.getCount());
+
+ // Verify that that a runLater is a no-op
+ final AtomicBoolean isAlive = new AtomicBoolean(false);
+ Platform.runLater(() -> isAlive.set(true));
+ Thread.sleep(SLEEP_TIME);
+ assertFalse(isAlive.get());
+ } else {
+ // Verify that the FX runtime has not exited
+ assertEquals(1, exitLatch.getCount());
+
+ // Make sure Toolkit is still alive and running
+ AtomicBoolean isAlive = new AtomicBoolean(false);
+ Util.runAndWait(() -> isAlive.set(true));
+ assertTrue(isAlive.get());
+
+ // Shutdown the FX runtime and wait for toolkit to exit
+ Platform.exit();
+
+ if (!exitLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ throw new AssertionFailedError("Timeout waiting for Platform to exit");
+ }
+ }
+ } catch (InterruptedException ex) {
+ if (testError[0] != null) {
+ Util.throwError(testError[0]);
+ } else {
+ fail("Unexpected exception: " + ex);
+ }
+ }
+ }
+
+ // ========================== TEST CASES ==========================
+
+ protected void doTestStartupExplicitExit() {
+ doTestCommon(false);
+ }
+
+ protected void doTestStartupImplicitExit() {
+ doTestCommon(true);
+ }
+
+}
diff --git a/tests/system/src/test/java/com/sun/javafx/application/PlatformStartupExplicitTest.java b/tests/system/src/test/java/com/sun/javafx/application/PlatformStartupExplicitTest.java
new file mode 100644
--- /dev/null
+++ b/tests/system/src/test/java/com/sun/javafx/application/PlatformStartupExplicitTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.application;
+
+import org.junit.Test;
+
+/**
+ * Test for Platform exit behavior when implicitExit is set to false
+ */
+public class PlatformStartupExplicitTest extends PlatformStartupCommon {
+
+ @Test
+ public void testPlatformStartupExplicitExit() {
+ doTestStartupExplicitExit();
+ }
+}
diff --git a/tests/system/src/test/java/com/sun/javafx/application/PlatformStartupImplicitTest.java b/tests/system/src/test/java/com/sun/javafx/application/PlatformStartupImplicitTest.java
new file mode 100644
--- /dev/null
+++ b/tests/system/src/test/java/com/sun/javafx/application/PlatformStartupImplicitTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.javafx.application;
+
+import org.junit.Test;
+
+/**
+ * Test for Platform exit behavior when implicitExit is set to true
+ */
+public class PlatformStartupImplicitTest extends PlatformStartupCommon {
+
+ @Test
+ public void testPlatformStartupImplicitExit() {
+ doTestStartupImplicitExit();
+ }
+}
diff --git a/tests/system/src/test/java/launchertest/Constants.java b/tests/system/src/test/java/launchertest/Constants.java
--- a/tests/system/src/test/java/launchertest/Constants.java
+++ b/tests/system/src/test/java/launchertest/Constants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,4 +61,9 @@
static final int ERROR_CONSTRUCTOR_WRONG_CCL = 24;
static final int ERROR_START_WRONG_CCL = 25;
+
+ static final int ERROR_STARTUP_SUCCEEDED = 26;
+ static final int ERROR_STARTUP_FAILED = 27;
+
+ static final int ERROR_ASSERTION_FAILURE = 28;
}
diff --git a/tests/system/src/test/java/launchertest/MainLauncherTest.java b/tests/system/src/test/java/launchertest/MainLauncherTest.java
--- a/tests/system/src/test/java/launchertest/MainLauncherTest.java
+++ b/tests/system/src/test/java/launchertest/MainLauncherTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -82,6 +82,11 @@
new TestData("TestApp"),
new TestData("TestAppNoMain"),
new TestData("TestNotApplication"),
+ new TestData("TestStartupApp1", ERROR_NONE),
+ new TestData("TestStartupApp2", ERROR_NONE),
+ new TestData("TestStartupAppNoMain", ERROR_NONE),
+ new TestData("TestStartupJFXPanel", ERROR_NONE),
+ new TestData("TestStartupNotApplication", ERROR_NONE),
new TestData("TestAppThreadCheck", ERROR_NONE),
new TestData("TestAppNoMainThreadCheck", ERROR_NONE),
new TestData("TestNotApplicationThreadCheck", ERROR_NONE),
@@ -224,13 +229,23 @@
case ERROR_START_WRONG_CCL:
throw new AssertionFailedError(testAppName
+ ": start has wrong CCL");
+ case ERROR_LAUNCH_SUCCEEDED:
+ throw new AssertionFailedError(testAppName
+ + ": Application.launch unexpectedly succeeded");
+ case ERROR_STARTUP_SUCCEEDED:
+ throw new AssertionFailedError(testAppName
+ + ": Plataform.startup unexpectedly succeeded");
+ case ERROR_STARTUP_FAILED:
+ throw new AssertionFailedError(testAppName
+ + ": Plataform.startup failed");
+
+ case ERROR_ASSERTION_FAILURE:
+ throw new AssertionFailedError(testAppName
+ + ": Assertion failure in test application");
case ERROR_UNEXPECTED_EXCEPTION:
throw new AssertionFailedError(testAppName
+ ": unexpected exception");
- case ERROR_LAUNCH_SUCCEEDED:
- throw new AssertionFailedError(testAppName
- + ": Application.launch unexpectedly succeeded");
default:
throw new AssertionFailedError(testAppName
diff --git a/tests/system/src/test/java/launchertest/TestStartupApp1.java b/tests/system/src/test/java/launchertest/TestStartupApp1.java
new file mode 100644
--- /dev/null
+++ b/tests/system/src/test/java/launchertest/TestStartupApp1.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package launchertest;
+
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.stage.Stage;
+
+import static launchertest.Constants.*;
+
+/**
+ * Test Platform.startup from FX application.
+ * This is launched by MainLauncherTest.
+ */
+public class TestStartupApp1 extends Application {
+
+ @Override public void start(Stage stage) throws Exception {
+ System.err.println("Should never get here");
+ System.exit(ERROR_START_BEFORE_MAIN);
+ }
+
+ public static void main(String[] args) {
+ try {
+ Platform.startup(() -> {
+ // do nothing
+ });
+ System.err.println("ERROR: platform startup unexpectedly succeeded");
+ System.exit(ERROR_STARTUP_SUCCEEDED);
+ } catch (IllegalStateException ex) {
+ System.exit(ERROR_NONE);
+ }
+ /*NOTREACHED*/
+// Application.launch(args);
+ }
+
+ static {
+ try {
+ Platform.runLater(() -> {
+ // do nothing
+ });
+ } catch (IllegalStateException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_TOOLKIT_NOT_RUNNING);
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_UNEXPECTED_EXCEPTION);
+ }
+ }
+
+}
diff --git a/tests/system/src/test/java/launchertest/TestStartupApp2.java b/tests/system/src/test/java/launchertest/TestStartupApp2.java
new file mode 100644
--- /dev/null
+++ b/tests/system/src/test/java/launchertest/TestStartupApp2.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package launchertest;
+
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.stage.Stage;
+
+import static launchertest.Constants.*;
+
+/**
+ * Test Platform.startup from FX application.
+ * This is launched by MainLauncherTest.
+ */
+public class TestStartupApp2 extends Application {
+
+ @Override public void start(Stage stage) throws Exception {
+ try {
+ Platform.startup(() -> {
+ // do nothing
+ });
+ System.err.println("ERROR: platform startup unexpectedly succeeded");
+ System.exit(ERROR_STARTUP_SUCCEEDED);
+ } catch (IllegalStateException ex) {
+ System.exit(ERROR_NONE);
+ }
+ }
+
+ public static void main(String[] args) {
+ Application.launch(args);
+ }
+
+ static {
+ try {
+ Platform.runLater(() -> {
+ // do nothing
+ });
+ } catch (IllegalStateException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_TOOLKIT_NOT_RUNNING);
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_UNEXPECTED_EXCEPTION);
+ }
+ }
+
+}
diff --git a/tests/system/src/test/java/launchertest/TestStartupAppNoMain.java b/tests/system/src/test/java/launchertest/TestStartupAppNoMain.java
new file mode 100644
--- /dev/null
+++ b/tests/system/src/test/java/launchertest/TestStartupAppNoMain.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package launchertest;
+
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.stage.Stage;
+
+import static launchertest.Constants.*;
+
+/**
+ * Test Platform.startup from application with no main method.
+ * This is launched by MainLauncherTest.
+ */
+public class TestStartupAppNoMain extends Application {
+
+ @Override public void start(Stage stage) throws Exception {
+ try {
+ Platform.startup(() -> {
+ // do nothing
+ });
+ System.err.println("ERROR: platform startup unexpectedly succeeded");
+ System.exit(ERROR_STARTUP_SUCCEEDED);
+ } catch (IllegalStateException ex) {
+ System.exit(ERROR_NONE);
+ }
+ }
+
+ static {
+ try {
+ Platform.runLater(() -> {
+ // do nothing
+ });
+ } catch (IllegalStateException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_TOOLKIT_NOT_RUNNING);
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_UNEXPECTED_EXCEPTION);
+ }
+ }
+
+}
diff --git a/tests/system/src/test/java/launchertest/TestStartupJFXPanel.java b/tests/system/src/test/java/launchertest/TestStartupJFXPanel.java
new file mode 100644
--- /dev/null
+++ b/tests/system/src/test/java/launchertest/TestStartupJFXPanel.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package launchertest;
+
+import javafx.application.Platform;
+import javafx.embed.swing.JFXPanel;
+
+import static launchertest.Constants.*;
+
+/**
+ * Test Platform.startup from class that is not an Application.
+ * This is launched by MainLauncherTest.
+ */
+public class TestStartupJFXPanel {
+
+ public static void main(String[] args) {
+ try {
+ Platform.runLater(() -> {
+ // do nothing
+ });
+ System.exit(ERROR_TOOLKIT_IS_RUNNING);
+ } catch (IllegalStateException ex) {
+ // OK
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_UNEXPECTED_EXCEPTION);
+ }
+
+ // This will start the platform
+ new JFXPanel();
+
+ // Verify that Platform.startup throws expected exception
+ try {
+ Platform.startup(() -> {
+ // do nothing
+ });
+ System.err.println("ERROR: platform startup unexpectedly succeeded");
+ System.exit(ERROR_STARTUP_SUCCEEDED);
+ } catch (IllegalStateException ex) {
+ System.exit(ERROR_NONE);
+ }
+ }
+
+}
diff --git a/tests/system/src/test/java/launchertest/TestStartupNotApplication.java b/tests/system/src/test/java/launchertest/TestStartupNotApplication.java
new file mode 100644
--- /dev/null
+++ b/tests/system/src/test/java/launchertest/TestStartupNotApplication.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package launchertest;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+import javafx.application.Platform;
+
+import static launchertest.Constants.*;
+
+/**
+ * Test Platform.startup from class that is not an Application.
+ * This is launched by MainLauncherTest.
+ */
+public class TestStartupNotApplication {
+
+ private static void assertEquals(String expected, String actual) {
+ if (expected == null && actual == null) return;
+ if (expected != null && expected.equals(actual)) return;
+ System.err.println("Assertion failed: expected (" + expected + ") != actual (" + actual + ")");
+ System.exit(ERROR_ASSERTION_FAILURE);
+ }
+
+ public static void main(String[] args) {
+ try {
+ Platform.runLater(() -> {
+ // do nothing
+ });
+ System.exit(ERROR_TOOLKIT_IS_RUNNING);
+ } catch (IllegalStateException ex) {
+ // OK
+ } catch (RuntimeException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_UNEXPECTED_EXCEPTION);
+ }
+
+ final Semaphore sem = new Semaphore(0);
+ final ArrayList list = new ArrayList<>();
+ final String keyStartup = "Startup runnable";
+ final String keyRunLater0 = "runLater #0";
+ final String keyRunLater1 = "runLater #1";
+ try {
+ Platform.startup(() -> {
+ list.add(keyStartup);
+ sem.release();
+ });
+ Platform.runLater(() -> {
+ list.add(keyRunLater0);
+ sem.release();
+ });
+ sem.acquire(2);
+ } catch (IllegalStateException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_STARTUP_FAILED);
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_UNEXPECTED_EXCEPTION);
+ }
+
+ Platform.runLater(() -> {
+ list.add(keyRunLater1);
+ sem.release();
+ });
+ try {
+ sem.acquire();
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ System.exit(ERROR_UNEXPECTED_EXCEPTION);
+ }
+ assertEquals(keyStartup, list.get(0));
+ assertEquals(keyRunLater0, list.get(1));
+ assertEquals(keyRunLater1, list.get(2));
+
+ System.exit(ERROR_NONE);
+ }
+
+}