Jetty 9.3.6 and Servlet WebAppContext getServletContext() returns null - servlets

I am missing something with this I am sure. But I have spent the last few days searching and unfortunately I have not found an answer that seems to fit.
I have a Servlet that extents HttpServlet and overrides init() "not init(ContextConfig)" and in the init() function getServletContext is always returning null. This was not the case while I was using Springs 4.0.x and Jetty 8.1.x I would guess I am doing something wrong but at a loss as to what it is. I have generally removed Springs from the test code, but it still gets null.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<display-name>MyServlet</display-name>
<servlet-name>MyServlet</servlet-name>
<servlet-class>servlet.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
JavaConfig Starter partial:
WebAppContext root = new WebAppContext();
root.setDescriptor("./WEB-INF/web.xml");
root.setDisplayName("Root Context");
root.setSessionHandler(sesh); //Persist Session across restarts of context
root.setHandler(csh);
root.setMaxFormContentSize(10000000);
// Cron Servlet
System.out.println("Checking root ServletContext ");
if (root.getServletContext() == null)
System.out.println("ServletContext is null");
//ServletHolder test = new ServletHolder(new MyServlet());
//test.setDisplayName("test");
//test.setName("test");
//root.addServlet(test, "/the");
root.setResourceBase(new File("./jsp").getPath());
server.setHandler(root);
//Start the server
server.start();
server.join();
And the servlet:
package servlet;
import java.io.*;
import org.apache.log4j.Logger;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyServlet extends HttpServlet {
static Logger log = Logger.getLogger(MyServlet.class);
private static final long serialVersionUID = 1L;
public void init() throws ServletException {
// Initialization code...
log.info("MyServlet init()");
super.init();
ServletContext sc = getServletContext();
if (sc == null)
log.info("54: Conext returned null");
}
public void destroy() {
log.info("MyServlet destroy()");
}
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setHeader("Server", "GoAway");
doProcess(req, resp);
}
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setHeader("Server", "GoAway");
doProcess(req, resp);
}
private void doProcess(HttpServletRequest req, HttpServletResponse resp) throws IOException {
PrintWriter out = resp.getWriter();
// setup no cache
resp.setContentType("text/html");
resp.getWriter().println("<html><head><META HTTP-EQUIV=\"refresh\" content=\"0;URL=/\"></head><body>\n</body>\n</html>");
resp.getWriter().close();
out.close();
return;
}
protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Server", "GoAway");
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
}
}
So this is something I stripped out of a larger application to figure out what I was doing wrong. so somethings might still be un-needed. You can see in the Javaconfig I have tried creating the servlet container there as well, but the results are the same.
So from inside the Start code the servletContext is not null.
but from inside the MyServlet init() code it is always returning null.
I really am not sure what I am doing wrong.
Thanks for your help.
o FYI included Jar's
commons-beanutils-1.9.2.jar
commons-codec-1.9.jar
commons-io-2.2.jar
commons-logging-1.2.jar
javax.el-2.2.6.jar
javax.el-api-2.2.5.jar
javax.mail-1.5.3.jar
javax.servlet-api-3.1.0.jar
jetty-http-9.3.6.v20151106.jar
jetty-io-9.3.6.v20151106.jar
jetty-security-9.3.6.v20151106.jar
jetty-server-9.3.6.v20151106.jar
jetty-servlet-9.3.6.v20151106.jar
jetty-util-9.3.6.v20151106.jar
jetty-webapp-9.3.6.v20151106.jar
jetty-xml-9.3.6.v20151106.jar
log4j-1.2.17.jar
org.apache.jasper.glassfish-2.2.2.v201112011158.jar
slf4 j-api-1.7.13.jar
spring-aop-4.2.3.RELEASE.jar
spring-beans-4.2.3.RELEASE.jar
spring-context-4.2.3.RELEASE.jar
spring-context-support-4.2.3.RELEASE.jar
spring-core-4.2.3.RELEASE.jar
spring-expression-4.2.3.RELEASE.jar
spring-tx-4.2.3.RELEASE.jar
spring-web-4.2.3.RELEASE.jar
Update 2015.12.10:
So I played around a bit with different Jetty Versions. The original code was using 8.1.17 and I decided to upgrade it to 9.3.6. So I downgraded it to 9.3.5, but had the same results. Then I downgraded to 9.2.14 and the problem was resolved. So Either this is a bug in Jetty 9.3.x ( which would seem unlikely as someone would be using this) or with 9.3 their is a different way to configure it. I looked for documentation about it be it all shows the same way that I am doing it.

