Why a Tomcat app can work locally but fail after upload

When a Tomcat application runs correctly on your local machine but fails after upload, the cause is usually not Tomcat itself. In most cases, the application depends on a local environment that is slightly different from the hosting account, the build output is incomplete, or a library is missing from the deployed package. On shared Java hosting with a private Tomcat instance, these differences become visible very quickly because the server uses a controlled runtime, fixed service settings, and a clean deployment path.

If you are using a hosting control panel such as Plesk with a Java hosting extension like My App Server, the best approach is to verify the application package, the Tomcat version, the Java version, and the deployment structure before looking for more complex causes. A locally working app can fail remotely even when the source code is correct, simply because the uploaded WAR file does not contain everything it needs.

Why local Tomcat and hosted Tomcat can behave differently

A local development setup often hides packaging issues. Your IDE may automatically add libraries, use a different JDK, expand resources from source folders, or start the app with debug-friendly defaults. In hosting, the application is deployed from a built artifact, usually a WAR file, into a private JVM and Tomcat service. Only what is included in that build is available at runtime.

This means the following differences can break an application after upload:

  • Different Java version locally and on the hosting account.
  • Different Tomcat version or servlet API level.
  • Missing JAR files in the WAR.
  • Wrong folder structure inside the archive.
  • Case-sensitive file paths on Linux hosting.
  • External configuration files not copied to the server.
  • Environment variables or system properties that exist locally but not on the host.
  • Build output generated by the IDE, but not by the final build tool.

Most common reasons a Tomcat app fails after upload

1. Missing dependency in the packaged WAR

The most common problem is that the application works in the IDE because the IDE classpath includes everything, but the final WAR does not contain all runtime libraries. This often happens when a dependency is marked as provided, placed only in the local project, or excluded by the build tool.

Typical symptoms include:

  • ClassNotFoundException
  • NoClassDefFoundError
  • HTTP 500 on first application request
  • Tomcat starts, but the app fails during deployment

Check whether all required JAR files are present in the deployed package. If the application uses Maven or Gradle, verify the dependency scope and the final packaging task.

2. Wrong Java version

A Java application can compile on one version of the JDK and fail on another. For example, a class built with a newer bytecode level may not run on the Java version selected in the hosting account. The same applies to libraries that require a minimum runtime version.

With managed Java hosting, the Java version is usually selected at the service level or during app server setup. Make sure the runtime version matches what the application expects. If the app was built locally on a newer JDK, confirm that the target bytecode is compatible with the hosted JVM.

3. Incomplete WAR structure

Tomcat expects a proper web application layout. If the archive is missing required folders or descriptors, deployment may fail. A valid package should normally contain the web resources, compiled classes, and libraries in the expected locations.

Common packaging mistakes include:

  • Uploaded source files instead of compiled output.
  • Classes placed in the wrong path.
  • Libraries stored outside WEB-INF/lib.
  • Missing WEB-INF/web.xml when the application needs it.
  • Incorrect root folder nesting inside the WAR.

For hosted Tomcat, the upload should contain the final deployment artifact, not the project directory structure from the IDE.

4. Case-sensitive file names

Local development on Windows or macOS can ignore file name case in some situations, while Linux hosting is strict. A resource named Logo.png is not the same as logo.png on the server. The same applies to JSP includes, CSS, image references, and Java package names in file paths.

If the application works locally but resources fail to load after upload, check every reference for exact case matching.

5. External configuration not deployed

Some applications rely on configuration files outside the standard WAR, such as:

  • Database connection files
  • Property files
  • API credentials
  • SMTP settings
  • Custom XML configuration

These files may exist on your local machine, but not in the hosted environment. In a Plesk-based Java hosting setup, configuration is often stored in a private app directory or injected through service settings. If the app expects a local path such as C:\dev\config\app.properties, it will usually fail after upload.

6. Different environment variables or system properties

Local runs often depend on IDE-run parameters, environment variables, or JVM options. The hosted Tomcat service may not have the same values unless you set them explicitly. This is especially important for database URLs, file storage paths, and third-party service tokens.

Verify whether the application reads settings from:

  • Environment variables
  • System properties passed to the JVM
  • Configuration files inside the app
  • External files mounted or referenced by path

7. Library conflicts or duplicate JAR files

Sometimes the app contains multiple versions of the same library, or a dependency conflicts with the Tomcat-provided libraries. Locally, the IDE may resolve the conflict in a way that hides the issue. After upload, the class loading order can expose it.

Signs of this issue include:

  • Unexpected method errors at runtime
  • ClassCastException
  • Application starts but fails in specific features
  • Errors only after a newer library is added

Remove duplicate JAR files and make sure the application bundles only the libraries it really needs.

How to check your build output before uploading

Before uploading anything to hosted Tomcat, inspect the actual build artifact. Do not assume that the source tree, IDE project, or local run configuration reflects the final package. The key question is simple: does the WAR contain every runtime dependency and every required resource?

Step 1: Build the application from the command line

Use your build tool to create the final artifact in a clean build. This helps you see whether the application can be assembled without IDE help. For Maven or Gradle projects, run a full package task and review the output files.

If the build succeeds only in the IDE but fails in a clean package, the problem is usually in dependency scope, resource paths, or compile settings.

Step 2: Open the WAR and inspect its contents

Check the archive itself. A correct package should include the web content, the compiled classes, and the libraries in the expected folders. Compare the deployed archive with your local project structure.

Look specifically for:

  • WEB-INF/classes
  • WEB-INF/lib
  • JSP files in the right location
  • Static resources included in the package
  • Configuration files needed at runtime

Step 3: Confirm dependency scopes

