Melissa Data Notes

Russell Bateman
September 2020

Melissa Data may have been at some point named Melissa DATA.

Melissa Data Address Verification and GeoCoder

Validate, standardize and format U.S. and global addresses in real-time.

Approximately 20% of addresses entered online contain errors—spelling mistakes, wrong house numbers, incorrect postal codes, formatting errors that don’t comply with a country’s postal regulations.

Melissa's Global Address Verification service verifies addresses for 240+ countries and territories at the point of entry and in batch to ensure only valid billing and shipping addresses are captured and used in your systems.

Melissa GeoCoder solutions convert addresses into geocodes (latitude and longitude coordinates), which can be used to place markers on a map or position the map. Precise rooftop geocodes for 95% of all physical addresses in the U.S. as well as 240 countries around the world are offered. Unique-address parsing and matching algorithms help GeoCoder fix spelling errors and complete addresses that have missing or invalid components to provide more precise results.

A decade ago, at Hewlet-Packard Snapfish, I used something called AddressDoctor (now from Informatica) to perform address verification and correction. Today, however, I am setting up Melissa Data GeoCoder for converting addresses into geocodes (latitude and longitude coordinates), and to perform corrections.

These notes are about setting up and using Melissa Data GeoCoder. Melissa Data Address works similarly.

On-premises installation

Under contract, you can use an on-site installation that's updated periodically. It's a roughly 8Gb installation. To reach the download, you are given a URL by the account executive you work with, something that looks like this:

There is a demonstration version that, installed, will geocode locations in Nevada. You will need a valid license string to make it do more, something like:


If all goes well, you'll see this:

russ@gondolin ~/dev/md $ ll
total 13608252
drwxrwxr-x  2 russ russ        4096 Sep  5 10:21 .
drwxrwxr-x 46 russ russ        4096 Sep  5 10:12 ..
-rw-rw-r--  1 russ russ 13934836456 Sep  5 10:21

I'm letting some of the download files that are most important to me (Linux, Java and Python) show below as I explode the zip:

russ@gondolin ~/dev/md $ unzip
  inflating: Changes.txt
   creating: linux/
   creating: linux/gcc34_32bit/
  inflating: linux/gcc34_32bit/geo_sample.cpp
  inflating: linux/gcc34_32bit/
  inflating: linux/gcc34_32bit/makefile
  inflating: linux/gcc34_32bit/mdEnums.h
   creating: linux/interfaces/
   creating: linux/interfaces/java/
  inflating: linux/interfaces/java/
  inflating: linux/interfaces/java/
  inflating: linux/interfaces/java/README.txt
  inflating: linux/interfaces/java/
   creating: linux/interfaces/java/com/
   creating: linux/interfaces/java/com/melissadata/
  inflating: linux/interfaces/java/com/melissadata/mdGeo$AccessType.class
  inflating: linux/interfaces/java/com/melissadata/mdGeo$AliasPreserveMode.class
  inflating: linux/interfaces/java/com/melissadata/mdGeo$AutoCompletionMode.class
  inflating: linux/interfaces/java/com/melissadata/mdGeo$DiacriticsMode.class
  inflating: linux/interfaces/java/com/melissadata/mdGeo$MailboxLookupMode.class
  inflating: linux/interfaces/java/com/melissadata/mdGeo$ProgramStatus.class
  inflating: linux/interfaces/java/com/melissadata/mdGeo$ResultCdDescOpt.class
  inflating: linux/interfaces/java/com/melissadata/mdGeo$StandardizeMode.class
  inflating: linux/interfaces/java/com/melissadata/mdGeo$SuiteParseMode.class
  inflating: linux/interfaces/java/com/melissadata/mdGeo.class
  inflating: linux/interfaces/java/com/melissadata/
  inflating: linux/interfaces/java/com/melissadata/mdGeoJavaWrapperJNI.class
  inflating: linux/interfaces/java/com/melissadata/
  inflating: linux/interfaces/java/
  inflating: linux/interfaces/java/mdGeo.jar
  inflating: linux/interfaces/java/mdGeoJavaWrapper.cpp
  inflating: linux/interfaces/java/mdGeoJavaWrapper.o
   creating: linux/interfaces/python/
  inflating: linux/interfaces/python/
  inflating: linux/interfaces/python/
  inflating: linux/interfaces/python/
  inflating: linux/interfaces/python/mdGeoPythonWrapper.cpp
  inflating: linux/interfaces/python/
  inflating: linux/interfaces/python/readme.txt
  inflating: md5.txt
  inflating: mdGeoRef.pdf
  inflating: readme.txt
  inflating: setup.exe
  inflating: windows/samples/dll_64bit/mdEnums.h
  inflating: windows/samples/dll_64bit/mdGeo.dll
  inflating: windows/samples/dll_64bit/mdGeo.h
  inflating: windows/samples/dll_64bit/mdGeo.lib