Related

Servlet Response wrapper to add getHeaderNames and getHeaders methods to Servet 2.4 spec container not working

Since Servlet 3.0, HttpServletResponse#getHeaderNames() and HttpServletResponse#getHeaders() has been available. However, I'm using an older spec, specifically Servlet 2.4.
Having looked at the resource, How can I get the HTTP status code out of a ServletResponse in a ServletFilter?, I got an idea of how to write a wrapper. If I understand it right, I have to use setHeader() to facilitate the creation of getHeaderNames() and getHeaders(). I think I have a solid footing on how to store the headers to simulate the usage of these missing methods.
The problem is the filter which leverages this wrapper does not seem to be calling setHeader() automatically. I don't get it. I presume sincegetStatus() is working properly, I'm expecting setHeader() to behave in the same fashion. Specifically, I'm looking to print out all the response headers, after calling chain.doFilter(). I'm not sure what I'm doing wrong here. Maybe there is something wrong with how I'm storing header name-value pairs.
I would appreciate any help. Thank you.
public class ServletResponseWrapper extends HttpServletResponseWrapper {
private int httpStatus = SC_OK;
private HashMap<String, String> hashMapHeaders = new HashMap<String, String>();
public ServletResponseWrapper(HttpServletResponse response) {
super(response);
}
#Override
public void sendError(int sc) throws IOException {
httpStatus = sc;
super.sendError(sc);
}
#Override
public void sendError(int sc, String msg) throws IOException {
httpStatus = sc;
super.sendError(sc, msg);
}
#Override
public void setStatus(int sc) {
httpStatus = sc;
super.setStatus(sc);
}
public int getStatus() {
return httpStatus;
}
#Override
public void sendRedirect(String location) throws IOException {
httpStatus = SC_MOVED_TEMPORARILY;
super.sendRedirect(location);
}
#Override
public void setHeader(String name, String value) {
hashMapHeaders.put(name, value);
super.setHeader(name, value);
}
public String getHeader(String name) {
return hashMapHeaders.get(name);
}
public Enumeration<String> getHeaderNames() {
Enumeration<String> enumerationHeaderNames = Collections.enumeration(hashMapHeaders.keySet());
return enumerationHeaderNames;
}
}
public class ServletResponseWrapperFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
ServletResponseWrapper servletResponseWrapper = new ServletResponseWrapper( (HttpServletResponse) response );
chain.doFilter( request, servletResponseWrapper );
// Process response
// This works, even though I never explicitly call the setStatus() method
int status = response.getStatus();
// This returns NULL because no header values get set; I presume setHeader() gets called implicitly
Enumeration<String> headerNames = servletResponseWrapper.getHeaderNames();
}
public void init(FilterConfig config) throws ServletException {
//empty
}
public void destroy() {
// empty
}
}
web.xml file
<display-name>Tomcat App</display-name>
<filter>
<filter-name>ResponseHeadersFilter</filter-name>
<filter-class>com.company.filters.ResponseHeadersFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ResponseHeadersFilter</filter-name>
<url-pattern>/testfilter.jsp</url-pattern>
</filter-mapping>
I took the vendor's servlet out of the equation. The filter now fires on an empty JSP file. Tomcat is also hooked to a front-end web server, IIS. I disabled IIS. Now, I'm accessing the website directly over Tomcat, via port 8080. Despite all this, I dot see any response headers.
Using Fiddler, the response headers I see are few but existing, namely:
(Cache) Date
(Entity) Content- Length, Content-Type
(Miscellaneous) Server
And status response, i.e. HTTP/1.1 200 OK
I can get by without getting response headers in the filter. But the big question I have is this is a bug with Servlet version 2.4 or is there some kind of OS Server and/or Tomcat configuration change I need to enable? Unless there's some Tomcat configuration, I'm led to believe this is likely a bug. Perhaps a clean install using the default configuration of the Tomcat version I'm using, 5.5.28, would resolve the problem, but I cannot attempt that at this time.

