1. Introduction to the problem:
There are various possible ways to solve the problem, some major requirements are however:
1. To write a software application
2. To make it transfer the Webservice over the Internet
3. A Servlet is to be copied to the Webapps directory of Tomcat
Some of the ways to solve the problem are:
1. Development of additional software for the server (beside of Tomcat) for the data transfer
2. Development of a Webservice to be placed inside Tomcat for the data transfer
3. Use of Tomcats WWW Management Interface for the data transfer
All three approaches are practicable.
However, the first two approaches require additional software which is to be installed beforehand. The third approach only needs a running Tomcat Application Server on the remote machine.
Therefore the way to go, which is described in this article is "just" to utilize Tomcats WWW Management Interface in software. This approach is very versatile, but has also many pitfalls, and various considerations are necessary. The proposed approach is suitable for one ore more webservices. If in the following only one is mentioned, it also means that more could be in place.
This article does not provide an exhaustive description for solving the problem, but is meant to give some guidance to avoid some of the major problems encountered by solving this task.
2. Requirements
There are two basic requirements:
- An already developed and packaged Webservice
- A properly set up server running Apache Tomcat
An introduction into Webservices would exceed the scope of this article, some previous knowledge is required. It should be noted however, that there are two major ways to use Webservices with the proposed approach. One is to create a Webservice (for example using JAX-WS) and pack it into a .war archive (this is a .jar archive renamed to .war) which is then to be deployed, the other is to use a dedicated Webservice engine (Apache Axis2 can be used with Tomcat) together with a Webservice, and these are then to be packed into a .war archve containing both, which is then to be deployed. For details on compatibility and packaging Webservices (for Axis2 you would package .aar files, these are .jar archives renamed to .aar) into an engine see its documentation.
[Note: The .jar files are incompatible with .zip!]
Another basic requirement is a running Apache Tomcat. For Linux as an OS this is a simple task: Only the login credentials are to be set. For MS-Windows there is some additional work necessary: As of Tomcat Version 6.0.18 the parameters "antiJARLocking" and "antiResourceLocking", both (!) must be set, otherwise an undeployment would fail. For details on configuration and possible drawbacks see the Apache documentation.
3. Compression (in Java)
To execute a tool like Jar (from the JDK) directly from Java issue the following code:
Process p1 = Runtime.getRuntime().exec("CommandLineToBeExecuted");
Don't forget to wait (!) until the command is finished:
BufferedReader input1 = new BufferedReader(new InputStreamReader(p1.getInputStream()));
String line1;
while ((line1 = input1.readLine()) != null) {/*Must wait for the program to finish*/}
input1.close();
4. Programmatically accessing Tomcats WWW Management Interface
Accessing a Web Interface programmatically means to execute "clicks" on links or to start a file upload from a software. Various APIs exist for accessing an interface over HTTP. In Java the java.net.HttpURLConnection is sufficient. As the upload address "http://TomcatHost:8080/manager/html/upload" is to be used. In general it is necessary "to repeat" what would be otherwise performed by a web browser.
The exact procedures would again exceed the scope of this article. However lots of sample code is available on the net. The following description outlines some adaptations necessary to work with Tomcat:
For uploading a .war archive
- Create an HttpURLConnection to the upload address
- Set several properties, some of which are
- "Log in"
# conn.setRequestProperty("Authorization", "Basic " + new BASE64Encoder().encode(loginString.getBytes())); //loginString has the format: "name:password"
- Make sure the "RequestMethod" is "POST"
# conn.setRequestMethod("POST");
- Assemble the data to be send; See various resources on the net.
- Make sure the Content-Disposition is something like that: "Content-Disposition: form-data; name=\"deployWar\";" + " filename=\"" + "foo.war" + "\"" + "\r\n"
Using something different than exactly "deployWar" may lead to failure
- For authentication the "BASE64Encoder" is necessary. The undocumented "sun.misc.BASE64Encoder" should not be used. However one could copy the files "BASE64Encoder" and "CharacterEncoder" from the OpenJDK sources to gain the same functionality.
For following or executing ("clicking") links the procedure is very similar, but
- Use "GET" instead of "POST"
- Don't use multipart content type any more
- Use the URL that is to be "clicked"
The execution of links gives lots of management possibilites. The most important are
List of running Servlets:
[http://TomcatHost:8080/manager/html/]
Undeployment:
[http://TomcatHost:8080/manager/undeploy?path=/foo]
With the latter the deployed Servlet can be undeployed.