Personal tools
You are here: Home Documentation How-tos

JavaMapscript on Tomcat 5.5

Document Actions
This how-to explains how to setup JavaMapscript on Apache Tomcat 5.5.x

When developing J2EE web-applications is generally desired to deploy the entire application in a single WAR file containing all assets and required non-standard resources, such as additional libraries and drivers etc.:

 

  •  JFreeChart
  • Batik (required by JFreeChart for SVG charts)
  •  Struts and all its dependant libraries.
  •  PostgreSQL Jdbc driver
  •  PostGIS

 

All of these are 100% implemented in Java and can therefore be deployed within the context (In J2EE a web-application is referred to as Context). JavaMapscript however is a wrapped native library and accessed via JNI (Java Native Interface). In Java native libraries can only be loaded once for a particular JVM instance. Since all contexts within a J2EE container (application server e.g. Tomcat) share the same JVM, attempting to load the same native library from a different context (or even the same context, if that context had been reloaded), would cause the native library to crash, as each context has its own ClassLoader who has no way of knowing that the library has already been loaded by a different context / class loader. To overcome this problem, Mapscript must be deployed separately from the context and installed in either the common or shared global context of the server (see Tomcat 5.5 Directory Structure below). Attempting to load a class or library from the shared context will cause it to be loaded through the shared class loader. This alone still not sufficiently resolves this issue.

 

Tomcat 5.5 Directory Structure
CATALINA_HOME
├───bin
├───common
├───conf
├───logs
├───server
├───shared
│   ├───classes (MapscriptLoader.class)
│   ├───lib (mapscript.jar)
│   └───mapscript (*.dll, *.so)
│       ├───fonts (*.ttf)
│       ├───nad
│       └───symbols (*.sym, *.gif, *.png)
├───temp
├───webapps
│   ├───ROOT
│   └───cis (*.jsp, *.jspf, *.css)
│       ├───admin (*.jsp)
│       ├───images (*.gif, *.jpg, *.png)
│       ├───javascript (*.js)
│       ├───layercontrol (*.jsp)
│       ├───map (*.map)
│       ├───META-INF (context.xml)
│       ├───ms_tmp (*.gif)
│       └───WEB-INF (*.xml, *.tld)
│           ├───classes (*.class)
│           └───lib (*.jar)
└───work

 

A separate class is required to load the actual native library. The loadLibrary statement must be either be contained in a singleton pattern or placed in a static block The solution provided by Umberto Nicoletti uses the former, but this example uses a static block instead, as this is easier to use and less error prone, because loading the native library within a static block located in the class definition will automatically ensure that the System.loadLibrary statement is only ever executed once without having to perform addition checks as necessary with a Singleton. Furthermore this method allows loading the library in the same manner most drivers are loaded in Java via Class.forName:

 

public class MapscriptLoader
{
   
static {
     
   try {
     
       System.loadLibrary("mapscript"); //load native library
         System.out.println(" * mapscript native library loaded *");
     
   } catch (Exception e) {
             System.err.println(" * error loading native library *");
 
           System.err.println("Error is: " + e);
             e.printStackTrace();
      
 }
}
}

 

In order for the JVM to successfully load the Mapscript library, the mapscript.dll (or mapscript.so under Linux) must be located on the search path. To set the PATH environmental variable during the start-up of Tomcat the bin/setenv.bat (setenv.sh) batch/shell file must contain the following lines (Windows only):

 

SET PATH=%PATH%;%CATALINA_HOME%\shared\mapscript
SET PROJ_LIB=%CATALINA_HOME%\shared\mapscript\nad

 

The PROJ_LIB variable is required by mapscript.dll to locate the directory containing the projections definitions. 

 

This MapscriptLoader class can now be loaded from within any context without crashing the JVM:

try { 
    Class.forName("MapscriptLoader");
} catch(Throwable t) { t.printStackTrace(); }

This How-to applies to: MapServer 4.4, MapServer 4.6

by Daniel Caldeweyher last modified 2005-12-12 14:04
Contributors: Daniel Caldeweyher

Loading library

Posted by Ajay Ranipeta at 2005-06-29 08:00
When developing web-apps, Mapscript/Java (mapscript.jar) automatically loads dll file, so you don't have to statically load it again. Ofcourse, you still have to when developing a desktop-based app.

If you are stuck, for example, with errors like "Dependent libraries not found", then make sure there are no multiple references in your System CLASSPATH and PATH environment variables (not the USER env. vars).

Here is a good "things to do" that I followed (thanks to Umberto), to get started (or fix-up rather):

0) clean up windows: remove old installs of mapserver and system32
libraries from this install. Start with a fresh system if you can
1) clean the environment from all possible references to
mapserver/gdal/etc libraries
2) create a c:\mapserver directory and copy all mapserver dlls in there
3) add a **system** (not user!!) PATH entry to c:\mapserver
4) if you can run the java mapscript tests (make test in mapscript/java)
4) install java and tomcat and make sure they work
5) install the webapp and dependent jars/classes in shared/lib and
shared/classes. Please note that as of recent versions of mapscript
the native library is loaded by mapscript.jar already, so there is no
need to provide a static method
6) edit catalina.bat and add -Djava.library.path=c:\mapserver [With tomcat 5.x, you can easily edit this with the CATALINA MONITOR, esp. with 5.5+, you don't necessarily have the *.bat files.]
7) run tomcat

Good-luck

Loading libmapscript.so

Posted by Umberto Nicoletti at 2006-05-26 02:24

Since mapserver 4.6 it is not necessary to load the shared library because the mapscript.jsr already takes care of it. Just drop mapscript.jar in TOMCAT_HOME/common/lib (for tomcat 4.x).


Powered by Plone