Servlet WebServlet multiple urlPattern

I must write a servlet that should do multiple operations according to the button I press on the html page.
I have one button that is a Insert into the Db, another is a Delete, another is a Select.
So I would like my servlet will do all those three operations in the doGet method.
My clue was to put
#WebServlet("select", "insert", "delete")
public class MyServlet extends HttpServlet {
...
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = request.getServletPath()!=null?request.getServletPath():"";
switch(path){
case "/select":
...
break;
switch(path){
case "/insert":
...
break;
switch(path){
case "/delete":
...
break;
then, into the javascript file it would have been (for select)
var req={
method: 'GET',
url: 'http://localhost:8080/AngularDb/select',
}
$http(req);
and into the web.xml
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
But all this doesn't work.
May you tell me what is wrong?

Groovy Servlet met java.lang.ClassNotFoundException: groovy.lang.GroovyObject

I'm trying to build a very simple Servlet using Groovy. Since it's just a single servlet plus a couple of gsp pages I don't want to integrate Grails into my project because I'm new to it. When I want the servlet run on Tomcat server(v7.0) I met such exception:
java.lang.ClassNotFoundException: groovy.lang.GroovyObject
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClass(ClassLoader.java:800)
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2904)
org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1173)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1681)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)...
Look at this thread Got java.lang.NoClassDefFoundError: groovy/lang/GroovyObject It seems the servlet.groovy is compiled fine but runtime env is not met.
My question is, how can I meet the runtime env without Grails(if possible)? I already have groovy-all-2.3.7.jar in my buildpath. Or could it be caused by version problems?
The servlet is extremely simple because I met the problem at very beginning.
import groovy.servlet.GroovyServlet
class Dispatcher extends GroovyServlet {
private static final long serialVersionUID = 1L;
public Dispatcher(){
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
println request;
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
println(request.getParameter("option"));
request.setAttribute("option", request.getParameter("option"));
Map<String,Object> result=new HashMap<>();
request.setAttribute("result", result);
println request;
// Forward to GSP file to display message
RequestDispatcher dispatcher = request
.getRequestDispatcher("/result.gsp");
dispatcher.forward(request, response);
}
}
To have the groovy-all-2.3.7.jar in the build path is not enough, it has to be in the WEB-INF/lib folder of the webapp, or in the Tomcat's lib folder, too.

Getting ClassNotFoundException when trying to implement web filter in my JSF app

