Development environment

This section describes the tools you will need to develop programs using the WebSphere MQ Everyplace Development Kit. It covers the following environments:

Java development

To develop programs in Java using the WebSphere MQ Everyplace development kit, you must set up the Java environment as follows:

You can use many different Java development environments and Java runtime environments with WebSphere MQ Everyplace. The system configuration for both development and runtime is dependent on the environment used. WebSphere MQ Everyplace includes a file that shows how to set up a development environment for different Java development kits. On Windows systems this is a batch file called JavaEnv.bat, for UNIX systems it is a shell script called JavaEnv. To use this file, copy the file and modify the copy to match the environment of the machine that you want to use it on.

A set of batch files and shell scripts that run some of the WebSphere MQ Everyplace examples use the environment file described above, and, if you wish to use the example batch files, you must modify the environment file as follows:

Note:
Customized versions of JavaEnv.bat or JavaEnv may be overwritten if you reinstall WebSphere MQ Everyplace.

When you invoke JavaEnv.bat on Windows you must pass a parameter that determines the type of Java development kit to use.

Possible values are:

Note:
These parameters are case sensitive and must be entered exactly as shown.
Sun
- Sun
JB
- Borland JBuilder
MS
- Microsoft(R)
IBM
- IBM

If you do not pass a parameter, the default is IBM.

The JavaEnv shell script on UNIX does not use a corresponding parameter.

On Windows, by default, you must run JavaEnv.bat from the <MQeInstallDir>\java\demo\Windows directory. On UNIX, by default, you must run JavaEnv from the <MQeInstallDir>/Java/demo/UNIX directory. Both files can be modified to allow then to be run from other directories or to use other Java development kits.

C development

To develop programs in C, using the WebSphere MQ Everyplace Development Kit, you need the following tools:

Microsoft eMbedded Visual C++ (EVC) Version 3.0.
This is included in Microsoft eMbedded Visual Tools 3.0, which is available as a free download from the Microsoft web page:
http://msdn.microsoft.com/mobile/
You must use version 3.0 as version 4.0 does not support PocketPC.
An SDK for your chosen platform
Microsoft eMbedded Visual Tools 3.0 includes an SDK for PocketPC 2000. You can also download an SDK for PocketPC 2002 from Microsoft:
http://msdn.microsoft.com/mobile/

Compilation information

The two main subdivisions of the native C codebase are code for PocketPC 2000 and code for PocketPC 2002. For both, there are binary files for the actual device and also for the emulator. Binary files are compiled for the ARM processors.

Binary files

The root of the binarie, as well as documentation and examples, is the C directory, found in the main installation directory. This contains directories for the examples, documentation, and separate directories for PocketPC 2000 and 2002.

PocketPC 2002
PocketPC 2000

Using eMbedded Visual C++

You can compile applications using the EVC Integrated Development Environment (IDE), or optionally, from the command line. However, you must consider the following:

We recommend that you develop applications using the PocketPC or PocketPC2002 emulator as this typically provides a faster compilation and debug environment. However, current emulators are API emulators, meaning that they do not emulate ARM hardware. They emulate PocketPC API calls, but the code is still x86, that is running in an x86 virtual machine in the PocketPC 2002 emulator case. Therefore, we recommend that you regularly test the application on the real target device, as many problems such as byte-alignment only becomes apparent on the real device.

Note:
WebSphere MQ Everyplace emulator binaries are provided only for development purposes and are not suitable for deployment into a production environment.

Threading

The native codebase is designed to be re-entrant. The actual codebase does not use threads, but this does not preclude the use of multiple threads in the application. For example, you can create an application thread to repeatedly call mqeQueueManager_triggerTransmission(). If you want to use multiple threads, you do not need to call any specific APIs.

Although it is not a requirement. we recommend that you have an exception block per thread. If you use one exception block shared across threads, an exception block for a thread that fails can be overwritten by the exception block for a thread that succeeds.

Note:
You must call mqeSession_initialize or mqeSessuion_terminateonce only, before any threads use a WebSphere MQ Everyplace API call. To ensure this, call it in the main thread before any application threads are created. For example, do not use the following:
mqeSession_initialize();
mqeSession_initialize();
mqeSession_terminate();
mqeSession_terminate();

Calling convention