Dependencies marked as provided are not packaged into the WAR. This is correct for some servlet APIs or server-provided libraries, but it can be a problem if a runtime dependency is accidentally marked this way.

Review your build file and ensure that all application-specific libraries are included in the final output.

Step 4: Verify the target Java level

Make sure the application is compiled for the Java version available in your hosting account. If the local machine uses a newer JDK, set the compiler target appropriately. This is one of the most common reasons a WAR deploys but does not run.

Step 5: Check resource references

Inspect JSP pages, controllers, and static assets for path mistakes. Hosted environments are less forgiving about relative paths that happen to work during local testing. Test image references, include statements, file uploads, and links to nested resources.

Tomcat hosting checks inside Plesk or My App Server

On a hosted Tomcat setup, such as a private JVM managed through Plesk and My App Server, you should also review the service settings. These controls are useful because they separate the application runtime from the web server and help you identify where the failure occurs.

Check whether the service starts correctly

If Tomcat itself does not start, the problem may be in the runtime configuration rather than the application. Use the service control options in the hosting panel to confirm that the Java service is running and that the selected Tomcat version is active.

Review the application logs

Tomcat logs usually reveal the exact deployment error. Look for stack traces during application startup, class loading failures, file access errors, and configuration issues. The first error in the log is often the most important one. Later messages may be only symptoms.

Confirm the selected Java and Tomcat version

Hosted Java platforms often allow you to choose from several prepared Tomcat and Java combinations. If your application was built for one version and deployed to another, the behavior can change. Ensure that the runtime version matches your application's requirements and that you are not relying on a local setup that uses different defaults.

Check upload location and deployment path

Make sure the WAR was uploaded to the correct app directory and that the service is configured to deploy that package. In some setups, the app is expected in a specific path and a wrong upload location may make it seem as though the application failed, when in fact it was never deployed.

Common build tool mistakes

Maven-specific issues

With Maven, check these points:

  • Dependencies incorrectly marked as provided.
  • Resources excluded from the package.
  • Profiles changing the final artifact only in local builds.
  • Compiler settings targeting a different Java version.

Gradle-specific issues

With Gradle, verify:

  • The correct WAR or bootWar task is used.
  • Runtime dependencies are in the final package.
  • Source and resource folders are configured properly.
  • The Java toolchain or target compatibility matches the hosting runtime.

IDE export issues

Projects exported directly from an IDE may look correct on the local machine but still miss generated files or packaging rules. Whenever possible, deploy the artifact produced by the build tool, not an ad hoc export from the IDE.

Practical troubleshooting checklist

If your Tomcat app works locally but fails after upload, use this checklist in order:

  1. Confirm the correct WAR or build output was uploaded.
  2. Open the archive and verify the expected structure.
  3. Check that all runtime JAR files are included.
  4. Compare the Java version locally and on the hosted service.
  5. Review Tomcat logs for the first startup error.
  6. Check file names and paths for case sensitivity.
  7. Verify external configuration files and environment settings.
  8. Remove duplicate or conflicting libraries.
  9. Restart the Tomcat service after a clean deploy.

Example scenario

A developer tests a JSP application locally and everything works. After uploading the WAR to the hosted Tomcat service, the homepage returns HTTP 500. The log shows ClassNotFoundException for a database driver. In the local IDE, the driver was available on the project classpath, but it was not included in the WAR. Once the driver JAR is added to the correct build dependency scope and the project is repackaged, the application deploys successfully.

This is a classic example of build output mismatch. The source code did not change. The packaged artifact did.

Best practices for Tomcat apps on managed hosting

To avoid deployment problems on hosted Tomcat, follow these practices:

  • Always test the final packaged WAR, not only the project in the IDE.
  • Keep runtime dependencies inside the build output when they are needed by the application.
  • Use the same Java version locally and on the hosting account whenever possible.
  • Keep configuration portable and avoid hardcoded local file paths.
  • Check logs immediately after deployment.
  • Deploy one clean version at a time to avoid confusion from old files.
  • Use exact file name casing in all references.

On a hosted Java platform with a private Tomcat and JVM, these habits save time because they reduce guesswork. The runtime is controlled and predictable, so most failures point back to packaging, compatibility, or configuration.

FAQ

Why does my app work in Eclipse or IntelliJ but not after upload?

Because the IDE often adds libraries, resources, and runtime settings that are not present in the final WAR. The hosted Tomcat service only sees the packaged output.

Can a missing library break deployment even if the app compiled successfully?

Yes. Compilation only proves that the classpath was correct at build time. The application can still fail at runtime if a required JAR is missing from the deployed package.

Does Tomcat version matter?

Yes. Some applications rely on features, APIs, or behaviors that differ between Tomcat versions. Always match the application requirements to the runtime version offered by your hosting service.

Why do file paths work locally but fail on the server?

Because hosted Linux environments are case-sensitive and usually do not have access to your local absolute paths. Any local-only path should be replaced with a portable configuration.

What should I check first when the app returns HTTP 500?

Start with the Tomcat logs. The first stack trace usually points to the real cause, such as a missing class, a bad config file, or a wrong Java version.

Is it enough to upload the source code?

No. Tomcat hosting needs the correct built artifact, usually a WAR file or a properly prepared application directory. Uploading source code alone is not enough unless the hosting setup explicitly supports building from source.

Conclusion

When a Tomcat application works locally but fails after upload, the root cause is usually packaging, compatibility, or configuration rather than the application logic itself. In a managed hosting environment with Plesk and a private Tomcat service, the most effective approach is to verify the WAR structure, runtime libraries, Java version, and log output before changing code.

If you build a clean artifact, include all required dependencies, and match the hosted Java/Tomcat environment, most deployment issues can be resolved quickly and predictably.

  • 0 Users Found This Useful
Was this answer helpful?