i have a JSF app and for some reasons i need to refresh the page on browser back button.I tried implementing the solution given in Force JSF to refresh page / view / form when opened via link or back button by BalusC ,the only difference is that my app runs with servlet version 2.5 so i did the mapping in web.xml as below
<?xml version="1.0" encoding="UTF-8"?>
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
javax.faces.STATE_SAVING_METHOD
client
javax.faces.CONFIG_FILES
/WEB-INF/faces-config.xml
com.sun.faces.config.ConfigureListener
javax.faces.PROJECT_STAGE
Production
javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE
true
login.xhtml
FacesServlet
javax.faces.webapp.FacesServlet
1
FacesServlet
/faces/
FacesServlet
.jsf
FacesServlet
.faces
FacesServlet
.xhtml
SessionUtil
SessionUtil
com.gaic.lpsr.utilclasses.SessionUtil
SessionUtil
/SessionUtil
<filter>
<filter-name>cacheFilter</filter-name>
<filter-class>com.gaic.lpsr.utilclasses.NoCacheFilter.java</filter-class>
</filter>
<filter-mapping>
<filter-name>cacheFilter</filter-name>
<servlet-name>FacesServlet</servlet-name>
</filter-mapping>
My filter class is
public class NoCacheFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (!request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
}
chain.doFilter(req, res);
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
// ...
}
I have included the jar servlet-api-2.5.jar.When i try to deploy app in tomcat server(version 6.0.29) i am getting the below error.
SEVERE: Exception starting filter cacheFilter
java.lang.ClassNotFoundException: com.gaic.lpsr.utilclasses.NoCacheFilter.java
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1645)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:269)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:422)
at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:115)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4001)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4651)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:445)
at org.apache.catalina.core.StandardService.start(StandardService.java:519)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:581)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Please guide me how to fix this problem.
Did silly mistake in web.xml :).Solved by removing .java extension in filter mapping
<filter-class>com.gaic.lpsr.utilclasses.NoCacheFilter</filter-class>

Lifecycle/Scope of #WebServlet [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do servlets work? Instantiation, session variables and multithreading
I have a weird (but probably expected) behaviour in my WebServlet. Environment is:
- Apache 2.2.x
- Glassfish 3.1.1 + mod_jk
- JSF Mojarra 2.1.3
I have an abstract servlet that implements some code to check in the FacesContext/Session if there is a specific #SessionScoped managed bean and if so, whether the user is signed-in. If user is signed-in, then proceeds to the file delivery. The implementing #WebServlet only provides the actual file download.
Abstract Servlet:
public abstract class SecureDownloadServlet extends HttpServlet {
#EJB
private UserProductBean userProductBean;
private UserInfoView userInfoView = null;
private UserInfoView getUserInfoView(HttpServletRequest req) {
FacesContext context = FacesContext.getCurrentInstance();
if (context != null) {
userInfoView = (UserInfoView) context.getApplication()
.getELResolver().getValue(FacesContext.
getCurrentInstance().getELContext(), null, "userInfoView");
}
if (userInfoView == null) {
userInfoView = (UserInfoView) getServletContext().
getAttribute("userInfoView");
}
if (userInfoView == null) {
userInfoView = (UserInfoView) req.getSession().
getAttribute("userInfoView");
}
return userInfoView;
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse response)
throws IOException, ServletException {
if (getUserInfoView(req) == null || !getUserInfoView(req).getLoggedIn()) {
response.sendRedirect("message.xhtml?msg=noLogin");
return;
}
doDownload(req, response);
}
public abstract void doDownload(HttpServletRequest req,
HttpServletResponse response)
throws IOException, ServletException;
}
Then I have a #WebServlet that extends the above abstract HttpServlet and implements the abstract method:
#WebServlet(name = "SecureImageServlet", urlPatterns = {"/print","/m/print"})
public class SecureImageServlet extends SecureDownloadServlet {
#Override
public void doDownload(HttpServletRequest req, HttpServletResponse response)
throws IOException, ServletException {
// some code
}
}
Now here is the issue:
- From computer A, sign in, then call the SecureImageServlet servlet to get a file (i.e. http://www.example.com/print?id=12345). The userInfoView session bean is initialized as expected, and the file is delivered.
- From computer B, without being signed-in, call http://www.example.com/print?id=12345. The userInfoView is already initialized with the session of user on computer A!!! And the file is delivered too.
It looks like the WebServlet becomes ApplicationScope or something like that. Is it the #EJB injection that does that?
Note the the instance of userInfoView is the same (the object id in the debugger shows the same number) which means somehow the computer B is seen as the same user as computer A
Edited format
Ok, a friend of mine (without an account on SO :) ) pointed out my mistake:
I am using userInfoView as a class member instead of keeping it within the request scope. I fixed it by removing the class member and voila!

Resources