5

My directory looks like this. I am just outside of the blah folder.

$ tree.com //F
Folder PATH listing for volume Acer
Volume serial number is 127C-AD6A
C:.
└───blah
    └───src
        └───main
            └───java
                └───blahModule
                    │   module-info.java
                    │
                    └───blahPackage
                            blah.java

Then, I compile with the following command line options.

  • --module blahModule
  • --module-source-path blahModule="blah/src/main/java/blahModule"
  • -d "blah/classes"

Now, my directory looks like this.

$ javac     --module blahModule     --module-source-path blahModule="blah/src/main/java/blahModule"     -d "blah/classes"

$ tree.com //F
Folder PATH listing for volume Acer
Volume serial number is 127C-AD6A
C:.
└───blah
    ├───classes
    │   └───blahModule
    │       │   module-info.class
    │       │
    │       └───blahPackage
    │               blah.class
    │
    └───src
        └───main
            └───java
                └───blahModule
                    │   module-info.java
                    │
                    └───blahPackage
                            blah.java

Cool. Exactly as expected.

Now, I want to run my code. I used the following commandline options.

  • --module "blahModule/blahPackage.blah"
  • --module-path "blah/classes"

And this is the output.

$ java --module "blahModule/blahPackage.blah" --module-path "blah/classes"
Error occurred during initialization of boot layer
java.lang.module.FindException: Module blahModule not found

I cycled through many, many permutations. But I can't seem to find what I did wrong. Why can't it find my module?

Here are my files, though I doubt having them will help.

module-info.java

module blahModule
{

   requires java.base;
   // requires java.desktop;

}

blah.java


package blahPackage;

public class blah
{

        public static void main(String[] args)
        {

                System.out.println("blah");
                System.out.println(java.util.Arrays.asList(args));

        }

}
2
  • 4
    Not sure who downvoted this (score was -1 when I arrived). I think this is a fine question. You were making a trivial but easily overlooked mistake which, while clearly explained in the documentation if you know where to look, will not be obvious at all to most people who haven't encountered it before. Commented Nov 10 at 18:29
  • 1
    @JakeRobb I ran into this issue many many times in the past, and didn't know better. It prevented me from using modules for over a year. When I accidentally stumbled onto it again (lost 30 minutes today), I made this post. Commented Nov 11 at 4:08

1 Answer 1

6

Silly me.

It's an order of operations issue!

Consider the following command.

java --argument1 --argument2 SomeClassWithAMainMethod --argument3

In the above snippet, arguments 1 and 2 are arguments passed to java, but argument 3 is passed to your code, not to Java!

For example, like this.

java --class-path=someFolder SomeClassWithAMainMethod --module-path=anotherFolder

In this example, java only receives the --class-path argument. The --module-path argument is passed to the application! That means that my main method could read it as an argument, as in public static void main(String[] args), that type of argument!

Assuming that I wanted both arguments to be passed to Java, I just need to reorder them.

java --class-path=someFolder --module-path=anotherFolder SomeClassWithAMainMethod

Now, both arguments are being passed to java, and none to my application.

Well, as it turns out, --module SomeModule works the exact same way too!

In the above examples, everything past the SomeClassWithAMainMethod is considered to be an application argument, and not a java argument. Well, the same goes for --module SomeModule. Anything past that is evaluated as an application argument and not a java argument.

So, let's go back to my original run example.

java --module "blahModule/blahPackage.blah" --module-path "blah/classes"

In this case, everything after the --module "blahModule/blahPackage.blah" is being interpreted as an application argument, and not a java argument. Therefore, all I need to do to fix this is to switch the arguments around.

java --module-path "blah/classes" --module "blahModule/blahPackage.blah"

Now, when I run this command, the code runs like so.

$ java --module-path "blah/classes" --module "blahModule/blahPackage.blah"
blah

SUCCESS.

And just to prove that this is the issue, I added some stuff after --module "blahModule/blahPackage.blah".

$ java --module-path "blah/classes" --module "blahModule/blahPackage.blah" --module-path="someFolder"
blah
[--module-path=someFolder]

As you can see, the second copy of --module-path is NOT being passed to Java, but is instead, being passed to the application code. And I can access that from the application code by looking at the args field from my main method.

Sign up to request clarification or add additional context in comments.

2 Comments

you could also refer to the documentation to check (prove) that all arguments after the --module module-name is interpreted as argument and options must be given before --module
It was actually that exact link that did reveal the answer to me. However, I was also looking at that page for over 20 minutes before I read the part that said Optional: Arguments following mainclass, source-file, -jar jarfile, and -m or --module module/mainclass are passed as arguments to the main class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.