Deploying Java Application As Servlet - java

I have a java application that up until now was run as a stand alone java application (i.e. executable jar). I now need to deploy it in Tomcat as a servlet. It doesn't need to actually process any HTTP requests though, but it needs to be started using tomcat.
What are the steps required to convert the project so that it can be deployed in Tomcat? I'm using maven as a build tool and Java 1.5.

I understand that you want to run this app on server's startup. The best way would be implementing ServletContextListener and run the app in the contextInitialized() method. E.g.
public class Config implements ServletContextListener {
private YourApp yourApp;
public void contextInitialized(ServletContextEvent event) {
yourApp = new YourApp();
yourApp.start();
}
public void contextDestroyed(ServletContextEvent event) {
yourApp.shutdown();
}
}
Register this in web.xml as follows:
<listener>
<listener-class>com.example.Config</listener-class>
</listener>
That's it. No need to wrap it in flavor of a HttpServlet as you aren't going to fire HTTP requests on it.
You however need to ensure that it runs in its own thread, otherwise it would block the startup. If it doesn't, then wrap it in a Runnable and execute it using ExecutorService.

I'm assuming that your app is continuously running and you have an app/web server already (e.g. Tomcat/Jetty), such that it's making your life easy to deploy into it. Given that, you need to:
extend an AbstractHttpServlet class and in particular the init() method. This would start your app.
build a web.xml that references this and sets the load-on-startup attribute to 1 (or at least non-zero)
build a .war from this and deploy it
Step 2 ensures that the init() method is called upon deployment/server reboot, and so you don't have to respond to HTTP requests (a normal startup trigger for a servlet).
It may be simpler and more appropriate to use something like javaservicewrapper, and wrap it up to be a Windows service or similar.

Related

How to recognise in Java when web project is deployed?

I have a simple web project which changes a line of text with another at the click of a button. What I want is a core Java method which will recognise when the .war file is deployed on the Tomcat server.
I want to output the exact time when the deployment happens. I have the code ready for that, and I want it to be in core Java.
Is there any such method that will allow me to perform some activity when the deployment happens?
You can use a ServletContextListener.
Add a <listener> tag in your web.xml file as follows:
<listener>
<listener-class>classes.MyListener</listener-class>
</listener>
And make a Java class implement the ServletContextListener interface. Overriding the contextInitialized() method and writing your code in it will do the trick.
For example:
package classes;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.joda.time.DateTime;
public class MyListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Project deployed: " + new DateTime());
//or any other form of output
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Project undeployed: " + new DateTime());
//or any other form of output
}
}
Hope this helps!
Look to see if the WAR file has been unzipped (exploded) in the webapps directory. This itself can be done two different ways, by looking to see if the exploded directory is there. Or by looking at the access time of the WAR file. Please note to see the access time of a file in *nix you have to use the -u option in the ls command.
But this has a flaw in the you cannot tell when the webservice has finished initializing. For that you can create a keepAlive service that you can poll in your webservice. That way when your application is done initializing you will get a response from the keepAlive. You can set a high loadnumber on this service to allow all the other Servlets to load first.
curl "http:localhost:8080/MyWebService/keepAlive"
Furthermore, I know specifically with Tomcat you can query its JMX monitor. I do not know if it has a JMX query to list out loaded Servlets, but it might and it is extensible so you can add your own queries for finding that out.
EDIT: You can also setup your Servlet to log when it is done initializing. Then just grep "your services' log msg" in a loop till it exits with exit code 0.

How to kill non-daemon threads created by library when quitting?

My application is running in tomcat, every time I stop tomcat it warns me there are lots of threads fail to shutdown. These threads are created by libraries my application use, I have no idea how to kill them. This issue leads tomcat process still live after I call bin/shutdown.sh shipped with tomcat.
can anybody help? thanks
Those libraries should also expose corresponding "shutdown", "stop", etc. methods you will need to call. Check their respective documentations or source.
You can also use jConsole or VisualVM to see what threads are alive after you try to shutdown your machine. If you're lucky your libraries will name them intelligently (RMQ doesn't by default, for instance), and you can tell what's left.
You can use a class that implements ServletContextListener and annotate it with #WebListener() (or indicate it's a listener in web.xml for earlier versions of Tomcat).
The interface has two methods contextInitialized and contextDestroyed where you can - in your implementation - do initialization and cleanup of any libraries or classes that might be spawning threads or otherwise need special tending. A Java Servlet Container like Tomcat will call both of the methods as part of a webapps start/stop life-cycle. Example:
#WebListener()
public class RestartListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
//some initialization code here
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
MemcachedManager.shutdown();
}
}

Deploying Terminal Base Java Application

