Java / Editorial solution guide
Diagnose classpath, module, and class-version failures
Classify loading, resolution, access, and bytecode-version problems before changing a launch command or weakening encapsulation.
Read-only knowledge base ยท No public comments
Recognize the symptoms
Messages may include Could not find or load main class, ClassNotFoundException, NoClassDefFoundError, FindException, InaccessibleObjectException, or UnsupportedClassVersionError. They represent different boundaries and should not receive one generic โadd a JARโ fix.
A program can work in an IDE yet fail from a packaged artifact because the IDE supplied different dependencies, output roots, runtime, or module options.
Understand the likely causes
- The binary name may not match the classpath root, a dependency may be absent at runtime, module descriptors may not resolve, or reflection may cross a closed package.
- A class compiled for a newer release may exceed the deployment JVM's supported class-file version. Copying files or adding opens flags cannot backport that bytecode or its required APIs.
Capture the real launch context
Record the exact compiler target, java and javac versions, artifact identity, launch arguments, and deployment directory without exposing secrets in command-line options. Compare with the working environment. Rebuild into a clean temporary output directory to eliminate stale classes. Use the first causal error, not only a later wrapper reporting that startup failed. Do not modify a configured service while studying the reproduction.
Verify the binary name and search root
If the declaration is package training.app and the class is Main, launch training.app.Main from a classpath root above training/app. Inspect a local JAR with the jar tool to see whether the expected entry and dependencies exist. imports do not control runtime loading. NoClassDefFoundError can also follow a previous initialization failure, so inspect the earlier cause before assuming the file is simply missing.
Use one minimal reproduction containing the intended package and only its required dependency. Compare the expected binary path with the actual artifact entry, then launch from a clean root. Add further dependencies only after explaining each mismatch. This prevents an oversized classpath from accidentally hiding a duplicate class or an artifact from the wrong build.
Separate module resolution from access
A module-not-found error concerns module identity and the module path. An inaccessible reflective member concerns exports or opens and the supported integration design. First prefer public supported APIs and correct descriptors. A narrowly reviewed opens declaration can be legitimate, but blanket --add-opens or --add-exports flags are not a missing-dependency repair and should not become an unexplained permanent workaround. Test the intended named-module or classpath launch mode explicitly.
Repair an evidenced version mismatch
UnsupportedClassVersionError requires a compatible runtime or a rebuild for the supported release, such as javac --release 17 for this course's baseline. The release flag checks platform APIs as well as language and class-file target. A Java 21 virtual-thread API cannot be made available in a Java 17 build by adding preview flags. Validate all transitive dependencies against the deployment runtime, not just the application's own classes.
Use a minimal local identity check
This complete classpath example reports the known platform module and its own binary name. It does not inspect another application or discover a secret configuration. Compare such a controlled baseline with the failing artifact's declared identity. Tool inspection output and version strings are environment-dependent, so keep their actual results rather than inventing a fixed value in a report.
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(String.class.getModule().getName());
System.out.println(Main.class.getName());
}
}
java.base
Main
The example runs on the classpath as Main and reads only its own type metadata and the standard String type.
Verify the fix
Verify the exact packaged launch command in a fresh isolated directory on the supported runtime, including required resources and dependencies. Confirm normal startup and a meaningful smoke operation, then remove temporary bypass flags. Preserve the error-to-fix explanation so success is tied to corrected resolution, access, or version compatibility rather than an accidental IDE configuration.
Keep it from recurring
- Keep builds reproducible, use explicit release targets, and test the deployable artifact and its dependency graph. Review module exposure as an API decision and pin supported runtime requirements in documentation and automation.