The calling convention for all of the APIs has been explicitly set at _cdec1. However, you can use

a different default calling convention in your application.

Handles and items

An application needs a mechanism for accessing WebSphere MQ Everyplace items such as the queue manager, fields, strings, and so on. Handles use WebSphere MQ Everyplace items. The handle points to an area of memory used to store the specific information for that instance of the item. Type information is held for each item. Therefore, you must take care to initialize the handle correctly.

To use a handle, you must initialize it. You can do this by calling the new function of the associated item to be used. For example, to create an MQeString, you must first call the mqeString_new() function and pass a pointer to MQeStringHndl to that function. The mqeString_new() function allocates memory for the internal structure and sets the required default values by MQeString. Once completed successfully, the function returns the handle, which can now be used in subsequent calls to MQeString functions.

Once an item has been finished with, it is important to call the free() function of the item with which the handle is associated. The free() functions release all the systems resources used by that item. Seting the handle to NULL introduces a memory leak to the application and the system may run out of resources. To avoid this, set the handle to NULL after it has been freed.

Note:
We recomment that you do not attempt to free a handle more than once, as this can cause unprecedented results.

You must use handles only with their associated items. You must also initialize and free them in the correct manner. The only instances where the application is not responsible for initializing the handle is when a pointer to a handle is passed as an input parameter to a WebSphere MQ Everyplace API. In such instances, a fully initialized handle is returned to the application without the user having to invoke the relevant new() function. An example of this is mqeQueueManager_BrowseMessages(), which has a pointer to an MQeVectorHndl as an input parameter. However, in instances like this, the application is still responsible for freeing the handle.

WebSphere MQ Everyplace memory functions

WebSphere MQ Everyplace provides the following functions for memory management:

These functions use the same memory management routines that are used within the WebSphere MQ Everyplace codebase. These are available for use by application programs. An application can generally use its own choice of memory management. However, some API calls, for example mqeAdministrator_QueueManager_inquire, need to return blocks of memory containing information. In this case, the memory must be freed using the mqeMemory_free function.

An additional advantage of using the mqeMemory functions is that their use gets traced along with mqe processing. However, never mix the memory allocation calls. For example, do not free memory allocation with mqeMemory_allocate with the C runtime free() call, as the application can become unstable.

MQeString

The MQeString class contains user defined and system strings. It is an abstraction of character strings used throughout the C API where a string is required. MQeString allows you to create a string in a number of formats, such as arrays containing Unicode code points, with each code point stored in a 1, 2, or 4 byte memory space, and UTF-8. The current implementation of MQeString supports external formats only.

Note:
Although they are passed using an MQeString, some API calls require the actual string to lie within the valid ASCII range.
Constant Strings

A number of constant strings are provided. These are defined in the following header files:

Constructor
		MQERETURN osaMQeString_new(MQeExceptBlock* pExceptBlock,
                               MQEVOID*        pInputBuffer,
                               MQETYPEOFSTRING type,
                               MQeStringHndl * phNewString
                              );
This function creates a new MQeString object from a buffer containing character data. The data can be in a number of supported formats including, null terminated single byte character arrays (i.e. normal C char* strings), null terminated double-byte Unicode character arrays, null terminated quad-byte Unicode character arrays, and null terminated UTF-8 arrays. The type parameter tells the function what format the input buffer is in.
Destructor
  MQERETURN osaMQeString_delete(MQeExceptBlock* pExceptBlock,
                                MQeString_*     pString
                               );
This function destroys an MQeString object that was created using osaMQeString_new, or MQeString_duplicate, or MQeString_getMQeSubstring
Getter
   MQERETURN osaMQeString_get(MQeExceptBlock*      pExceptBlock,
                         MQEVOID*             pOutputBuffer,
                         MQEINT32*            pBufferLength,
                         MQETYPEOFSTRING      requiredType,
                         MQECONST MQeStringHndl hString
                         );
