5

Do I need to run my main method inside a module or outside?

I am new in using the modular system of Java. I am trying create a simple program with JavaFX in Java 10, since it is the last version of Java that supports JavaFX.

I imported the necessary dependencies on my module-info.java for JavaFX which shows just a simple window.

sample.fxml code:

<?import javafx.scene.layout.GridPane?>
<GridPane fx:controller="com.gui.Controller"
          xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
</GridPane>

When I build my code it says:

Warning:(4, 27) java: module not found: com.main

When I try to run my code I get:

Exception in Application constructor Exception in thread "main" java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)

Can anyone give me advice for this, or somehow a real world application advice about creating projects with the modular system.

I have attached a pair of screenshots below.

Build Warning :

enter image description here

Runtime Failure :

enter image description here

neth07
  • 61
  • 3
  • Please review your question before posting and fix any mistakes. Do not use quotes instead of code blocks or vice versa. – Maarten Bodewes Oct 13 '18 at 15:13
  • And do not share image links, instead include the images in the question itself. – Naman Oct 13 '18 at 15:16
  • @neth07 On the other side, adding the `module-info.java` code to the question would make it further clear as well. – Naman Oct 13 '18 at 15:21

3 Answers3

2

The possible suspect here is that you're using com.main as a module name within the module-info.java which the IDE complains to have not found in the project.

I would guess, this could be possibly be resolved using com.gui as the module name in the declaration.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • Thanks for that, now the first was solved, the problem is I forgot to remove qualified exports of `com.main` when i did a test earlier. do you have ideas about the runtime failure? – neth07 Oct 13 '18 at 15:28
  • 2
    @neth07 I was expecting that, can you please update the question further now with the correct `module-info.java` and the `sample.fxml`? – Naman Oct 13 '18 at 15:29
1

The module system adds stronger encapsulation. In other words, it is no longer the case that all classes are reflectively accessible to every other class.

When launching JavaFX the usual way, an instance of your Application subclass is instantiated for you. This is done via reflection which means the module responsible for instantiating the subclass (javafx.graphics) must have the reflective access necessary to instantiate a public class with a public, no-arg constructor. To grant this access, the module containing the Application subclass must exports the appropriate package to at least javafx.graphics.

This is described in the documentation of Application:

...

The Application subclass must be declared public and must have a public no-argument constructor.

...

Deploying an Application as a Module

If the Application subclass is in a named module then that class must be accessible to the javafx.graphics module. Otherwise, an exception will be thrown when the application is launched. This means that in addition to the class itself being declared public, the module must export (or open) the containing package to at least the javafx.graphics module.

For example, if com.foo.MyApplication is in the foo.app module, the module-info.java might look like this:

module foo.app {
    exports com.foo to javafx.graphics;
}

You also seem to be using FXML. If necessary, you must make sure the appropriate packages are reflectively accessible to javafx.fxml (e.g. the controller class). This is documented in Introduction to FXML:

Deploying an Application as a Module

If FXMLLoader is used to load types in a named module, the application must ensure that all types that are referenced in the FXML files, including the controller class and any custom Node classes, are reflectively accessible to the javafx.fxml module. A type is reflectively accessible if the module opens the containing package to at least the javafx.fxml module.

For example, if com.foo.MyController is in the foo.app module, the module-info.java might look like this:

module foo.app {
    opens com.foo to javafx.fxml;
}
Slaw
  • 37,820
  • 8
  • 53
  • 80
0

I fixed this problem by making sure that:

the modules that requires javafx dependencies also exports itself cause some javafx packages or modules needs the modules that requires it.

ex. javafx.graphics

Also make sure that the fxml resource is correct.

1.) Correction on fxml resource:

enter image description here

2.) Exporting the module that requires javafx dependencies:

Error: (Read)

Caused by: java.lang.IllegalAccessException: class com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot access class com.gui.GUI (in module com.gui) because module com.gui does not export com.gui to module javafx.graphics
    at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:360)
    at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:589)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:479)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:875)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)

Solution : module-info.java

module com.gui {
    requires javafx.graphics;
    requires javafx.fxml;
    exports com.gui;
}
Community
  • 1
  • 1
neth07
  • 61
  • 3