Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

Servlet 3.1 is the latest greatest Servlet API version. I needed to figure out the correct Maven dependencies for using a Servlet 3.1 container, Tomcat 8 specifically. This task was made more difficult because the Java Servlet dependencies tend to move over time. It would be so much better if they were consistent and all one had to do was to change the version numbers. Or better yet, why can’t I include the dependency for Expression Language 3.0 and have it pull in all of its transitive dependencies?

The Tomcat documentation had the following:

Tomcat Servlet API JSP API JSTL API Expression Language API
8.0 3.1 2.3 1.2 3.0

It took a bit of tinkering, but I think I have the Maven dependencies for Servlet 3.1 worked out.

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>3.0.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

Most of the Servlet 3.1 dependencies are packaged by Tomcat 8 and should have their scope marked as provided. The JSTL library is not packaged by Tomcat and cannot be scoped as provided. If you do mark it as provided, you will get the following exception when you try to use JSTL

HTTP Status 500 - Handler processing failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config

type Exception report

message Handler processing failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config
	org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletionWithError(DispatcherServlet.java:1302)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:977)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config
	org.springframework.web.servlet.support.JstlUtils.exposeLocalizationContext(JstlUtils.java:101)
	org.springframework.web.servlet.view.JstlView.exposeHelpers(JstlView.java:135)
	org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:142)
	org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
	org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1243)
	org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
note The full stack trace of the root cause is available in the Apache Tomcat/8.0.30 logs.

Apache Tomcat/8.0.30

By using the above Maven dependencies, I was able to write a JSP page that used both Expression Language (EL) and JSTL Core Tags. All that is left now is to get to coding the next great webapp that is going to change the world.

April 12th, 2016

Posted In: Glassfish, Java, java ninja, Javaninja, JSP, Servlet Spec, Tomcat

Leave a Comment

I have a Springframework project that had a property value that contained the host of the server that I was going to be deployed on. There was more to it, because there were profiles, etc, but that is the gist of it. There is a value in a property file that I need.

The properties file was declared as:

<util:properties id="commonProperties" location="classpath:common-default.properties"/>

The contents of the properties file contained:

hostUrl=localhost:8080

To use the value in the jsp, pull in the Spring tags by:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

Tie it all together by

<spring:eval var="loginUrl" expression="@commonProperties.hostUrl"/>
<a href="http://${loginUrl}/hub/login.jsp">Return to login</a>

January 27th, 2014

Posted In: JSP, SpEl, Spring

2 Comments

I have a JSP tag file named collapsiblePanel with the following attribute declaration for a JSP fragment.

<%@ attribute name="content" required="true" fragment="true"
              description="Passed as fragment, renders content1 inside of panel." %>

I am using the tag around some output to create a collapsed panel.

                <tags:collapsiblePanel id="principalsSection"
                                       heading="Principals (${fn:length(business.principals)} Found)">
                    <jsp:attribute name="content">
                        <c:if test="${not empty business.principals}">
                            <div class="jx-container">
                                <table class="jx-table">
                                    <thead>
                                        <tr>
                                            <th>Name</th>
                                            <th>Title(s)</th>
                                            <th>Address</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <c:forEach var="principal" items="${business.principals}" varStatus="status">
                                            <tr class="${jxp:rowClass(status)}">
                                                <td>
                                                    ${principal.name.firstName} ${principal.name.middleName} ${principal.name.lastName}
                                                </td>
                                                <td>${principal.title}</td>
                                                <td>${jxp:tloAddress(principal.address)}</td>
                                            </tr>
                                        </c:forEach>
                                    </tbody>
                                </table>
                            </div>
                        </c:if>
                    </jsp:attribute>
                </tags:collapsiblePanel>

The collapsible panel adds an arrow before the heading and makes the arrow and the headging a clickable area that will trigger the uncollapse. I did not want to add the arrow or the clickable area if there wasn’t anything to uncollapse. I tried to test for this by saying

<c:if test="${empty content}">
     ...
</c:if>

This is supposed to work, but in Glassfish 2.1.1 content contains the reference to the content fragment. I worked around this by:

<jsp:invoke var="content" fragment="content"/>
<c:if test="${empty content}">
     ...
</c:if>

This did the trick. I evaluated the JSP fragment and placed the result in a variable also named content. I was able to then act on it like a normal attribute.

April 3rd, 2012

Posted In: Java, JSP

One Comment

LinkedIn Auto Publish Powered By : XYZScripts.com