javamoduleprogram-entry-point

How to set up a java module to run directly (not via a .jar file) without having to specify a main class


How does one set up a java program that can be run as a module simply by doing java -m mymodule?

I know this is possible because I have seen it in, e.g., the jwebserver documentation; you can run this by doing java -m jdk.httpserver. However there doesn't seem to be any evidence in the jdk source code about specifying the 'main' class of the module at any point, neither in the module-info.java file, nor in any of the main-containing classes of the module (of which there are two, not one).

How does the module know which main-containing class to pick as the main entry point for running the module? Is there some sort of convention that's not well documented? (e.g. if a package in the module contains a class called Main.java, is this special in any way? and should there only be one Main.java file over all packages in the module?)

In https://dev.java/learn/modules/intro/ there's an example of a module run without specifying the main class in the commandline, but it just says:

To launch a modular app, run the java command with a module path and a so-called initial module - the module that contains the main method

but without clarifying how this main method (and its respective class/package) is detected or specified for the module as the specific package/class to be used as the main entry point; and there's no requirement for a module's packages to not have more than one such main-containing class.

Please note the question is not about .jar files or specifying a main class for a jar file containing a module, but for modules themselves. (https://dev.java/learn/modules/building/ has good information for specifying main classes for jar files with modules, but this is not what I'm asking here).


Solution

  • Answering own question. I found the explanation here: https://youtu.be/C5yX-elG4w0?feature=shared&t=1857

    There are two ways to create something that can be launched as java -m <modulename> without specifying the main class (i.e. without having to do java -m <modulename>/<mainclass> explicitly:

    Since the jdk.httpserver is baked into the default jre environment (which can be confirmed by doing java --list-modules), this allows java -m jdk.httpserver to run directly. The implication here is that the java command itself was generated via a jdk.httpserver.jmod file, which specified the mainclass. We can confirm this is indeed the case by running jmod describe jdk.httpserver.jmod, which yields (among other lines) the line:

    main-class sun.net.httpserver.simpleserver.Main