2

here is a template code of netbeans IDE for a JavaFX project. if you clear public keyword from BombDroid class you get runtime error.why? Note:I know that main should be public.But why Bombdroid class should be public?

package bombdroid;

import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.shape.*;
import javafx.stage.Stage;

public class BombDroid extends Application {
    @Override
    public void start(Stage primaryStage) {
        Group root = new Group();
        Scene scene = new Scene(root);
        Line line = new Line(0, 0, 500, 500);
        Rectangle man = new Rectangle(0, 0, 100, 100);
        root.getChildren().add(line);
        root.getChildren().add(man);
        primaryStage.setScene(scene);
        primaryStage.show();
        }
    public static void main(String[] args) {
        launch(args);
        }
    }
gigili
  • 195
  • 1
  • 13
  • My guess would be that because it's different classes that end up calling `main`, those classes cannot see that class, because it's `default` or `package-private`. I'd be interested to see what happens if you set the package to the same as the calling code (`java.lang` maybe?) – Zymus Mar 29 '16 at 19:56
  • @Zymus, this is an application launched by the JRE runtime launcher `java`. There is no user code which acts as calling code. All calling code is in the JRE. Due to JRE security restrictions user code cannot be placed in java.lang (`java.lang.SecurityException: Prohibited package name: java.lang`), so it is not possible to try the test you suggest. – jewelsea Mar 29 '16 at 21:28
  • While it may be tempting to think this question is a duplicate of the related question: [why main method in Java need to be public always?](http://stackoverflow.com/questions/20776413/why-main-method-in-java-need-to-be-public-always), it is not as this question refers to the access classifier on the class containing the main method, not the main method itself. – jewelsea Mar 30 '16 at 04:15

1 Answers1

3

The launcher for JavaFX applications works via reflection, a consequence of which and the way it is used is that a JavaFX Application class must be declared public.

The specific error message you get when running your sample (without a main method, which is unnecessary for a JavaFX application) is:

Exception in Application constructor
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class BombDroid
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: BombDroid.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.getConstructor(Class.java:1825)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:818)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

As you can see, the system is looking for a no-argument constructor to your application class. Tracing through, the source code at LauncherImpl.java:818, is:

Constructor<? extends Application> c = appClass.getConstructor();

The documentation for the getConstructor() method states:

Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object.

@throws NoSuchMethodException if a matching method is not found.

If your application class is not public, it has no public constructor, and a NoSuchMethodException is returned when you try to launch it. Which is what is happening here, causing the launch of the Application to fail.

Aside

Note the requirement that the Application class for JavaFX be public differs from a non-JavaFX application. For example, the simplest hello world program in Java does not require a public class to run, only a public main method.

class HelloWorld {
    public static void main(String[] args) {
        System.out.println("hello, world");
    }
}
jewelsea
  • 150,031
  • 14
  • 366
  • 406