1 | | draft |
| 1 | {{{ |
| 2 | #!html |
| 3 | <a name="N1000C"></a><a name="My+Notes"></a> |
| 4 | <h3>My Notes</h3> |
| 5 | <div> |
| 6 | <p> |
| 7 | Many people ask questions about Java Mapscript on <em>mapserver-users</em>. This is an attempt |
| 8 | to record my answers to them, my impressions on mapserver and Java Mapscript. |
| 9 | Before you proceed I must warn you that the following are my opinions and |
| 10 | they might not be endorsed or approved by the mapserver community at all. |
| 11 | </p> |
| 12 | <p> |
| 13 | Most of this is <strong>LINUX</strong> specific, but some is general. |
| 14 | </p> |
| 15 | </div> |
| 16 | |
| 17 | <a name="N1001F"></a><a name="Building+Java+Mapscript"></a> |
| 18 | <h3>Building Java Mapscript</h3> |
| 19 | <div> |
| 20 | <p> |
| 21 | Guidelines for building a working Java Mapscript. |
| 22 | </p> |
| 23 | <a name="N10028"></a><a name="The+Golden+Rule:+KISS!+(Keep+it+simple,+stup^H^H^H^sir!)"></a> |
| 24 | <h4>The Golden Rule: KISS! (Keep it simple, stup^H^H^H^sir!)</h4> |
| 25 | <div> |
| 26 | <p> |
| 27 | Mapserver is really a big piece of software with plenty of functionalities (some say it is the most advanced web |
| 28 | mapping software) and chances are you do need all of them. If you are a newbie to mapserver |
| 29 | or to Java mapscript try to understand what you need and stick with it, removing the unneeded features. |
| 30 | <br /> |
| 31 | This approach is generally suggested because: |
| 32 | </p> |
| 33 | <ul> |
| 34 | |
| 35 | <li>it reduces the number of lines of code involved and thus reduces the number of possible |
| 36 | bugs that could bite</li> |
| 37 | |
| 38 | <li>it makes for a smaller binary which is more efficient</li> |
| 39 | |
| 40 | <li>in case of a crash the number of suspects is lower and will speed up investigation |
| 41 | and in some cases resolution</li> |
| 42 | |
| 43 | <li>it requires less software to be installed on your computer which makes it easier to |
| 44 | mantain in the long term</li> |
| 45 | |
| 46 | <li>the first three items apply (with recursion) to the previous</li> |
| 47 | |
| 48 | <li>if you ask for help on the mailing list the first general advice is to remove components you |
| 49 | don't use: so do it in advance</li> |
| 50 | |
| 51 | </ul> |
| 52 | <p> |
| 53 | See <a href="#compile">below</a> for a example of a basic (but working) mapserver/mapscript build example. |
| 54 | </p> |
| 55 | </div> |
| 56 | <a name="N10050"></a><a name="How+do+I+disable+option+X?"></a> |
| 57 | <h4>How do I disable option X?</h4> |
| 58 | <div> |
| 59 | <p> |
| 60 | Chances are that even if you do not need tiff or mysql support it will get built in anyway |
| 61 | because the configure script detects their libraries. In all cases you should review |
| 62 | the output of the configure script and then use the proper command line argument to disable unwanted |
| 63 | features. |
| 64 | </p> |
| 65 | <p> |
| 66 | When running the <em>./configure</em> program use the |
| 67 | <em>--disable-X</em> option. You can get the list of available options by running: |
| 68 | </p> |
| 69 | <pre class="code">./configure --help<br /> </pre> |
| 70 | </div> |
| 71 | <a name="N10068"></a><a name="Know+your+enemy"></a> |
| 72 | <h4>Know your enemy</h4> |
| 73 | <div> |
| 74 | <p> |
| 75 | Certain libraries/features are known <strong>NOT</strong> to work with mapscript because they are not thread-safe. |
| 76 | Be sure not to enable them at compile time or you will get errors that will crash the JVM. |
| 77 | You can review the list of unsafe components <img src="/images/link-ext.gif" align="middle" /><a href="../../faq/thread_safety">here</a>. |
| 78 | </p> |
| 79 | </div> |
| 80 | <a name="N10079"></a><a name="Know+your+enemy+(part+2:+gdal+and+tiff)"></a> |
| 81 | <h4>Know your enemy (part 2: gdal and tiff)</h4> |
| 82 | <div> |
| 83 | <p> |
| 84 | If you need raster support through GDAL disable tiff (using <em>--without-tiff</em>) because they don't play well |
| 85 | with each other. |
| 86 | </p> |
| 87 | </div> |
| 88 | <a name="N10086"></a><a name="Know+your+enemy+(part+3:+pdf)"></a> |
| 89 | <h4>Know your enemy (part 3: pdf)</h4> |
| 90 | <div> |
| 91 | <p> |
| 92 | PDF is supported as an output format, but it is not worth the price of risking a buggy mapscript. |
| 93 | A better solution is to incorporate the image in a PDF document by using a pure Java library like the excellent |
| 94 | <em>iText</em>. |
| 95 | </p> |
| 96 | <p> |
| 97 | By doing so you will be able to customize headers, footers, paper format and transparencies will also work as supposed. |
| 98 | iText additionally supports PDF encryption to disallow printing, editing or modification. |
| 99 | </p> |
| 100 | <p> |
| 101 | Also remember that PDF output in mapserver cannot make use of an embedded scalebar because pixmap |
| 102 | fonts are not supported. |
| 103 | </p> |
| 104 | </div> |
| 105 | <a name="N10099"></a><a name="Know+your+enemy+(part+4:+connection+pooling)"></a> |
| 106 | <h4>Know your enemy (part 4: connection pooling)</h4> |
| 107 | <div> |
| 108 | <p> |
| 109 | Connection pooling is locked hence thread safe, but as of version 4.8.x (that is until Feb 2006) |
| 110 | it has known memory leaks. There is an issue on bugzilla that tracks this problem with Oracle.<br /> |
| 111 | |
| 112 | <img src="/images/link-ext.gif" align="middle" /><a href="../../../bugs/show_bug.cgi?id=1662">http://mapserver.gis.umn.edu/bugs/show_bug.cgi?id=1662</a>. |
| 113 | </p> |
| 114 | <p> |
| 115 | Until that is cleared you can use connection pooling, just make sure that once in a while the application is |
| 116 | restarted or you will eventually run out of memory. How often this should happen depends on the number |
| 117 | of database connections defined in the map and the number of users. Sites with 1 or two database connections and |
| 118 | moderate to low use could reboot the application (that is the tomcat process in case of web apps) once a day. |
| 119 | </p> |
| 120 | <div class="frame note"> |
| 121 | <div class="label">Note</div> |
| 122 | <div class="content"> |
| 123 | There is no way to disable connection pooling. |
| 124 | </div> |
| 125 | </div> |
| 126 | <p> |
| 127 | |
| 128 | </p> |
| 129 | </div> |
| 130 | <a name="N100B2"></a><a name="Know+your+friends"></a> |
| 131 | <h4>Know your friends</h4> |
| 132 | <div> |
| 133 | <p> |
| 134 | Java Mapscript will <strong>NEVER</strong> work without the following configure flag: <em>--with-threads</em>. |
| 135 | Do not complain about you JVM going belly up on the mailing lists if you do not have enabled |
| 136 | this option. |
| 137 | </p> |
| 138 | </div> |
| 139 | <a name="N100C2"></a><a name="compile"></a> |
| 140 | <h4>The proper way to compile mapscript is...</h4> |
| 141 | <div> |
| 142 | <p> |
| 143 | To use mapserver and mapscript you will quite likely need to download and install |
| 144 | many other libraries and this might not particularly easy as most of |
| 145 | them (gdal, for instance) do not have a binary rpm for linux.<br /> |
| 146 | You have then to find, download all of them and install one by one, solving |
| 147 | dependencies by hand. If this is not what you want and need a more portable |
| 148 | ,reliable and easier to deploy environment you should seriously consider |
| 149 | <img src="/images/link-ext.gif" align="middle" /><a href="http://fwtools.maptools.org/">fwtools</a>. Fwtools is collection of the most popular |
| 150 | libraries used with mapserver already compiled and ready to run on almost |
| 151 | any linux distribution.<br /> |
| 152 | |
| 153 | <a href="#againstFwtools">This section</a> describes how to compile mapserver |
| 154 | and Java mapscript against fwtools. |
| 155 | </p> |
| 156 | <p> |
| 157 | The proper way to compile is to carefully select options as described above, then to run make, |
| 158 | cd into mapscript/java and run: |
| 159 | </p> |
| 160 | <pre class="code">make interface<br />make<br />make test<br /> </pre> |
| 161 | <p> |
| 162 | Make interface requires that you have <img src="/images/link-ext.gif" align="middle" /><a href="http://www.swig.org">swig</a> installed, at least version 1.3.21. |
| 163 | </p> |
| 164 | <p> |
| 165 | My configure options to build mapscript with support for raster (through gdal), truetype fonts (through freetype), |
| 166 | shape files (native, cannot be disabled), projection (through proj) are: |
| 167 | </p> |
| 168 | <pre class="code">./configure --with-freetype --without-tiff --with-gdal=/opt/gdal/bin/gdal-config --with-proj --without-pdf --with-threads<br /> </pre> |
| 169 | <p> |
| 170 | These are known to work (for me at least :-)) and are used in production sites. Note that proj, even |
| 171 | if it not used, is required for good operation of mapserver. |
| 172 | </p> |
| 173 | </div> |
| 174 | <a name="N100F2"></a><a name="againstFwtools"></a> |
| 175 | <h4>Compiling against fwtools</h4> |
| 176 | <div> |
| 177 | <p> |
| 178 | Download <img src="/images/link-ext.gif" align="middle" /><a href="http://fwtools.maptools.org/">fwtools</a> and install it. I usually install it in <em>/opt/FWTools-1.0.0b2</em>. |
| 179 | Cd into the lib subdirectory and run the following two commands: |
| 180 | </p> |
| 181 | <pre class="code">ln -s libpng.so.2 libpng.so<br />ln -s libfreetype.so.6 libfreetype.so<br /> </pre> |
| 182 | <p> |
| 183 | This is required for mapserver configure script to find and use the freetype |
| 184 | and png libraries shipping with fwtools. |
| 185 | </p> |
| 186 | <p> |
| 187 | Download latest mapserver and unpack it, then compile it with the following |
| 188 | configuration: |
| 189 | </p> |
| 190 | <pre class="code">./configure --enable-debug --with-threads --without-pdf --without-tiff \<br /> --with-gdal=/opt/FWTools-1.0.0b2/bin/gdal-config --with-proj=/opt/FWTools-1.0.0b2/ \<br /> --with-gd=/opt/FWTools-1.0.0b2 --with-freetype=/opt/FWTools-1.0.0b2 \<br /> --with-png=/opt/FWTools-1.0.0b2 --with-zlib=/opt/FWTools-1.0.0b2 --with-jpeg=/opt/FWTools-1.0.0b2<br /> </pre> |
| 191 | <p> |
| 192 | Before you run mapserver or mapscript make sure you load the fwtools environment by running |
| 193 | <em>/opt/FWTools-1.0.0b2/fwtools_env.sh</em>. |
| 194 | </p> |
| 195 | </div> |
| 196 | <a name="N10119"></a><a name="What's+the+deal+with+"></a> |
| 197 | <h4>What's the deal with make interface?</h4> |
| 198 | <div> |
| 199 | <p> |
| 200 | When I first used Java mapscript in 2003 running swig was a necessary prerequisite to |
| 201 | generate the Java and c wrapper files as the source distribution did not have any. There was a problem |
| 202 | though: swig would generate Java methods and c wrappers for all mapserver components (like postgis, wfs or ogr) |
| 203 | regardeless of the fact that they were enabled in the <em>configure</em> phase. |
| 204 | </p> |
| 205 | <p> |
| 206 | Then I submitted bug <img src="/images/link-ext.gif" align="middle" /><a href="../../../bugs/show_bug.cgi?id=876">#876</a> along with a patch which would |
| 207 | let swig know of which components were enabled and consequently generate Java and c wrappers only for them. |
| 208 | For the patch to work the user <strong>had to</strong> run make interface. |
| 209 | </p> |
| 210 | <p> |
| 211 | The problem then was that a rather new version of swig was required, which was not available on all distros |
| 212 | so the developers decided to provide a default version of the Java and c wrappers to help those who |
| 213 | did not have a recent swig (at least 1.3.21). That issue should be overcome by now as all |
| 214 | linux distros should ship with a swig version that is two years old! |
| 215 | <br /> |
| 216 | So, if you have a recent version of swig (run <em>swig -version</em> to know) you should run make interface |
| 217 | to update your Java and c wrappers, even if the README does not recommend it. |
| 218 | </p> |
| 219 | </div> |
| 220 | </div> |
| 221 | |
| 222 | <a name="N1013C"></a><a name="Running+Java+Mapscript+(on+Linux)"></a> |
| 223 | <h3>Running Java Mapscript (on Linux)</h3> |
| 224 | <div> |
| 225 | <p> |
| 226 | To correctly run any Java Mapscript application (be it a servlet, jsp page or a standalone graphical client) |
| 227 | you need to let the Java Virtual Machine know where to find two pieces of software: |
| 228 | </p> |
| 229 | <ol> |
| 230 | |
| 231 | <li> |
| 232 | |
| 233 | <em>libmapscript.so</em> whose role is to tie together mapserver and Java</li> |
| 234 | |
| 235 | <li> |
| 236 | |
| 237 | <em>mapscript.jar</em> which provides the mapserver Java objects which interface with libmapscript.so</li> |
| 238 | |
| 239 | </ol> |
| 240 | <p> |
| 241 | The location of the second must be specified on the classpath by means of the <em>CLASSPATH</em> environment variable |
| 242 | or the <em>-cp</em> option. The location of the first can be specified using the <em>LD_LIBRARY_PATH</em> variable or the |
| 243 | <em>-Djava.library.path</em> option. For an example see the <em>make test</em> command you ran after compiling mapscript. |
| 244 | </p> |
| 245 | <a name="N10166"></a><a name="Dealing+with+unresolved+dependencies"></a> |
| 246 | <h4>Dealing with unresolved dependencies</h4> |
| 247 | <div> |
| 248 | <p> |
| 249 | If your Java application brings up an error like the following: |
| 250 | </p> |
| 251 | <pre class="code">javac -classpath ./:examples/:./mapscript.jar -d examples/ examples/*.java<br />java -classpath ./:examples/:./mapscript.jar -Djava.library.path=. DumpShp ../../tests/point.shp<br />java.lang.UnsatisfiedLinkError: /opt-4.4.2/mapscript/java/libmapscript.so:<br /> libgdal.so.1: cannot open shared object file: No such file or directory<br />make: *** [test] Error 255<br /> </pre> |
| 252 | <p> |
| 253 | it means that the gdal library was not found by the linker: this is probably due to the fact that gdal |
| 254 | was not supplied by your Linux distro and you installed it from source. In this case you must find the directory |
| 255 | where <em>libgdal.so.1</em> is and then add it to the <em>LD_LIBRARY_PATH</em> or the <em>-Djava.library.path</em>. |
| 256 | </p> |
| 257 | <a name="N10180"></a><a name="Specifying+the+library+name"></a> |
| 258 | <h5>Specifying the library name</h5> |
| 259 | <div> |
| 260 | <p> |
| 261 | When the JVM attempts to load the shared library it will look by default for a file named <em>libmascript.so</em> |
| 262 | in one of the system directories or in those specified by <em>LD_LIBRARY_PATH</em> or <em>-Djava.library.path</em>.<br /> |
| 263 | If necessary one can tell the JVM to load a shared library with a different name by passing the following |
| 264 | argument to the <em>java</em> interpreter: <em>-Dmapserver.library.name=yourname</em>. For instance to load |
| 265 | an hypothetical library named libmapscript-debug.so: |
| 266 | </p> |
| 267 | <pre class="code">java -Dmapserver.library.name=mapscript-debug MyJavaProgram<br /> </pre> |
| 268 | </div> |
| 269 | </div> |
| 270 | </div> |
| 271 | |
| 272 | <a name="N101A2"></a><a name="Learning+Java+Mapscript"></a> |
| 273 | <h3>Learning Java Mapscript</h3> |
| 274 | <div> |
| 275 | <p> |
| 276 | If you got this far then by now you probably want to know how to do X in Java Mapscript? (replace X with query, zoom, etc). |
| 277 | </p> |
| 278 | <p> |
| 279 | To date there is not a tutorial, nor code that you can look at (besides the examples, but that's not much frankly), |
| 280 | so the best thing you can do is take the php mapscript example form the mapserver web site and <em>translate</em> it |
| 281 | to Java. This is how I did the first time and somehow it worked. |
| 282 | </p> |
| 283 | <p> |
| 284 | Additional documentation is in the mapserver sources in <em>mapscript/doc</em>. |
| 285 | </p> |
| 286 | <a name="N101B7"></a><a name="QueryByPoint+example"></a> |
| 287 | <h4>QueryByPoint example</h4> |
| 288 | <div> |
| 289 | <p> |
| 290 | The following is an example of a working code snippets that opens a layer and queries |
| 291 | its features by shape. It has been used succesfully against shape and postgis sources. |
| 292 | </p> |
| 293 | <p> |
| 294 | Note the usage of the <img src="/images/link-ext.gif" align="middle" /><a href="http://jakarta.apache.org/commons/logging/">commons-logging</a> api for debuggins the code. |
| 295 | </p> |
| 296 | <pre class="code">protected List queryLayerByPoint(int i, pointObj queryPoint) {<br /> List results = new ArrayList();<br /><br /> layerObj layer = map.getLayer(i);<br /> if (layer != null && isVisible(layer)) {<br /> if (log.isDebugEnabled()) {<br /> log.debug("Querying layer: " + layer.getName());<br /> }<br /> if (layer.queryByPoint(map, queryPoint,mapscript.MS_MULTIPLE, -1) == mapscript.MS_SUCCESS) {<br /> // OLD pre 4.2 code, see http://mapserver.gis.umn.edu/docs/howto/mapscript_querying<br /> //resultCacheObj resultCache = layer.ggetResultcache();<br /> if (layer.open() == mapscript.MS_SUCCESS) {<br /> // OLD pre 4.4 code<br /> //for (int j=0;j < resultCache.getNumresults();j++) {<br /> for (int j = 0; j < layer.getNumResults(); j++) {<br /> if (log.isDebugEnabled())<br /> log.debug("Layer " + layer.getName() + ", result number:" + j);<br /> resultCacheMemberObj resultMember = layer.getResult(j);<br /> shapeObj shape = new shapeObj(layer.getType());<br /> layer.getShape(shape,resultMember.getTileindex(), resultMember.getShapeindex());<br /> if (shape != null) {<br /> Map aResult = getResult(shape, layer);<br /><br /> results.add(aResult);<br /> } else {<br /> log.error("Shape " + j + " is null!");<br /> }<br /> }<br /> layer.close();<br /> } else {<br /> log.error("Cannot open layer: " + layer.getName());<br /> }<br /> } else {<br /> log.info("Query on layer " + layer.getName() + " failed.");<br /> }<br /> }<br /> return results;<br />}<br /> </pre> |
| 297 | </div> |
| 298 | </div> |
| 299 | |
| 300 | <a name="N101CE"></a><a name="What+to+do+if+mapscript+crashes"></a> |
| 301 | <h3>What to do if mapscript crashes</h3> |
| 302 | <div> |
| 303 | <p> |
| 304 | Make sure that you have done all I have suggested here, in particular review the list |
| 305 | of unsafe components. After that try to isolate the piece of code that is |
| 306 | failing: if you cannot do that because errors are random then look for a <em>hs_err*.log</em> somewhere |
| 307 | in your filesystem. That is the file that the JVM creates when a crash occurs. |
| 308 | </p> |
| 309 | <p> |
| 310 | The file should report a stack trace that will tell you more or less exactly where the crash happened. |
| 311 | Review that piece of code and eventually ask on the mailing list. Before you ask on the mailing list |
| 312 | gather all information that you have available and that will be useful to diagnose the problem. |
| 313 | A good report should include: |
| 314 | </p> |
| 315 | <ul> |
| 316 | |
| 317 | <li>Linux version (both kernel and distro). Can be obtained by running: <em>uname -a</em> |
| 318 | |
| 319 | </li> |
| 320 | |
| 321 | <li>GCC Version: <em>gcc --version</em> |
| 322 | |
| 323 | </li> |
| 324 | |
| 325 | <li>mapserver version and compile flags: run <em>mapserv -v</em> and/or report the configure flags</li> |
| 326 | |
| 327 | <li>Java version and vendor: <em>java -version</em> |
| 328 | |
| 329 | </li> |
| 330 | |
| 331 | <li>swig version (if used): <em>swig -version</em> |
| 332 | |
| 333 | </li> |
| 334 | |
| 335 | <li>support libraries used and their version: gdal, proj, curl, postgis, etc</li> |
| 336 | |
| 337 | <li>whatever you think could help</li> |
| 338 | |
| 339 | </ul> |
| 340 | <p> |
| 341 | Additionally some will definitely find telling the reading of the venerable guide: |
| 342 | <img src="/images/link-ext.gif" align="middle" /><a href="http://www.catb.org/%7Eesr/faqs/smart-questions.html">how to ask questions the smart way</a>. |
| 343 | </p></div> |
| 344 | }}} |