This function populates a character buffer with the contents of an MQeString performing conversion wherever necessary. Only simple conversions are carried out. No codepage conversion is attempted. For example, if an SBCS string has been put into the string, then trying to get the data out as DBCS (Unicode) data works correctly. If the data was put in as DBCS however, and you try to get the data out as SBCS, this only works if the data does not have any values that cannot be represented with a single byte. When get() is used for SBCS, DBCS, or QBCS, each character is represented by its Unicode code point value.
   MQERETURN osaMQeString_getSubstring(MQeExceptBlock* pExceptBlock,
                     MQEVOID*        pOutputBuffer,
                     MQEINT32*       pBufferLength,
                     MQETYPEOFSTRING requiredType,
                     MQECONST MQeStringHndl hString,
                     MQEINT32 from,
                     MQEINT32 to
                     );
This function is very similar to osaMQeString_get except that it only gets a substring (from from to to inclusive).
   MQERETURN osaMQeString_getMQeSubstring(MQeExceptBlock* pExceptBlock,
                     MQeStringHndl *      phOutput,
                     MQECONST MQeStringHndl   hString,
                     MQEINT32 from,
                     MQEINT32 to
                     );
This function is very similar to osaMQeString_getSubstring except it returns its result as an MQeString.
   MQERETURN osaMQeString_duplicate(MQeExceptBlock  * pExceptBlock,
                     MQeStringHndl * phNewString,
                     MQECONST MQeStringHndl   hString
                     );
This function duplicates an MQeString.
   MQERETURN osaMQeString_codePointSize(MQeExceptBlock* pExceptBlock,
                     MQEINT32 * pSize,
                     MQECONST MQeStringHndl   hString
                     );
This function finds the memory size (in bytes) required for the largest character in the string.
   MQERETURN osaMQeString_getCharLocation( MQeExceptBlock* pExceptBlock,
                     MQEINT32*       pOutIndex,
                     MQECONST MQeStringHndl    hString,
                     MQECHAR32       charToFind,
                     MQEINT32        startFrom,
                     MQEBOOL         searchForward
                     );
This function returns the location index (starting from 0) of the first appearance of a specified character, specified as its Unicode code point value. You can specify the starting point of your search and the direction of the search.
Tester
   MQERETURN osaMQeString_isAsciiOnly(MQeExceptBlock*   	pExceptBlock,
                          MQEBOOL*          	pIsAsciiOnly,
                          MQECONST MQeString_* pString
                          ); 																											
This function determines whether the string contains any non-invariant ASCII characters.
   MQERETURN osaMQeString_equalTo(MQeExceptBlock*   pExceptBlock,
                          MQEBOOL*          pIsEqual,
                          MQECONST MQeString_* pString,
                          MQECONST MQeString_* pEqualToString
                          );
This function determines whether two strings are equivalent.
   MQERETURN osaMQeString_isNull(MQeExceptBlock  * pExceptBlock,
                          MQEBOOL * pIsNull,
                          MQECONST MQeStringHndl  hString
                          );
This function determines if a string is a null string. A a NULL handle is considered as a null string as well.

The Single Byte Character Set (SBCS) is the standard mode of operating with C on an ASCII code page. Java works in Unicode only and there may be platforms to support, that do not load an SBCS code page, for example in some countries languages are represented in DBCS. As it does not include the character pointer, the string item allows you to create strings on an ASCII machine without considering Unicode requirements. WebSphere MQ Everyplace carries out any necessary conversions. Use the UTF-8 representation of the string as this can cope with any character representation and does the conversion for you. Once created, an MQeString cannot be altered. However, a number of functions facilitate the use of the MQeString type. You can also create constant MQeStrings in a similar manner to using #define NAME "mystring". Using MQeString ensures portability of the application.

J2ME environment

There are two distinct J2ME environments:

Connected Device Configuration (CDC) and Profile
An example is Foundation + Applications in the CDC environment, which can effectively be developed like a normal Java 2 Platform Standard Edition (J2SE) application. The only change required is modifying the bootclasspath option to point to the relevent CDC jar or zip class file.
Note:
The 'bootclasspath' option may not be available on all JVM's
Connected Limited Device Configuration (CLDC) and Mobile Information Device Profile (MIDP)
Applications developed for MIDP can also be compiled using a normal J2SE JVM (again using the bootclasspath to point to the required Midp class library), but they normally have to be run within a Midp Emulator. Therefore, we recommend developing the application using one of the MIDP Toolkits available on the Web. WebSphere MQ Everyplace provides a MIDP jar that should be used within this environment. The MQeMidpBase.jar is in the <MQeInstallDir>\Java\Jars directory.