Encountering JSP code that displays source code instead of executing is a common and frustrating issue for developers managing Java web applications. This specific behavior indicates that the server is not processing the JSP file as a dynamic template but is instead delivering it as a plain text asset. When this occurs, the browser reveals the raw Java and HTML code, signaling a fundamental failure in the rendering pipeline. Understanding the mechanics behind this failure is the first step toward resolving it and restoring the intended dynamic functionality.
Understanding the JSP Lifecycle and Compilation
The JavaServer Pages specification defines a strict lifecycle for JSPs that explains why source code might appear. When a browser requests a JSP for the first time, the web container, such as Apache Tomcat or Jetty, must translate the `.jsp` file into a standard Java Servlet. This translation converts JSP tags and scriptlets into pure Java code, which is then compiled into a `.class` file for execution. If this initial translation or compilation step is bypassed, the server cannot generate the dynamic response, resulting in the source code being sent directly to the user.
Common Culprit: Incorrect File Placement
A frequent reason for this issue is the physical location of the JSP file within the project's directory structure. Web servers are configured to serve dynamic content only from specific directories, typically the `WEB-INF` folder or the application root. However, static resources like images or CSS are often placed in public directories. If a developer mistakenly places a JSP file in a folder intended for static content, the container treats it as a regular file. In this scenario, the server skips the servlet engine entirely and performs a direct file download or text display, exposing the source code to the client.

| Correct Location | Incorrect Location |
|---|---|
| /WEB-INF/jsp/secret.jsp | /public_html/secret.jsp |
| /index.jsp | /resources/pages/index.jsp |
The Role of the web.xml Configuration
Deployment descriptors, primarily the `web.xml` file, dictate how a servlet container handles requests. Misconfigurations here are a primary suspect when JSPs fail to execute. If a servlet mapping is incorrect or missing, the container does not know to route `.jsp` requests to the JSP servlet handler. Furthermore, security constraints defined in `web.xml` might block access to the JSP page entirely. In such cases, the server might default to serving the file as plain text rather than returning a 403 Forbidden error, creating the illusion of a source code leak.
Verifying MIME Type Settings
Servers rely on MIME types to instruct browsers on how to handle a response. For JSPs to execute, the content type must be set to `text/html` so the browser renders it as a webpage. If the MIME type is incorrectly configured as `text/plain` or if the server fails to set a type specific to JSP execution, the browser might attempt to display the content directly. While this does not always cause the source to appear, it disrupts the rendering process and can expose the raw structure of the page, especially if the server defaults to a generic text transfer.
Debugging Server-Side Configuration
Beyond file structure and XML settings, the server environment itself requires scrutiny. Custom error pages defined in the deployment descriptor might be pointing to JSPs that cannot execute due to initialization failures. If the main application fails to compile, the server might attempt to serve the error page as a static resource, revealing the code. Additionally, specific server security managers or sandboxing features might restrict the Java permissions required for JSP compilation, effectively halting the process and leaving the source vulnerable to exposure.

To resolve this, developers should always inspect the server logs before checking the browser. Compilation errors or `ClassNotFoundException` entries often provide the exact reason why the JSP was not transformed. Ensuring that the runtime environment has the correct permissions and that no security policies are blocking access to the temporary compilation directories is essential for maintaining the integrity of the JSP execution pipeline.
Preventing Future Occurrences
Avoiding this issue requires a disciplined approach to project structure and version control. Teams should establish clear conventions regarding where dynamic pages reside versus static assets. Integrating build tools like Maven or Gradle can automate the correct packaging of JSPs into the `WEB-INF` directory, reducing human error. Consistent code reviews that verify `web.xml` mappings and server configurations also play a vital role in preventing regressions that lead to source code being served to end users.























