I have a legacy Java servlet that is currently running in a Tomcat container. I want to run it outside the container, as a standalone Java application. The primary intention in doing so is because the new role in which this application will be deployed, involves only computation, and no servicing of requests.
How should I go about modifying the servlet code? Will pulling out the servlet's init() code into the main() method of a new class help?
Extract the functionality you want from the servlet to other classes, so that the servlet is only the web interface to the functionality.
Those other classes should ideally not use anything in javax.servlet.*.
Then create a separate class with a main method that uses those other classes, in an appropriate way.
I would transform the servlet class into a main class, as you mentioned. The main method of the new class will create an instance of main class, execute init method to initialise if (potentially using the arguments received from the command line). Then invoke the service method inside a try/catch/finally block and invoke the destroy method of the servlet inside the finally block. Of course, your new service method will be invoked without parameters and will not contain any references to the servlet api.
yes.
The servlet implements the interface to interact with the Tomcat servlet container. If there are no settings read from the servlet context (path names, configuration paramters) you can extract the logic into a main class.
You will need to make sure you do not rely on the request/response scheme in your services. Usually if only one process runs code is much easier to write than in concurrent scenarios. But one cannot be sure there will be no such effect (for example caches that are now request based will not be emptied in standalone).
also remove any servlet api dependencies in your code. It will not work and is no longer required.
good luck!
You have to do that carefully. It may happen that some filters are doing necessary work not seen within the servlet
Assuming your case is rather simple and a GET or POST just triggers the code, it should be easy to convert into a classical java application.
Just call the former init part and the code from doGet or doPost respectly.
You need to figure out a couple of things first, the functionality in the servlet will probably react to some of the url's parameters.
first figure out what the computational part is and what parameters it expects,
once you understand that, figuring out what to put in your standalone application will be trivial.
another approach is to embed Jetty in your main application and let that run your servlet,
this will leave your servlet code untouched reducing the risk of introducing bugs
Related
I just wanted to ask if it is necessary to test the java servlet that calls another java method (in another file I might add) to do the bulk of the work.
Like for instance, my java servlet currently only is being used to get parameters and displaying the results of the method that was called in html format. So I am only planning on testing my main java file that does all the work!
I am not very familiar with testing so if there would be specific ways to test this simple Java servlet, please let me know!
Testing your Java Servlet or for that case, any Java code is very necessary. The way we always tend to write any code is called the HAPPY PATH, which sometimes overlooks possible scenarios that might break your service. It is always a best practice to code via the TDD way (test driven).
You can Unit Test your Servlet alone, if it does perform the main logic as a single unit.
You can perform Integration testing if your Servlet along with other Java code performs the logic as a whole.
There is this question on SO which covers almost all the details on how to perform this and also the various choices to choose from to perform them.
Hope this helps!
Like for instance, my java servlet currently only is being used to get
parameters and displaying the result of the method is has called in
html format. So I am only planning on testing my main java file that
does all the work!
Ideally, you should Why so?
If something messy happens and servlet broke befoe calling the Main business logic
Testing how parameters are fetched so you can be sure which kind of parameters my Servlet can handle (I personally don't like junk values to be passed to my business logic).
Is there anyway I can use spring to get rid of the main function in my java project.
It is going to be a standalone program, and I want spring to get rid of the main function, and take care of entry point by itself.
I understand that main function are a must, but I am talking something on the line of a dynamic web project, wherein I do not define the main classes, but just the services etc.
If You want a standalone application, that is impossible. You should rather load context in Your main method, and just run a specific bean's method (treat main method only as an entry point to Your app).
*Hello Guys..! *
Normally a java program needs main() function to execute the code otherwise it'll returns an error[java.lang.NoSuchMethodError: main Exception in thread "main"]..! In struts2 we are using action classes & bean classes(java codes) but they don't needs main() function in it. What is the concept behind this..? By the way I'm a newbie to the Struts framework.
This is because the Struts framework provides the infrastructure to get the application up and running. As a user of the framework, you implement specific classes that are called by the framework code.
Struts itself runs inside an application server such as Tomcat, and usually it is the server that contains the main() method which is ultimately responsible for starting up your application.
This is an example of inversion of control -- many application frameworks work this way.
You need a main() method in applications started from the command line as that's the API that the JVM expects to execute in that case. Code called from within other frameworks must implement whatever API that framework expects. In many cases that framework implements main() and calls your code via some other API. This is usually more robust than public void main(String[] args) allows. In other instances the framework is itself called from another abstraction (e.g. a Web Application within a Web Framework within a App Container).
I just got a servlet class working in Eclipse. I was testing it by deploying it using App Engine, and it would prompt me to run as a Web Application. Now I want to run this code from another class. So I made another class and put "TestServlet ts = new TestServlet();" in the main function. When I run it nothing happens. Do I have to make a call to the TestServlet's "doGet" method, or is it something to do with not running the main class as a web application?
Umm... you should not be doing this. Extract common logic into a separate POJO (plain old java object) class and invoke it from both your servlet and your other class.
Manually instantiating / invoking servlets is NOT a good idea.
You need a servlet container if you want to run it up for real. I would suggest using Winstone http://winstone.sourceforge.net. It's a small, fast, zero-config container for getting your servlet up and running.
Calling doGet (or doPost or any other visible method) in the instance of the servlet object will execute the containing code. However be aware that behaviour may differ from running the servlet in an web container if the code makes use of any of the "wired-in" context variables.
At face value I would suggest you refactor to have the code you require in a common method and call from both your servlet and your main class.
I need to execute a JSP. But I need to directly from Java, without using Tomcat or any other servlet container. Compiling JSPs would be a good thing too, but not necessary. I think maybe org.apache.jasper package is good for doing this, but I can't find any good example or tutorial online.
I need something as:
Class compiledJSP = compileJSP(new File("helloWorld.jsp"));
String html = executeJSP(compiledJSP, httpServletRequest, httpServletResponse, ...);
html --> "Hello World, John!"
Thanks!
If you need to capture JSP's output as string it's reasonably straightforward (although far from ideal from the design point of view) from within Servlet Container:
1. Extend javax.servlet.HttpServletResponseWrapper and override getWriter() / getOutputStream() methods to provide your own buffered versions (e.g. StringWriter)
2. Invoke "include()" method of RequestDisparcher, wrapping original response in your own.
3. Grab buffer's content.
Now if you need to do the same thing outside Servlet Container, you really need to ask yourself "why?". Perhaps you should be using a template engine (FreeMarker / Velocity / StringTemplate / etc...) instead of JSPs? If your JSPs are well-formed XML files and are not using any java code inserts it may be reasonably trivial to convert them to FreeMarker templates (FreeMarker supports custom JSP tag libraries) which would greatly simplify your task.
Nevertheless, if it's an absolute hard requirement your most straightforward options are:
1. Run an external Servlet Container and let it handle JSP interpretation. Your program would submit HTTP requests to it and capture the output.
2. Same as above, but you can run embedded Servlet Container (e.g. Jetty).
If your JSPs are available at build-time you can precompile them via Jasper as suggested in other answers.
I would strongly advice against trying to implement your own servlet container - you'll be walking into a world of hurt.
You will need a container. A JSP is an abstraction on Servlet. Servlets have a dependency on a life cycle provided by a container.You need a container to provide the life cycle.
This is possible without a servlet container. There are two steps to it.
The first is to generate the source code. If you look at the source code of the jspc ant task it is possible to do it directly in code. Or you could just invoke the ant task.
The code that is generated is just a Servlet and it is possible to invoke the methods on a servlet outside of a container:
Just instantiate it and then call doGet(request, response). I'm not sure exactly what you need this for but your life will be made easier using spring mock objects for the http request and response.
This will populate the Response object. you can then get the output with:
res.getContentAsString();
See an example here:
http://ytreyvus.blogspot.com/2007/03/private-void-cloneplaneffectrelationshi.html
Try MockRunner to execute it. You'll need to compile the JSP first, though. I'm using Maven 2 for this (and the JSP Compiler plugin)