russ@gondolin ~/dev/md $ ll
total 13609624
drwxrwxr-x  9 russ russ        4096 Sep  5 11:49 .
drwxrwxr-x 46 russ russ        4096 Sep  5 10:12 ..
drwxrwxr-x  5 russ russ        4096 Jul 15 12:00 aix
-rwxrw-r--  1 russ russ        1031 Jul 15 12:00 Changes.txt
drwxrwxrwx  2 russ russ        4096 Jul 15 12:00 data
drwxrwxr-x  5 russ russ        4096 Jul 15 12:00 extras
-rw-rw-r--  1 russ russ 13934836456 Sep  5 10:21
drwxrwxr-x  6 russ russ        4096 Jul 15 12:00 hpux
drwxrwxr-x  7 russ russ        4096 Jul 15 12:00 linux
-rw-rw-rw-  1 russ russ       28542 Jul 15 12:00 md5.txt
-rwxrw-r--  1 russ russ      696810 Jul 15 12:00 mdGeoRef.pdf
-rwxrw-r--  1 russ russ        2582 Jul 15 12:00 readme.txt
-r-xr-xr-x  1 russ russ      346176 Jul 15 12:00 setup.exe
-r-xr-xr-x  1 russ russ       77388 Jul 15 12:00
-r-xr-xr-x  1 russ russ      207871 Jul 15 12:00
-r-xr-xr-x  1 russ russ         374 Jul 15 12:00
drwxrwxr-x  6 russ russ        4096 Jul 15 12:00 solaris
drwxrwxr-x  8 russ russ        4096 Jul 15 12:00 windows
russ@gondolin ~/dev/md $ ./ .
Detected Kernel Name: Linux
Detected Kernel Release: 4.13.0-36-generic
Detected Kernel Version: #40~16.04.1-Ubuntu SMP Fri Feb 16 23:25:58 UTC 2018
Detected Hardware Type: x86_64
Beginning installation of Melissa Data GeoCoder Object

The following configuration details have been supplied:

Data from uname: KERNEL=Linux
                 KERNEL_VERSION=#40~16.04.1-Ubuntu SMP Fri Feb 16 23:25:58 UTC 2018

Requested install platform: linux-i86

Compiler type: Vendor-Supplied 64-bit

Object install path: "/home/russ/dev/md/."
Data install path: "/home/russ/dev/md/."

Optional components to install: <NONE>

Installing platform-independent files now...
Copied: mdGeoRef.pdf -> /home/russ/dev/md/./GeoObj/mdGeoRef.pdf
Installing platform-dependent files now...
Copied: geo_sample.cpp -> /home/russ/dev/md/./GeoObj/geo_sample.cpp
Copied: -> /home/russ/dev/md/./GeoObj/
Copied: makefile -> /home/russ/dev/md/./GeoObj/makefile
Copied: mdEnums.h -> /home/russ/dev/md/./GeoObj/mdEnums.h
Copied: mdGeo.h -> /home/russ/dev/md/./GeoObj/mdGeo.h
Installing data files now...
Not copied, already in destination: /home/russ/dev/md/./data/mdGeoCode.db3

The argument to script could have been a path like /opt/melissa-data/geocode in order to install the software in a more commercially genteel place. I chose the local subdirectory. Therefore, to the original, post explosion subdirectory, set-up adds GeoObj underneath which you see:

russ@gondolin ~/dev/md $ ll GeoObj
total 1996
drwxrwxr-x  2 russ russ    4096 Sep  5 12:14 .
drwxrwxr-x 10 russ russ    4096 Sep  5 12:14 ..
-r--r--r--  1 russ russ    4342 Sep  5 12:14 geo_sample.cpp
-r-xr-xr-x  1 russ russ 1308746 Sep  5 12:14
-r--r--r--  1 russ russ     533 Sep  5 12:14 makefile
-r--r--r--  1 russ russ    1826 Sep  5 12:14 mdEnums.h
-r--r--r--  1 russ russ    6794 Sep  5 12:14 mdGeo.h
-r--r--r--  1 russ russ  696810 Sep  5 12:14 mdGeoRef.pdf

These are the C/C++-related artifacts, the default ones. However, will be needed by most other languages and environments. I will not be showing everything here.

Exposing language-specific intefaces...

GeoCoder is natively interfaced in C/C++ because it was written in C++. Melissa Data supports many other languages, however. For each interface you wish to expose, you will need to descend down into the subdirectory corresponding to the OS architecture on which you're running GeoCoder. In my case, this is Linux. There, you will see the language support. Only two interest me:

russ@gondolin ~/dev/md $ cd linux/interfaces
russ@gondolin ~/dev/md/linux/interfaces $ ll
total 40
drwxrwxr-x 9 russ russ 4096 Jul 15 12:00 .
drwxrwxr-x 7 russ russ 4096 Jul 15 12:00 ..
drwxrwxr-x 3 russ russ 4096 Jul 15 12:00 java
-rwxrw-r-- 1 russ russ 3755 Jul 15 12:00 makefile
drwxrwxr-x 2 russ russ 4096 Jul 15 12:00 perl
drwxrwxr-x 2 russ russ 4096 Jul 15 12:00 php
drwxrwxr-x 2 russ russ 4096 Jul 15 12:00 php7
drwxrwxr-x 2 russ russ 4096 Jul 15 12:00 plsql
drwxrwxr-x 2 russ russ 4096 Jul 15 12:00 python
drwxrwxr-x 2 russ russ 4096 Jul 15 12:00 ruby


This is relevant to both Java and Python.

LD_LIBRARY_PATH is an environment variable for a Linux (UNIX) process that works in essence like PATH to tell a running process where to go if execution attempts to load objects that are missing (non-resident). Normally, this doesn't relate to Java Virtual Machine (JVM) execution except when JNI is involved because a JNI's dependencies are shared objects created (usually) in C/C++. Wherever you wish to locate any of these GeoCoder shared objects (files ending in .so), you need to modify LD_LIBRARY_PATH in the process to keep your program from failing.

Python works this way as well.

A sample LD_LIBRARY_PATH might appear similar to this if I were to drop the shared objects into a subdirectory named /opt/melissa-data/geocode:

$ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/melissa-data/geocode/"

The process that's going to run the application working with GeoCoder must do so with LD_LIBRARY_PATH set in some equivalent way.

Exposing Python interfaces...

I had trouble getting running probably because I needed to convert it to Python 3. I wrote a lot of Python code back in the days of Python 2, but I do not consider myself a Pythonista. Consequently, I struggled with this project.

First, lets note that Python samples ship for Python 2. to convert to Python 3, you are expected to use the 2to3 executable that ships with Python 3. It seemed to have corrupted something changing.

-        except __builtin__.Exception:
+        except builtins.Exception:

When I tried to run, I saw this (in PyCharm):

/usr/bin/python3.5 /home/russ/dev/md/samples/python/

Traceback (most recent call last):
  File "/home/russ/dev/md/samples/python/", line 136, in __init__
  File "/home/russ/dev/md/samples/python/", line 102, in 
    __getattr__ = lambda self, name: _swig_getattr(self, mdGeo, name)
  File "/home/russ/dev/md/samples/python/", line 80, in _swig_getattr
    raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))
AttributeError: 'mdGeo' object has no attribute 'this'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/russ/dev/md/samples/python/", line 26, in 
    mdGeo = mdGeoPythonWrapper.mdGeo()
  File "/home/russ/dev/md/samples/python/", line 137, in __init__
    except builtins.Exception:
