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.
Related
This question already has answers here:
Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"
(19 answers)
Closed 2 years ago.
I just started learning about Servlets. I followed the basic steps to create a new servlet project:
File -> new -> Dynamic Web Project -> new -> Servlet (AddServlet) with a basic print statement in the doGet()
package com.demo.servlets;
//all of my imports
#WebServlet("/AddServlet")
public class AddServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public AddServlet() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().print("Hello");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
I'll I've done is make the servlet but I can't get past this step. I've looked at a million tutorials and stack overflow answers. I made sure Tomcat 9.0 was installed and connected to my project correctly, made sure the servlet version was 4.0, made sure my build path was correct, made sure that my servlet was in a package.
I've also even tried using web.xml instead of the web annotations but I get the same 404error. . Ive been working on this for the past 72 hours, and I don't understand what the problem is.
You need to override doGet and doPost from HttpServlet. For this reason you need to add #Override annotation above the doGet and doPost.
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//some code here
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//performTask(req, resp);
//some code here
}
private void insertRequestTemplate() {
HttpSession session = req.getSession();
responsePage = req.getParameter("ResponsePage");
ServletContext ctx = getServletConfig().getServletContext();
ctx.getRequestDispatcher(responsePage).forward(req,resp);
readMessage();
public void readMessage()
{
System.out.println("calling MessageTrigger_ABean");
MessageTrigger_ABean msg = new MessageTrigger_ABean();
msg.read();
}
msg.read() has the code to read messages from MQ. Inside insertRequestTemplate method, I am calling readMessage method after ctx.getRequestDispatcher(responsePage).forward(req,resp);is this the correct way of calling this?
But inside insertRequestTemplate method, the page is not getting forwarded to the next page untill readMessage() is executed because of which the page keeps on loading for a long time until message is read from MQ. Could you please help me on this.
Most examples I have seen of a servlet forwarding the request to another servlet have the dispatcher forward invocation at the end of the method. ie. there is no more code, other than closing braces at the end of the method.
I am guessing that the forwarding doesn't happen until the invoking method completes. So where you have your msg.read() will stop the insertRequestTemplate method from completing. This will more than likely be because the code inside msg.read is being performed synchronously. Leading to http timeouts on the http request.
How you solve this will depend on what you want to do with the messages you obtain from msg.read().
I'm trying to practice multiple asynchronous request chain in servlets and I'm bumping into a weird behavior. Not sure if it has anything to do with tomcat.
So here's the scenario. I have a simple J2EE maven web application.
I have two servlets and a filter. I have marked all of them with asyncSupported=true. When I click on a link in a JSP, the first servlet does indeed take the request and spawns a new worker thread using AsyncContext. The worker thread then writes something to the response, commits it (as I learned it's legal for asynchronous processing in servlets) and then dispatches the request to another servlet. It works fine till this point.
The second servlet is supposed to spawn a second worker thread and then the plan was to make the second worker thread call dispatch (As I was also trying to practice the parameter-less call to dispatch()) to go back to the Second servlet that called it. However, I get the below error when calling startAsync() on the second servlet
06-Apr-2018 19:04:48.128 WARNING [RMI TCP Connection(5)-127.0.0.1] org.apache.catalina.startup.ContextConfig.validateSecurityRoles Security role name [authSupervisor] used in an <auth-constraint> without being defined in a <security-role>
06-Apr-2018 19:04:48.261 INFO [RMI TCP Connection(5)-127.0.0.1] com.kingshuk.listeners.MyServletContextListener.contextInitialized The servlet class com.kingshuk.servlets.MyAppDynamicServlet is now being registered
06-Apr-2018 19:05:09.025 WARNING [http-nio-8080-exec-8] org.apache.catalina.connector.Request.startAsync Unable to start async because the following classes in the processing chain do not support async []
java.lang.IllegalStateException: A filter or servlet of the current chain does not support asynchronous operations.
at org.apache.catalina.connector.Request.startAsync(Request.java:1636)
at org.apache.catalina.connector.Request.startAsync(Request.java:1628)
at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:1043)
at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:378)
at com.kingshuk.servlets.BiggestAsyncSecondServlet.doGet(BiggestAsyncSecondServlet.java:23)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.kingshuk.filters.AsyncRequestLoggingFilter.doFilter(AsyncRequestLoggingFilter.java:25)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712)
at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:633)
at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:601)
at org.apache.catalina.core.AsyncContextImpl$AsyncRunnable.run(AsyncContextImpl.java:566)
at org.apache.catalina.core.AsyncContextImpl.doInternalDispatch(AsyncContextImpl.java:352)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:196)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:235)
at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:228)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Below are all the related files
The Filter
#WebFilter(filterName = "AsyncRequestLoggingFilter",
urlPatterns = {"/asyncServlet", "/biggestAsyncRequestTest", "/biggestAsyncRequestTest2"},
asyncSupported = true,
dispatcherTypes = {DispatcherType.ASYNC, DispatcherType.REQUEST})
public class AsyncRequestLoggingFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
System.out.println("<<AsyncRequestLoggingFilter>> Initializing the Filter");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws ServletException, IOException {
if (DispatcherType.ASYNC.equals(req.getDispatcherType())) {
System.out.println("<<AsyncRequestLoggingFilter>> This is BEFORE calling the doFilter during the ASYNC dispatching");
} else {
System.out.println("<<AsyncRequestLoggingFilter>> This is BEFORE calling the doFilter");
}
chain.doFilter(req, resp);
if (DispatcherType.ASYNC.equals(req.getDispatcherType())) {
System.out.println("<<AsyncRequestLoggingFilter>> This is AFTER returning from the doFilter call after the ASYNC dispatching");
} else {
System.out.println("<<AsyncRequestLoggingFilter>> This is AFTER returning from the doFilter call");
}
}
public void destroy() {
System.out.println("<<AsyncRequestLoggingFilter>> Destroying the Filter");
}
}
The First Servlet
#WebServlet(name = "BiggestAsyncFirstServlet",
urlPatterns = "/biggestAsyncRequestTest",
asyncSupported = true)
public class BiggestAsyncFirstServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(10000);
asyncContext.addListener(asyncContext.createListener(BiggestAsyncContextListener.class));
//asyncContext.start(new BiggestAsyncFirstWorkerThread());
/*
Step 5.Get the reference to the thread pool that was created in the context listener class
when the app was deployed
*/
ThreadPoolExecutor executor = (ThreadPoolExecutor) request.getServletContext().getAttribute("executor");
/*
Step 6.Actually creating the worker thread
and kick starting the thread by calling the run method of the class implementing the runnable interface.
*/
executor.execute(new BiggestAsyncFirstWorkerThread(asyncContext));
System.out.println("Hi I'm the servlet " + getServletName() + " and my job is done");
}
}
The Second servlet
#WebServlet(name = "BiggestAsyncSecondServlet",
urlPatterns = "/biggestAsyncRequestTest2",
asyncSupported = true)
public class BiggestAsyncSecondServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
//asyncContext.setTimeout(10000);
//asyncContext.createListener(BiggestAsyncContextListener.class);
//asyncContext.start(new BiggestAsyncFirstWorkerThread());
/*
Step 5.Get the reference to the thread pool that was created in the context listener class
when the app was deployed
*/
ThreadPoolExecutor executor = (ThreadPoolExecutor) request.getServletContext().getAttribute("executor");
/*
Step 6.Actually creating the worker thread
and kick starting the thread by calling the run method of the class implementing the runnable interface.
*/
executor.execute(new BiggestAsyncSecondWorkerThread(asyncContext));
System.out.println("Hi I'm the servlet " + getServletName() + " and my job is done");
}
}
The first worker thread
public class BiggestAsyncFirstWorkerThread implements Runnable {
private AsyncContext context;
public BiggestAsyncFirstWorkerThread(AsyncContext context) {
this.context = context;
}
#Override
public void run() {
//The idea is to write something to the response and then dispatch.
try {
AsyncRequestProcessor.waitingTime(6000);
PrintWriter writer = context.getResponse().getWriter();
writer.print("<html>\n" +
"<head>\n" +
" <title>User login</title>\n" +
"\n" +
" <link rel=\"stylesheet\" type=\"text/css\" href=\"/" +
context.getRequest().getServletContext().getServletContextName() + "/style/master_css.css\">\n" +
"\n" +
"\n" +
"</head>");
writer.print("<body>\n" +
"<div id=\"allcontent\">");
context.getRequest().getRequestDispatcher("pages/common/header.jsp").
include(context.getRequest(), context.getResponse());
writer.print(" <div id=\"actual_content\">");
context.getResponse().flushBuffer();
context.dispatch("/biggestAsyncRequestTest2");
} catch (IOException | ServletException e) {
e.printStackTrace();
}
}
}
The second worker thread
public class BiggestAsyncSecondWorkerThread implements Runnable {
private AsyncContext context;
public BiggestAsyncSecondWorkerThread(AsyncContext context) {
this.context = context;
}
#Override
public void run() {
//The idea is to write something to the response and then dispatch.
try {
AsyncRequestProcessor.waitingTime(6000);
PrintWriter writer = context.getResponse().getWriter();
context.getRequest().getRequestDispatcher("pages/common/cr_leftnav.jsp").
include(context.getRequest(), context.getResponse());
writer.print(" <div id=\"content-body\">\n" +
" <h3>The external app</h3>");
writer.print("<p>This is the page you have been waiting so patiently for. After one round of asynchronous processing" +
"here you are. I love you..!!</p>");
writer.print(" </div>\n" +
" </div>\n" +
"</div>\n" +
"</body>\n" +
"</html>");
context.getResponse().flushBuffer();
//context.complete();
context.dispatch();
} catch (IOException | ServletException e) {
e.printStackTrace();
}
}
}
And finally the initial call from the jsp that triggered this request in the first place
<div id="sidebar">
<ul id="parent_nav">
<li>Checking everything async does</li>
</ul>
</div>
Note: I have an async listener too. But the error seems to have nothing to do with it, so leaving it
Some additional info
Before the error I have mentioned at the top prints, the following lines are printed in the logs, suggesting that it's going wrong on line 23 of the Second Servlet.
<<AsyncRequestLoggingFilter>> This is BEFORE calling the doFilter
Hi I'm the servlet BiggestAsyncFirstServlet and my job is done
<<AsyncRequestLoggingFilter>> This is AFTER returning from the doFilter call
<<AsyncRequestLoggingFilter>> This is BEFORE calling the doFilter during the ASYNC dispatching
My apologies for such a long question. Any help I can get to understand why it's saying "A filter or servlet of the current chain does not support asynchronous operations." despite all the components being marked with asyncSupported=true, is deeply appreciated.
Thanks,
Kingshuk
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
homePageController = (HomePageControllerV2) BeanLoader.getBean("homePageControllerV2");
}
}
whenever i hit to servlet from multiple machine. i still get the same instance of homePageController. is there any way can get diffrent instance of object homePageControllerper servlet request.
i have tired with changing the scope of bean to prototype. but still faced the same issue.
I am just beginning with Servlets and managed to have some servlets that act as individual URLs for populating a database for some dummy testing. Something of the form:
public class Populate_ServletName extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain");
//Insert records
//Print confirmation
}
}
I have about 6 such servlets which I want to execute in a sequence. I was thinking of using setLocation to set the next page to be redirected but was not sure if this is the right approach because the redirects should happen after the records have been inserted. Specifically, I am looking for something like this:
public class Populate_ALL extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain");
//Call Populate_1
//Call Populate_2
//Call Populate_3
//...
}
}
Any suggestions?
Use RequestDispatcher#include() on an URL matching the url-pattern of the Servlet.
public class Populate_ALL extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
request.getRequestDispatcher("/populateServlet1").include(request, response);
request.getRequestDispatcher("/populateServlet2").include(request, response);
request.getRequestDispatcher("/populateServlet3").include(request, response);
//...
}
}
Note: if those servlets cannot be used independently, then this is the wrong approach and you should be using standalone Java classes for this which does not extend HttpServlet. In your specific case, I think the Builder Pattern may be of interest.
The RequestDispatcher#forward() is not suitable here since it throws IllegalStateException when the response headers are already committed. This will be undoubtely the case when you pass the request/response through multiple servlets which each writes to the response.
The HttpServletResponse#sendRedirect() is absolutely not suitable here since it implicitly creates a brand new request and response, hereby trashing the original ones.
See also:
How do I call a second JSP servlet while in the first JSP servlet?
RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()
communication between remote servlets
It looks like what you may need is a service that each of the servlets can use to perform some work. Then the servlets are not depending one and another, but rather all using the service.
However, here is an explanation of forwarding or redirecting requests.