I am using MS4W (MapServer 4 Windows with Java Mapscript) - v 3.0.3 for a GIS web application hosted over Tomcat 6.0.33 with Java jdk1.6.0_13 and PostgreSQL 9.1 with PostGIS 1.5.2 @ the database end. The GIS application has polygon,line and point spatial layers.

The problem is that ms4w(MapServer) crashes the JVM & Tomcat very frequently for simple map functionalities such as pan, zoom-in and sometimes even at first time loading of the map. Attached is log file generated in E:\Program Files\apache-tomcat-6.0.33-for-ME\bin\ folder.hs_err_pid3848.log


Is the MapServer MS4W Java API thread safe? Will making the method declarations in edu.umn.gis.mapscript.mapscriptJNI or edu.umn.gis.mapscript.mapObj classes as synchronized effect the API adversely?

I did try marking all the method declarations as synchronized in the edu.umn.gis.mapscript.mapObj class and few methods such as mapObj_draw(..), mapObj_drawQuery(..), mapObj_drawLegend(..),mapObj_drawScalebar(..) and mapObj_drawReferenceMap(...) in edu.umn.gis.mapscript.mapscriptJNI class. This helped reduce the tomcat crashing issue.

Is there any particular way to create (thread-safe) mapObj and using it? I have a common mapObj with all its properties like mapHeight,mapWidth,boundingBox coords shared by different mapping functionality methods such as zoom-in,zoom-out,pan,fullExtent,etc.

Can anybody suggest me about the best way (thread-safe) to create and use the mapObj in MapServer Java Mapscript API?

  • you cannot share a given mapObj across multiple threads, is that what you are doing ? Nov 25 '13 at 10:35
  • I have the mapObj as property in a class called MapServerHelper with other properties such as mapHeight,mapWidth,dblMinx,dblMiny_geo,dblMaxx_geo,dblMaxy_geo,rectObj orgMapExtent,etc. The MapServerHelper class object i.e, msHelper is passed on to different map functionality methods such as pan(msHelper),zoomIn(msHelper),zoomOut(msHelper),fullExtent(msHelper) where the above properties are set or read. Say a thread from one request is doing zoomIn and another thread request comes in for pan at the same time the mapObj property is accessed by both the requests and tomcat crashes.
    – Shiva
    Nov 25 '13 at 12:11
  • Can you suggest a better way to create and use mapObj in a thread-safe way?
    – Shiva
    Nov 25 '13 at 12:12

I have no direct experience with MS4W but Mapserver can be used safely in threaded environments, provided that some simple precautions are taken.

For a starting checklist consult the Mapserver FAQ, which has an entry just for thread safety. I have used successfully Java mapscript myself in many web apps.

By looking at MS4W build notes it seems like thread safety ought to be supported, but you can check for yourself as follows:

locate mapserv.exe, then execute it in a command prompt with the -v option. It should report the features that have been enabled at build time, something like the following:

  mapserv -v    

Look for SUPPORTS=THREADS in the output.

That being said as Thomas pointed out you must not use or reuse Mapscript objects across requests: you should create a new set of mapscript objects with every request and then be done with it.

From a performance point of view there is no significant overhead, but the latter approach is critical for stability.

Just search the mailing lists for java mapscript, you should find plenty of references.

  • Thanx for replying back. I am not sharing the same mapObj across multiple requests/threads, instead msHelper.getMap().cloneMap() to create a new mapObj. Following is the method which is called by different mapping functions such as zoomIn, zoomOut, pan, fullExtent, etc.
    – Shiva
    Nov 26 '13 at 12:05
  • public synchronized void createImage(MapServerHelper msHelper) throws Exception { try { System.gc(); File f=new File(msHelper.getStrImageSavePath()); if(f.exists()==false) { f.mkdirs(); } mapObj newmap=msHelper.getMap().cloneMap(); imageObj image=newmap.drawQuery(); long now=System.nanoTime(); String strFileName="\\map"+now+"."+msHelper.getStrImageExt(); String strLegendFileName="";
    – Shiva
    Nov 26 '13 at 12:07
  • try { imageObj legendimage=newmap.drawLegend(); strLegendFileName="\\legendmap"+now+"."+msHelper.getStrImageExt(); legendimage.save(msHelper.getStrImageSavePath() + strLegendFileName, newmap); } catch (Exception e) { MapHelper mapHelper=new MapHelper(); mapHelper.copyfile(msHelper.getStrRealPath()+"/legend-error.png",msHelper.getStrImageSavePath()+strLegendFileName); } image.save(msHelper.getStrImageSavePath()+strFileName,newmap); strFileName=strFileName.substring(1,strFileName.length()); . . . .
    – Shiva
    Nov 26 '13 at 12:08
  • Stacktrace of D:/Program Files(x86)/apache-tomcat-7.0.41/bin/hs_err_pid4536.log mentions the following Problematic frame: # C [orageneric11.dll+0x3c2e42] Java frames: j edu.umn.gis.mapscript.mapscriptJNI.mapObj_drawQuery(JLedu/umn/gis/mapscript/mapObj;)J+0 j edu.umn.gis.mapscript.mapObj.drawQuery()Ledu/umn/gis/mapscript/imageObj;+5 j com.mapserver.util.MapServerExecutor.createImage(Lcom/mapserver/util/MapServerHelper;)V+36 j com.mapserver.util.MapServerExecutor.pan(Lcom/mapserver/util/MapServerHelper;DD)Z+81 tomcat crashes in mapscriptJNI.mapObj_drawQuery method.
    – Shiva
    Nov 26 '13 at 12:13
  • you should also not use cloneMap, create a new one with its contructor every time.
    – unicoletti
    Nov 26 '13 at 14:42

To avoid thread issues, you can create all mapserver objects inside the given method, if using it in a servlet.

Mapserver Java binding(SWIG) it not very safe for use. Missing to set some properties on objects, like layer type, can push you into some of those crashes.

You can try check for Mapserver Error instances benn throw in a catch block. This will be your last chance to log some mapserver reported message.

try {

catch ( Error mapserverError )


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.