JSP compilation issue due to JSTL validation on adding a jsp to running embedded jetty instance - jstl

I have created a JSP test framework but running into this issue if I try to add jsp to running server. The project config is as follows:
JSP is present under /webapps folder.
I create a ServletHolder dispatching to this JSP and add the servlet to webcontext.
I setup the embedded Jetty server with this webcontext and start the server
jsp page is served fine.
Now I create another ServletHolder for a different JSP and add it to running server's webcontext.
On accessing the page, I get following exception
java.lang.NullPointerException
at org.apache.taglibs.standard.tlv.JstlBaseTLV.validate(JstlBaseTLV.java:149)
at org.apache.taglibs.standard.tlv.JstlCoreTLV.validate(JstlCoreTLV.java:105)
at org.apache.jasper.compiler.TagLibraryInfoImpl.validate(TagLibraryInfoImpl.java:949)
at org.apache.jasper.compiler.Validator.validateXmlView(Validator.java:1921)
at org.apache.jasper.compiler.Validator.validate(Validator.java:1888)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:223)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:451)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:625)
at org.apache.jasper.servlet.JspServletWrapper.loadTagFile(JspServletWrapper.java:280)
at org.apache.jasper.compiler.TagFileProcessor.loadTagFile(TagFileProcessor.java:660)
at org.apache.jasper.compiler.TagFileProcessor.access$000(TagFileProcessor.java:91)
at org.apache.jasper.compiler.TagFileProcessor$TagFileLoaderVisitor.visit(TagFileProcessor.java:719)
org.apache.jasper.JasperException: PWC6033: Error in Javac compilation for JSP
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:634)
Strange thing is, if I stop the webcontext and add the servlet and start webcontext again, things run fine.
I tried to debug this and found that for the second jsp/tag call to 'JstlCoreTLV.getInitParameters()' is returning null, maybe jstl is reusing the validation object from previous cache and this property is reset to null in between.
Has anyone come across this issue? would it be a bug in JSTL library?

Here is a workaround I used to fix this issue - Reinitialized the default JSP servlet to invalidate its taglib cache
ServletHolder jspServletHolder = webContext.getServletHandler()
.getServlet("jsp");
Servlet jspServlet = jspServletHolder.getServlet();
ServletConfig jspServletConfig = jspServlet.getServletConfig();
jspServlet.destroy();
jspServlet.init(jspServletConfig);

Related

Log4j2 JSP Taglib not working in Spring-boot Embedded Servlet Containers