NameError: name 'builtins' is not defined

Process finished with exit code 1

To fix this...

(For now, I'm not super interested in Python here), the following occurrences involving builtin(s) must appear exactly as follows in By the way, this file is crucial in what does.

    import builtins as __builtin__
except ImportError:
    import builtins
    _object = object
    _newclass = 1
except __builtin__.Exception:
    class _object:
    _newclass = 0
    def __init__(self):
        this = _mdGeoPythonWrapper.new_mdGeo()
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _mdGeoPythonWrapper.delete_mdGeo
    __del__ = lambda self: None

(For now, I'm not super interested in Python here and I'm not sure, nor am I willing to spend the time to verify, that 2to3 is responsible for having broken this file, but I think that's what happened.) builds the artifact,, which you must use alongside—both found because of LD_LIBRARY_PATH.

Here are my modifications to


#Put path of Geocoder Object ( and Python Include Path.

g++ -fpic -c mdGeoPythonWrapper.cpp -I$mdGeoPath -I$PythonIncludePath
g++ -shared mdGeoPythonWrapper.o -o -L$mdGeoPath -lmdGeo -pthread

rm mdGeoPythonWrapper.o


russ@gondolin ~/dev/md/linux/interfaces/python3 $ ./
(nothing echoed, so no errors) changed sizes, so I copied both it and which I'm guessing did not change over to ~/dev/md/samples/python where my PyCharm project lives. That subdirectory appears thus:

russ@gondolin ~/dev/md/samples/python $ ll
total 1428
drwxrwxr-x 4 russ russ    4096 Sep 12 13:04 .
drwxrwxr-x 4 russ russ    4096 Sep 12 11:19 ..
-rw-rw-r-- 1 russ russ    4465 Sep 12 13:04
drwxrwxr-x 3 russ russ    4096 Sep 12 13:03 .idea
-r-xr-xr-x 1 russ russ 1308746 Sep 12 12:51
-rw-rw-r-- 1 russ russ   11244 Sep 12 11:55
-r-xr-xr-x 1 russ russ  108064 Sep 12 12:51
drwxrwxr-x 2 russ russ    4096 Sep 12 11:56 __pycache__
-rw-rw-r-- 1 russ russ    3157 Sep 12 13:03

At the top of, I put this to alert me in test output to whether or not LD_LIBRARY_PATH is correctly set up.

import os
library_path = os.environ.get( 'LD_LIBRARY_PATH' )
print( "LD_LIBRARY_PATH=" + library_path )

After all of this, began to work in PyCharm.

Exposing Java interfaces...

To expose Java interfaces, drop into its subdirectory:

russ@gondolin ~/dev/md/linux/interfaces $ cd java
russ@gondolin ~/dev/md/linux/interfaces/java $ ll
total 168
drwxrwxr-x 3 russ russ  4096 Jul 15 12:00 .
drwxrwxr-x 9 russ russ  4096 Jul 15 12:00 ..
-r-xr-xr-x 1 russ russ   524 Jul 15 12:00
drwxrwxr-x 3 russ russ  4096 Jul 15 12:00 com
-rw-rw-r-- 1 russ russ  5624 Jul 15 12:00
-r-xr-xr-x 1 russ russ 43800 Jul 15 12:00
-rw-r--r-- 1 russ russ 19058 Jul 15 12:00 mdGeo.jar
-rw-rw-r-- 1 russ russ 39395 Jul 15 12:00 mdGeoJavaWrapper.cpp
-rw-r--r-- 1 russ russ 30528 Jul 15 12:00 mdGeoJavaWrapper.o
-rw-rw-r-- 1 russ russ  2769 Jul 15 12:00 README.txt
-r-xr-xr-x 1 russ russ   252 Jul 15 12:00

Note importantly that Melissa Data did not go to the trouble of providing a Java interface that is in correct Java. The name of the Java class is mdGeo and its methods are incorrectly capitalized. Consequently, the sample code is slightly confusing as will be your production code. My suggestion is that you confine calls into Melissa Data to as few classes as possible, or resort to a decorator pattern. Obstacles are the numerous internal classes.

The interface consumed from Java code is done using a Java Native Interface (JNI) built atop the Linux/UNIX shared-object, JNI is how Java is able to extend itself to platform-level objects from software like GeoCoder. This shared-object also needs The three artifacts crucial to using Java to reach GeoCoder are therefore:

(Now, if we were on Windoz, even in Java, we would need DLLs, mdGeoJavaWrapper.dll and mdGeo.dll—just saying this to make Windoz guys happy.)

Note: I have heard that the shipping mdGeo.jar was built using Java 7. This is not a problem. The interface simply makes no use of language constructs or mechanisms from Java 8 or later Java versions. There is no reason to ask for or attempt to build a latter one. (You cannot, however, write Java programs against GeoCoder using any version older than Java 1.4.2. It will not work. Note that Java 5 came out in September, 2004.)

You may nevertheless rebuild these artifacts by following information under Setup in README.txt and run a sample building This isn't necessary unless Melissa Data issues an update containing new Java methods. To access the new methods you must follow those instructions, which are:

  1. Execute to create files named and mdGeo.jar (replacing the ones that shipped with the installation.
  2. Execute to compile and run the java program—not really necessary, but it will validate your build.

Typically, however, an update comes with a new and if there has been nothing added to or changed in the interface, there is no need to perform the above. It's only necessary to ensure replacement of the previous shared object with the new one.

While we're at it, contains sample code for writing to Geocoder Object (Melissa Data).

Building with Maven...

The mdGeo.jar artifact is inadequate for the way modern Java programs are developed. These use Maven, Ivy, Gradle, etc. all of which expect to obtain JAR files that are to be linked to be found in a repository. Loose JAR files, such as mdGeo.jar, are not suitable for this. Because this JAR will never find its way into Maven Central or some such repository, to use it you will need to do something similar to what's explained here, How to create Maven local repositories. Read this note and surrounding notes both below and above it. I give all of these because your mileage may vary. I have my own way of doing this, but there are variations to it. I prefer a subdirectory, lib, local to my project that is structured to resemble identically the .m2 subdirectory on any host.

Building the sample code...

In order to create a project around the sample code,, and to advance the utility of building real geocoding using Melissa Data later on in production code, I created a project including pom.xml.

This script will generate a sutable Maven repository fragment as discussed above. As I could find no version number, I sustituted one equal to the current date (September 2020). Run this from the project root with a copy of mdGeo.jar sitting alongside. I have taken the guesswork out of groupId, artifactId and version here for you.

mvn -e install:install-file \
    -DlocalRepositoryPath=./lib \
    -DcreateChecksum=true \
    -Dpackaging=jar \
    -Dfile=./mdGeo.jar \
    -DgroupId=com.melissadata \
    -DartifactId=mdGeo \
    -Dversion=2020.9 \
    -Dpackaging=jar \

Upon executing this script, you will see that the lib subdirectory is populated thus:

russ@gondolin ~/dev/md/samples/java $ tree lib
└── com
    └── melissadata
        └── mdGeo
            ├── 2020.9
            │   ├──
            │   ├── mdGeo-2020.9.jar
            │   ├── mdGeo-2020.9.jar.md5
            │   ├── mdGeo-2020.9.jar.sha1
            │   ├── mdGeo-2020.9.pom
            │   ├── mdGeo-2020.9.pom.md5
            │   └── mdGeo-2020.9.pom.sha1
            ├── maven-metadata-local.xml
            ├── maven-metadata-local.xml.md5
            └── maven-metadata-local.xml.sha1

4 directories, 10 files

Note also that I copied the shared object into this same subdirectory.


Here is the project pom.xml. Certain parts, highlighted, will be relevant to hosting the Melissa Data code, in particular, hosting the local repository:

<project xmlns=""
  <description>Melissa Data Sample Code</description>


      <name>Melissa Data GeoCode JAR and JNI</name>


<!-- vim: set tabstop=2 shiftwidth=2 expandtab: -->

Output from running

/home/russ/dev/jdk-11.0.2/bin/java -agentlib:jdwp=transport=dt_socket,address=,suspend=y,server=n -javaagent:/home/russ/dev/idea-IU-2020.6397.94/plugins/java/lib/rt/debugger-agent.jar -Dfile.encoding=UTF-8 -classpath /home/russ/dev/md/samples/java/target/classes:/home/russ/.m2/repository/com/melissadata/mdGeo/2020.9/mdGeo-2020.9.jar:/home/russ/dev/idea-IU-2020.6397.94/lib/idea_rt.jar
Connected to the target VM, address: '', transport: 'socket'
*****  Initialization Info  *****
    Set License: true
   Build number: 17222
  Database Date: 2020-07-15
Expiration Date: 2020-09-15

Enter Mak: (nothing put here—Melissa Data address key)
Enter Zip:89106
Enter Plus4: (nothing put here—those 4, extra digits in a zipcode)
Results:	GS03
Latitude:	36.182900
Longitude:	-115.164700
CensusTract:	000201
CensusBlock:	3006
CountyFips:	32003
CountyName:	Clark
PlaceCode:	3240000
PlaceName:	Las Vegas
TimeZoneCode:	08
TimeZone:	Pacific Time
CBSACode:	29820
CBSATitle:	Las Vegas-Henderson-Paradise, NV
CBSALevel:	Metropolitan Statistical Area
CensusKey:	320030002013006
CountySubdivisionCode:	94504
CountySubdivisionName:	Las Vegas CCD
StateDistrictLower:	006
StateDistrictUpper:	004
UnifiedSchoolDistrictCode:	00060
UnifiedSchoolDistrictName:	Clark County School District
SourceLevel:	MD
PlaceCode:	3240000
PlaceName:	Las Vegas

Press Enter to Continue, X to quit:X
Disconnected from the target VM, address: '', transport: 'socket'

Process finished with exit code 0


Various notes...

Expectations of input use

GeoObject never takes an address as its input.

GeoObject only take input of Zip5, Zip9, Zip11, or MAK id as input.

Zip5 city-level, the five-digit zipcode (or postal code)
Zip9 city-level, Zip5 + Plus4 (the extended zip- or postal code)
Zip11 rooftop-level, or AddressKey, a result of an AddressObject
AddressKey rooftop-level, a result of an AddressObject (deprecated?)
MAK rooftop-level

If the client wishes to use an address as an input, they must first use addresss object verification to get back the MAK and/or AddressKey, then use either MAK or addressKey as input for Geo Object to get back Geo data such as latitude and longitude.

Result Codes

See Result Code Examples for a list of errors/result codes that can come back.

(Java) Loading Melissa Data shared objects without resorting to LD_LIBRARY_PATH

How about copying the share objects to one of these paths which was seen to be part of java.library.path in IntelliJ IDEA?

(Python) Loading Melissa Data shared objects

In your Python environment, mine is PyCharm, set LD_LIBRARY_PATH to wherever you have placed:

This must be done long before importing the software you depend on.

In PyCharm, this done thus:

  1. Run → Edit Configurations.
  2. In the left-hand pane, under Python, you should see GeoSample. (If not, then attempt to run and PyCharm will create a run/debug configuration for it.)
  3. Click on GeoSample.
  4. In the right-hand pane, find Environment variables:.
  5. Click at extreme right in the edit field on a little icon to get a dialog, Environment Variables.
  6. Under User environment variables:, click the + sign.
  7. Type in LD_LIBRARY_PATH.
  8. The new variable will be on a line with a dark, blue background. Double-click where the Value should be put in order to make the edit field listen to you.
  9. Type the path to the subdirectory where you have put the two shared-object artifacts noted above.
  10. Click OK to exit the Environment variables dialog, then OK again to exit the Run/Debug Configurations dialog.
  11. At this point, you're set. If you wish to verify that this works, create a code snippet, perhaps simply at the top of like the one below.
    import os
    library_path = os.environ.get( 'LD_LIBRARY_PATH' )
    print( library_path )
  12. As soon as you run with this code snippet, you will see something like this. (I set LD_LIBRARY_PATH to /home/russ/dev/md/samples/python.)
    /home/russ/sandboxes/ /home/russ/dev/md/samples/python/

Melissa Data documentation links