Search code examples
javaintellij-idea

Relation between Java , IntellIj and Classpath


I am trying to setup a project in IntelIj . I was facing some issue related to project structure setting in IntelIj . Although I was able to fix it . but I am still confused why it was not working with default settings ?

With following config I was getting an error to configure the out path . enter image description here

I was facing following error :-

enter image description here

Why is this happening ?

To fix this I chose another option in Modules compiler output path , and let the default options be there .

enter image description here

Although it fixed the above issue but it caused another issue - ClassNotFoundException

enter image description here

Then to fix this I added a path manually for compiler output . enter image description here

It fixed the problem .

One difference which I see in the terminal that -classpath is being used while running main method . enter image description here

Please note that both Java and IntelIj are not installed in C drive but in D drive . Don't know if this could cause any issue .

One more question :- In my IntelIj why do I need to manually set directory as source root ?

Please help me understand why this happens . I would appreciate a detailed explanation . Thanks .


Solution

  • The general way Java works is that source code is saved to .java files, which are then compiled to .class files (typically in a different directory to your source files).

    The class files are then run in a Java Virtual Machine, which finds the compiled .class files using the classpath.

    You have to tell the Java compiler and therefore IntelliJ where the source files are (the source root) and which directory you want to use when the source .java files are compiled to .class files.

    While this may appear redundant in an IntelliJ project with only a single module, however IntelliJ projects often contain multiple modules and keeping the .java source files and compiled .class files separate at the module level is generally good practice, imho.

    Anyway, IntelliJ lets you choose, resulting in the following options:

    Given a project with a single module:

    my-project
      + my-module
        + src
          + com
            + mycompany
              + myproject
                + mymodule
                  + Main.java
    

    IntelliJ lets you specify where the .class files will be created, at either:

    • the project level - this option is not normally what you want, because all .class files from all modules will end up under that root (in either production or test directories). For example, specifying where the .class files are created at a project level would result in:

       my-project
         + out 
           + production
             + com 
               + mycompany
                 + myproject
                   + mymodule
                     + Main.class
      

      Which would be run something like:

      java -cp my-project/out/production com.mycompany.myproject.mymodule.Main
      
    • the module level - this is normally the option you want, because .class files can be stored relative to the module (although this may appear redundant in a project with one module, it's still a good practice, imho). For example, specifying where the .class files are created at a project level would result in:

       my-project
         + my-module 
           + out
             + com 
               + mycompany
                 + myproject
                   + mymodule
                     + Main.class
      

      Which would be run something like:

       java -cp my-project/my-module/out com.mycompany.myproject.mymodule.Main
      

    Essentially, the reason for creating modules is to isolate parts of your codebase, hence the point about it being good practice to specify the output directory at the module level.