I have a Spring boot web application which I created using the spring-boot-starter-web artifact. I am using Spring Boot Embedded Servlet Containers features to use the Tomcat embedded server. I am able to run my app in Tomcat embedded mode. I can also create a WAR file of my app and deploy it to a normal installation of Tomcat.
I have one JSP page in which I am using log4j2's JSP taglib tags. On a normal installation of Tomcat the logging from that JSP page works as expected. But when bootRun on the Tomcat embedded server I get the following error
SEVERE: Servlet.service() for servlet [jsp] in context with path [] threw exception [The absolute uri: [http://logging.apache.org/log4j/tld/log] cannot be resolved in either web.xml or the jar files deployed with this application] with root cause
org.apache.jasper.JasperException: The absolute uri: [http://logging.apache.org/log4j/tld/log] cannot be resolved in either web.xml or the jar files deployed with this application
Can this issue be solved?
The problem is occurring because Spring Boot skips log4j-*.jar by default. I've opened an issue to address this.
You can work around the problem by explicitly enabling scanning of the log4j-taglib jar. To do so, you need to add a TomcatContextCustomizer that changes the configuration of the jar scanner:
#Bean
TomcatContextCustomizer log4jTldScanningCustomizer() {
return (context) ->
((StandardJarScanFilter)context.getJarScanner().getJarScanFilter()).setTldScan("log4j-taglib*.jar");
}

Spring MVC: how to handle incoming request to wrong context path

How do we handle incoming request to a wrong contextpath in spring mvc?
I have deployed a spring mvc application having contextpath as
http://exampledomain.com/mycontext
But when I try accessing url http://exampledomain.com/wrongcontext I get error as HTTP Status 404 - /wrongcontext/
I have implemented error handling which works fine for all wrong url when correct context path is used but it does not work for wrong context path.
I am trying to understand how do we redirect all incoming request to specific page in production environment..
thanks in advance
Your application can only see requests to its context /mycontext There is nothing your application can do about requests to other contexts.
You can however deploy an application at the root context / and implement an error handler there.
Check out this answer: How to customize JBoss AS7 404 page
That answer relates to JBoss, but the same idea will apply on other servers.
It is not possible to handle wrong context path requests in Spring since it only will handle the requests which goes to your context root. You have to take a look at server configuration parameters to redirect those kind of requests. If you are working on Tomcat, check path parameter of context.xml:
https://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Defining_a_context
We can use #ExceptionHandler inside a #Controller or #ControllerAdvice to handle such kind of exceptions and decide on the view page to be rendered.
#ExceptionHandler({ HttpRequestMethodNotSupportedException.class,
HttpMediaTypeNotSupportedException.class, HttpMediaTypeNotAcceptableException.class,
MissingPathVariableException.class, MissingServletRequestParameterException.class,
ServletRequestBindingException.class,MethodArgumentNotValidException.class, MissingServletRequestPartException.class,
NoHandlerFoundException.class})
public ModelAndView handleException(){
return new ModelAndView("errorpage");
}

Questions about spring reference statement and application context

I have two primary doubts about spring:
When we get a bean from context, should we must use ways like :
context = new ClassPathXmlApplicationContext("applicationContext.xml");
Should it be called only via this explicit way?
I was thinking about that when the website start, this spring config file should also be read.
When we use tags of spring or other packages like jstl, etc. We should give the reference statement first like :
<%# taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
I was so curious about that, when the page is parsing, the web server do download this uri and use it in this page? But without internet, it seems also work. How it works, or why we must add this in the head part of a file.
It is indeed possible to get a bean from the Spring context that way, but it might be considered to be defeating the purpose of having a bean container with dependency injection. The goal of the container would be to provide the beans to your classes, so they don't need to instantiate or grab them directly from the context. See this short tutorial for a simple example of (xml-based) DI.
The uri attribute in a <%taglib> tag can be resolved locally if the tld is in your classpath under a certain specific path. See With JSP, does the taglib URI mean that my site is reliant on the URI resolving?.

UnknownSessionException when using SessionScoped CDI managed beans with Shiro managed sessions

I am developing a JSF web based application that makes use of CDI managed beans and Shiro managed sessions. The problem I've got is when a JSF page that references an object annotated with #javax.enterprise.context.SessionScoped an UnknownSessionException is thrown. I have set the logging level to finest and looking through the application server log file I can see that when the user accesses the login page a new session is created along with a cookie that sets JSESSIONID to b2b69494-2236-467f-9e0b-3c262c74b7c4. When the user accesses the page that references the SessionScoped bean the cookie is updated to have a JSESSIONID set to 49253beaee601d4107cba4b61c77, at this point an UnknownSessionException is thrown. When accessing pages that reference a managed bean annotated with either #javax.enterprise.context.ApplicationScoped or #javax.faces.view.ViewScoped everything works fine.
It appears that when accessing a page that references a session scoped bean, the servlet container is creating a new session rather than allowing the Shiro managed session to be used. If I configure Shiro to use something other than JSESSIONID then the error isn't thrown but instead two sessions appear to be created, one managed by Shiro and the other managed by the servlet container.
The contents of my shiro.ini file is
[main]
authc.loginUrl = /login.xhtml
authc.usernameParam = login:username
authc.passwordParam = login:password
authc.rememberMeParam = login:rememberMe
user.loginUrl = /login.xhtml
authc.successUrl = /app/index.xhtml
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
[users]
admin = password
[urls]
/login.xhtml = authc
/app/** = user
My environment is using Glassfish 4.1, Java EE version 7, Mojarra version 2.2.7 for JSF, Weld version 2.2.2 for CDI, and Shiro version 1.2.3. I have also reproduced the same issue on Glassfish version 4.0 albeit with earlier versions of Mojarra and Weld.
I have uploaded the relevant portion of the application server log to PasteBin which can be accessed with the URL http://pastebin.com/2sPHfdTQ
I've also created an example Maven project to demonstrate the problem. The example project can be downloaded from https://www.dropbox.com/s/1x9pe2o9ja0q9jw/TestJavaEE-web.zip?dl=0 which contains the source code and the complied war file.
Is anyone else currently using CDI managed session scoped beans with Shiro managed sessions, and if so have you had any problems?
Is there a configuration setting I've missed either in Shiro or GlassFish or is this a bug?
Note: I have previously posted this question on the Shiro mailing list but I'm yet to find a solution and I'm hoping that there will be a wider audience on StackOverflow.

Error 404: No target servlet configured for uri

I just got done with a new Web module built with Spring Framework. Till now I was testing all the pages on my local machine using Tomcat. Today after I moved the application to Websphere,
I am getting the following error:
Error 404: No target servlet configured for uri
is there anything I need to do in web.xml or somewhere? I deployed an EAR file on my WAS , which has another war file.
Below is the output I am seeing on the console, if thats any help.
The resource WEB-INF/ibm-web-bnd.xmi that is defined in URI WEB-INF/ibm-web-bnd.xmi for module analytics.war is not valid. The resource has a cross reference org.eclipse.jst.j2ee.webapplication.internal.impl.WebAppImpl#4be44be4 (eProxyURI: WEB-INF/web.xml#WebApp_ID) that cannot be resolved.
[6/17/09 15:24:49:465 CDT] 00000011 ArchiveDeploy W ADMA0091E: The resource WEB-INF/ibm-web-ext.xmi that is defined in URI WEB-INF/ibm-web-ext.xmi for module analytics.war is not valid. The resource has a cross reference org.eclipse.jst.j2ee.webapplication.internal.impl.WebAppImpl#7b7a7b7a (eProxyURI: WEB-INF/web.xml#WebApp_ID) that cannot be resolved.
It looks like you haven't got your servlet configured correctly. I'd say your web.xml has a servlet-name entry that doesn't correspond to a -servlet.xml file in your WEB-INF directory.
I got same error for my json response. This is fixed by setting contentLength in the action.
ibm-web-bnd.xmi has an attribute: fileServingEnabled.
This controls if Websphere is serving static content or not (index.html, pictures, etc.).
It is true, by default if omitted, but you can make sure it is on by adding it to tag WebAppExtension
fileServingEnabled="true"

Resources