I'm migrating from .net to java and I'm not yet used in java application deployment. I'm used in deploying console base application that acts as a stand alone application , a mixed of tcp and udp servers with custom protocol.
I have a requirement that my ported .net application to java must be deployed inside tomcat or glass fish ( no embedding stuff ). I really don't know what technology I must used. I've been searching the net but my understanding is that tomcat is like IIS and for web application only and glass fish is somewhat an application server for hosting web application too. Can I really run my java console base application inside tomcat or glass fish? Can someone point out a good tutorials for this kind of stuff? Thanks!
EDIT 1
Ok got the reason why I need to deploy my app in tomcat/glassfish. I need to provide a web ui for my application since I'm currently using the console for user input. Now my application will not just support a custom tcp/udp server inside but also web functionality for management. Any suggestion how I can implement this is greatly appreciated, I just don't know yet what java api/technology to start with.
I am not sure why your requirement says that you need to run an application using a servlet container . I don't think at least based on your description your application fits servlet container programming model.
As long as you create an entry point, I think you can launch your application from command line either using java or javaw,
But If you are unable to change the requirement on the deployment to tomcat, You can do this by using a servlet to launch your application, I would read up on these things
Servlet
Deploying Servlet to tomcat
Here is one way you could do using a servlet and deploy this to tomcat
public class LaunchServlet extends HttpServlet
{
private static final long serialVersionUID = 4277145689972356257L;
//this method is run as tomcat starts up this servlet
public void init() throws ServletException
{
try
{
System.out.println("Launching my application...");
new Thread(new ApplicationLauncher()).start();
System.out.println("Launched my application successfully. ");
}
catch(Exception e)
{
throw new RuntimeException("Fail Fast: Unable to launch exception.");
}
}
class ApplicationLauncher implements Runnable
{
public void run()
{
//start you applicaton here
}
}
}

Spring: Is there a simple non-web tutorial?

I'm attempting to create a Spring application (NOT web application) to perform some simple tasks. Eventually they will hook up with some other Spring apps around the network, but for now I'm keeping it simple. I have a CheckForNewItems class (extending Timer) which is configured to run every 10 seconds.
I can confirm it runs by calling it programmatically:
public class Tester {
public static ApplicationContext context;
private void loadContext() {
String filename = "beans.xml";
context = new FileSystemXmlApplicationContext(filename);
}
public static void main(String[] args) {
Tester test = new Tester();
test.loadContext();
CheckNewItemsTask task = (CheckNewItemsTask)context.getBean("checkNewItemsTask");
}
}
Running this works as expected, task.run() gets called every 10 seconds. Now I need to work out how to deploy this to either a JBoss or Tomcat server, in such a way that it automatically starts running the task.
Most of the tutorials I've found only describe how to get Spring MVC and servlets running, not a standalone application. Does anyone know better?
Cheers, Rob.
You don't need JBoss or Tomcat to do that. If the app is headless and you have no intention of adding a UI, consider jsvc for unix or procrun on windows. If you need the ability to monitor and control an app and do not need a proper UI for doing that, you might want to look at JMX. This will work on a daemon without the rest of the Java EE stack.
If you have a maven project and want an easy way to turn it into a deployable daemon app, you can use maven appassembler to automate the process of creating a deployable daemon, setting up a directory structure of the app, scripts to start and stop, libraries and config files.
You need a servlet that is set to autostart on deployment. The servlet can then call into your "Tester" class to trigger your "standalone" initialization process.
If you don't have a servlet (or potentially some other server related process) reference your code, then your initialization process will never be run.

Start / stop a web application from itself?

I've made a web application using Java, Struts and running over Apache Server and Tomcat. It would be very useful to be able to restart the application from the web. I don't want to restart Tomcat, only this webapp, the same way as Tomcat Manager does it.
Do you know how can I do it? If not, any way to simulate that behaviour (reload config.properties, make Hibernate init process, etc)?
Thank you a lot.
I took a quick look at the source code for the Tomcat Manager. It looks like there's a class that's part of the Tomcat source called "Container Servlet". From the javadocs:
A ContainerServlet is a servlet
that has access to Catalina internal
functionality, and is loaded from the
Catalina class loader instead of the
web application class loader.
A ContainerServlet automatically gets passed a wrapper that can be used to get the Context and Deployer -- and the Deployer has helpful methods such as start(String contextPath) and stop(String contextPath) that will do what you want.
So, what I think you would need to do is write your own servlet that inherits from ContainerServlet, and configure Tomcat to load your servlet using the Catalina class loader (look at how the Manager is configured to see how). Note that this is probably not going to be an option for you in a hosted environment.
Then your servlet could have, say, a button you press to reload the application. I recommend putting password-protection of some kind in front of that. :)
Just hit the URLs
http://<username>:<password>#<hostname>:<port>/manager/stop?path=/<context path>
to stop and
http://<username>:<password>#<hostname>:<port>/manager/start?path=/<context path>
to start. That simulates you using the manager application.
Tomcat Manager offers an http interface to start/stop an application and other tasks. There are Ant tasks that you can use to easily access these operations.

Categories