The javac compiler is failing because it can’t find the .class files for classes you’re trying to use, indicating a classpath issue.

Common Causes and Fixes

1. Missing JAR File on Classpath

  • Diagnosis: Run jar tvf /path/to/your.jar to list the contents of the JAR. If the package/class you need isn’t listed, the JAR is wrong or incomplete. If the JAR exists but javac still complains, the JAR isn’t on the classpath.
  • Fix: Ensure the JAR containing the missing classes is included in your classpath.
    • Command Line: javac -cp ".:/path/to/missing.jar" YourClass.java
    • Maven/Gradle: Add the dependency to your pom.xml or build.gradle file. For example, in Maven:
      <dependency>
          <groupId>com.example</groupId>
          <artifactId>missing-artifact</artifactId>
          <version>1.0.0</version>
      </dependency>
      
    • Why it works: The -cp flag (or build tool configuration) tells the compiler where to look for .class files and .jar files. Without it, javac only looks in the current directory.

2. Incorrect Package Declaration in Source File

  • Diagnosis: Open YourClass.java. The very first non-comment line should be package com.example.mypackage;. If this is missing, or doesn’t match the directory structure, the compiler won’t find it.
  • Fix:
    • Ensure the package declaration at the top of YourClass.java exactly matches the directory structure where the file resides. For example, if YourClass.java is in src/com/example/mypackage/, the file must start with package com.example.mypackage;.
    • If the file is in the default package (no package declaration), it must be in the root of the source directory being compiled.
  • Why it works: Java’s package system is directly mapped to the file system. The compiler expects a class com.example.mypackage.YourClass to be found within a com/example/mypackage/ directory.

3. Compiling from the Wrong Directory

  • Diagnosis: If you’re in the directory containing YourClass.java and it has package com.example.mypackage;, but you’re running javac YourClass.java, it will fail.
  • Fix: Navigate to the root directory of your source code (the directory above your package directories) and compile using the fully qualified class name.
    • Command: If your source files are in src/com/example/mypackage/YourClass.java:
      cd src
      javac com/example/mypackage/YourClass.java
      
    • With classpath: If you have external JARs:
      cd src
      javac -cp "../lib/external.jar" com/example/mypackage/YourClass.java
      
  • Why it works: This allows the compiler to correctly resolve the package structure relative to the specified classpath or current directory.

4. Transitive Dependency Missing (Maven/Gradle)

  • Diagnosis: If YourClass.java depends on com.example.AnotherClass which is provided by artifact-B, and artifact-B is provided by artifact-A, but you’ve only declared artifact-A in your build file.
  • Fix: Ensure all direct and transitive dependencies are declared correctly in your build tool.
    • Maven: Run mvn dependency:tree to see the dependency hierarchy. If artifact-B is missing, add it as a direct dependency to your pom.xml.
    • Gradle: Run gradle dependencies to see the tree. If artifact-B is missing, add it to your build.gradle.
  • Why it works: Build tools manage dependency resolution. If a library you depend on (directly or indirectly) is missing, the classes it provides won’t be available to the compiler.

5. Incorrect JAVA_HOME or JDK Version Mismatch

  • Diagnosis: If you’re using features from a newer Java version (e.g., Java 11 var keyword) but compiling with an older JDK (e.g., Java 8 javac), you’ll get errors that look like missing classes or syntax errors.
  • Fix: Ensure your JAVA_HOME environment variable points to a JDK that supports the language features you’re using, and that javac is invoked from that JDK’s bin directory.
    • Check: javac -version and echo $JAVA_HOME
    • Set (Linux/macOS): export JAVA_HOME=/path/to/jdk-11 and export PATH=$JAVA_HOME/bin:$PATH
    • Set (Windows): Set JAVA_HOME in System Properties -> Environment Variables, and add %JAVA_HOME%\bin to your Path.
  • Why it works: Different Java versions have different language features and standard library classes. Using a compiler from an older version will not recognize constructs or classes introduced in newer versions.

6. Corrupted JAR Files

  • Diagnosis: The JAR file exists, is on the classpath, but jar tvf your.jar shows errors or the specific class is missing despite the JAR’s description suggesting it should be there.
  • Fix: Re-download or rebuild the corrupted JAR file. If it’s a dependency from a repository (Maven Central, etc.), clear your local Maven/Gradle cache (~/.m2/repository or ~/.gradle/caches) and rebuild the project to force a re-download.
  • Why it works: A corrupted JAR file means the internal structure is damaged, making it unreadable or incomplete for the compiler.

The next error you’ll likely encounter after fixing these is a java.lang.NoClassDefFoundError at runtime, because the compiler found the classes but the Java Virtual Machine (JVM) can’t find them when executing the application.

Want structured learning?

Take the full Java course →