JavaTM Message Queue

Version 1.1

Release Notes

Last updated: 31 May 2000




This document contains the following:
GENERAL INFORMATION
Java Message Service (JMS) Compliance
Discussion Forum
NEW IN THIS RELEASE
Improved Performance and Robustness
Updated JMS Implementation
Multi-router Network Support
Access to Objects Through JNDI
Router as an NT Service
Java 2 Policy Files
KNOWN BUGS
JMS 1.0.2 Compliance-related Bugs
Other Bugs
FUNCTIONALITY MARKED AS OPTIONAL IN JMS 1.0.2
JMS MessageID
Overriding Message Header Fields
JMS-defined Properties
Provider-specific Properties
Distributed Transactions
Multiple Sessions
CLIENT PROGRAMMING GUIDANCE
Connection Close, Session Close, and Message Listeners
TECHNICAL NOTES
One Installation Per Machine
Synchronization Recommended
Possible Exception When Running jmqconfig
Administration Objects Created with Prior Releases
JAR Files for Client Applications
Maximum Size of Property String
Out of Memory Errors
Y2K Information
JavaTM 2 SDK Guidance (Solaris)
OS-Defined Connection Limitations on Clients and Routers

NOTE: You can find this document, and any updates made to it after the product's release, on our website at: http://www.sun.com/forte/jmq/


GENERAL INFORMATION

Java Message Service (JMS) Compliance
Java Message Queue is designed to be compliant with the Java Message Service (JMS) 1.0.2 specification. Because an official Compatibility Test Suite (CTS) for JMS has not yet been released, we are unable to provide verification of JMS 1.0.2 compliance.

Known bugs related to JMS compliance, and their workarounds, are listed in the KNOWN BUGS section of this document.

Discussion Forum
A discussion forum is available for Java Message Queue customers. It provides a place for customers to exchange ideas on Java Message Queue-related topics and share problem-solving tips and techniques.

To subscribe to the jmq-interest list, send email to listserv@java.sun.com and include in the message body:

subscribe jmq-interest <your full name>

For example:

subscribe jmq-interest firstname lastname

To unsubscribe to the list, send email to listserv@java.sun.com and include in the message body:

signoff jmq-interest


NEW IN THIS RELEASE

Improved Performance and Robustness
Since the release of Java Message Queue 1.0, significant effort has gone into additional testing and tuning of the software. The result is a product with even greater stability and speed.

Updated JMS Implementation
Java Message Queue 1.1 now supports Java Message Service (JMS) 1.0.2, an update to the JMS specification that was published after Java Message Queue 1.0 was released.

Multi-router Network Support
Fully connected multi-router configurations are now supported. By a "fully connected network" it is meant a network in which every router is connected to every other router by no more than one "hop".

Access To Objects Through JNDI
Java Message Queue now provides a utility for the management of administered objects, such as topics and queues, through the Java Naming and Directory Interface (JNDI).

Router as an NT Service
Installing the router as an NT service means it can be managed using the Windows NT Services panel, including setting it to start automatically whenever the system is restarted.

In Java Message Queue 1.0, if you chose not to install the router as an NT Service initially and then later changed your mind, you had to re-install the entire product to accomplish this. In this release, if you change your mind after installation of the product, you simply run the new jmqsvcadmin utility to change the router installation to an NT service.

Java 2 Policy Files
Three policy files are provided with Java Message Queue for use with the Java 2 security manager: jmqadmin.policy, jmqclient.policy, and jmqexamples.policy.

The jmqadmin.policy file provides the permissions needed by the jmqconfig and jmqadmin administration utilities to create log files, delete log files, and open socket connections (for instance, for starting the Security Server or connecting to the Router). In most cases, the jmqadmin.policy file will not require modification.

The jmqclient.policy file provides the permissions necessary for your client application to access the router and network resources. The file should be modified to reflect the security requirements of your particular application. Guidelines for possible modifications are provided in the file itself.

The jmqexamples.policy files provides the permissions necessary for running the Java Message Queue examples. If you modify the examples, you might need to modify the policy file to reflect those changes. Guidelines for making modifications are provided in the file itself.



KNOWN BUGS

This section contains a listing of the more important bugs known at the time of the Java Message Queue 1.1 release.

For the most up-to-date list of bugs and their status, JavaTM Developer ConnectionSM members should see the Bug Parade page on the Java Developer Connection web site. Please check that page before you report a new bug.

You can also check the listed bugs for any workarounds.

The relevant page is:

http://developer.java.sun.com/developer/index.html
Note: Java Developer Connection membership is free but does require registration for access. Details on how to become a Java Developer Connection member are provided on Sun's For Developers web page.

To report a new bug or submit a feature request, simply fill out the details in the easy-to-use form on our website and submit.

JMS 1.0.2 COMPLIANCE-RELATED BUGS:
Bug ID Description
4297174 This bug accumulates non-compliance issues related to Section 3.8.1.1 Message Selector Syntax of the JMS specification.
  • In some cases, Java Message Queue fails to throw InvalidSelectorExceptions.

    One such case that should throw an Exception, but does not, is selecting an identifier against a set that is not composed of string literals. For example, the following form of selector is incorrect but does not throw an Exception:

    "switchvalue IN (1,2,3)"
    "switchvalue NOT IN (1,2,3)"

    The correct form of the selector is:

    "switchvalue IN ('1', '2', '3')"
    "switchvalue NOT IN ('1', '2', '3')"

    Note that Java Message Queue *does* comply for message delivery in the above cases. That is, if the incorrect form of selector is used, messages are not matched (and therefore are not delivered). If the correct form of selector is used, messages that match the selector are delivered.

    Workaround: Do not use the incorrect form of the selector.

  • In some cases, Java Message Queue fails to recognize a match to stated selection criteria.

    • One such case where messages match but Java Message Queue does not correctly recognize the match (and therefore does not deliver the message) is when comparing exact and approximate numeric values. For example, using a selector like:

      "Value = -57.9E2"

      will not match a message that has an Integer property set, as in:

      msg.setIntProperty("Value", -5790);

      In this case, Java Message Queue does not correctly promote -5790 to a float value for comparison. For receipt, either the selector should be "Value = -5790" or the property should be of like type as in msg.setFloatProperty("Value", -57.9E2) or msg.setFloatProperty("Value", -5790);

      Workaround: Use like types in the selector and message properties when camparisons are to be made.

    • JMQ does not correctly interpret a selector if an arithmetic expression involving property names is on the right hand side of the conditional expression being evaluated. For example, using the following selector expression will result in non-receipt of a message, even though it evaluates to true:

      property < property - 1

      Workaround: On the right-hand side of a conditional expression, use literals only.

  • In some cases, Java Message Queue throws an InvalidSelectorException when the selector is valid.

    • Conditional expressions cannot contain arithmetic sub-expressions involving properties. For example, the following conditional expression would cause the selector to throw an exception:

      (Value1 + 100) > 10000

      Workaround: Use single property logical sub-expressions instead.

4297469 Recovering CLIENT_ACKNOWLEDGE messages works incorrectly per JMS specification.

If an application using the Session.CLIENT_ACKNOWLEDGE acknowledgement mode is rapidly receiving messages and Session.recover() is called, the application may receive some number of new messages even after the call. These new messages are then erroneously considered to be in the scope of the recover() call and so are redelivered along with the previously received messages.

Here is an example of the problem scenario:

  1. Sender publishes 6 messages.
  2. Receiver receives messages 1, 2, 3.
  3. Receiver calls recover().
  4. Receiver then receives messages 4, 5, 6.
    (JMSRedelivered is false).
  5. Receiver re-receives messages 1, 2, 3, 4, 5, 6.
    (JMSRedelivered is true)

The proper behavior after a recover() call would have been for messages 1, 2, 3 to be redelivered (with JMSRedelivered set to true) before messages 4, 5 and 6 are delivered (with JMSRedelivered set to false) for the first time.

Workaround: To avoid receiving duplicate messages after a recover() call, discard messages in the recovered session until the first message with JMSRedelivered set to true is received. (That is, discard messages in the recovered session with JMSRedelivered set to false.)

Note that JMSRedelivered correctly reflects the redelivery state of the message.

4307850 JMS implementation should not allow duplicate ClientID's for Connection objects.

The JMS specification states that Connection.setClientID() should throw InvalidClientIDException if a duplicate clientID is set on a Connection.

JMQ does not throw this exception and allows duplicate ClientIDs which can cause durable subscriptions to have unexpected behavior.

The developer will have to be responsible for ensuring that any ClientIDs set are unique.



OTHER BUGS:
Bug ID Description
4302398 Receiving > 1 duplicate messages after provider failure (AUTO_ACK).

Workaround: After a provider failure, ignore messages with JMSRedelivered set to true.

4285193 ircmd connect subcommand gives wrong status (erroneously indicates connected) if the host being connected to does not exist or does not have an irouter running.

Workaround: none.

4286456 Windows only: ircmd text display is not cleared by backspace.

Workaround: Once your cursor is repositioned by backspace, replace the existing text by typing over it.

4291584 Using -w -fMYFILE to write personal options to a specified file results in other saved option (.rfb) files on RESPATH being ignored when the router is next run.

Workaround: When you want to change your saved personal options, but not the saved system-wide USER options (res/user/rtrdef.rfb), run irouter with the -f and -w flags then exit the irouter. When irouter is run again without any options, it will reflect the complete set of nested options found in all the RESPATH files.

4298427 When irouter is run with network debugging option -dn2, only the first message sent arrives at the client, any other messages are held by the router.

Workaround: Do not use -dn2 or above.

4320398 Windows only: ircmd -do <filename> does not echo keyboard input.

Workaround: None required. While the keyboard may appear to be hung, input and output is being sent to the output device specified by the -do option.

4322841 An instance of the jmqadmin GUI is unaware of any Client Authentication Server instance it did not start.

Workaround: You must manually take care that you only run a single instance of the Client Authentication Server.

4333117 jmqadmin's log manager consumes 90% CPU time if AutoSave set to 0.

Workaround: Do not set the AutoSave to a value less than 1.

4334418 In a multi-router system, a Queue Receiver client re-connecting to a different router may receive messages that have already been delivered and acknowledged by another client.

Workaround: The Queue Receiver for a specific Queue should always re-connect to the same router (although it does NOT need to be the same router the Queue Publisher is using).

4335156 Sending a message with one long property can crash router running with -ds3 enabled.

Workaround: If your messages contain large properties, do not run the router with the -ds3 option.

4335916 Two threads using a single session simultaneously can hang the client.

If in the message listener of a transacted session, you notify another thread to use the same session and perform either a commit or a rollback, the client can deadlock.

The following code example causes the client to hang in the current release:

//message listener onMessage()
public void onMessage(Message message){

try {

//mainThread is an object running in a different thread.
//the method mainThread.notifyCommit() simply calls
//Session.commit().
mainThread.notifyCommit();
} catch (Exception e) {

e.printStackTrace();
}
} //end onMessage

Workaround: Choose one of the following as a workaround:

  1. Do not use a separate thread to do a commit or rollback in a transacted session.
  2. Use a non-transacted, client-acknowledged session for the message consumer.

4338924 jmqconfig with LDAP does not work with JDK 1.1.8

Workaround: The ldapbp.jar file in the lib directory has references to JDK 1.2, which is invoked only when ldapbp.jar is available. Consequently, when running jmqconfig with JDK 1.1.8, you should:

  1. Remove the ldapbp.jar and jaas.jar from the lib directory.
  2. Remove ldapbp.jar and jaas.jar from the JMQ_CPATH environment variable in jmqconfig scripts.
4339587 JMQ router may send messages not selected by queue receiver's selector to a client.

When using a Queue, a selector is checked when the messages are received by the router, but it is not re-checked before a message is sent out.

When you re-connect to a queue with a receiver which has a selector that is different from the previous selector, the selector will only affect new messages sent into the system. This means that the client will receive old un-acknowledged messages that match the original (not the current) selector.

Once all previously queued messages have been received, only new messages that match the new selector will be received.

4340075 The close method of QueueRequestor throws an exception.

Workaround: Do not use javax.jms.QueueRequestor.close(). Use Session.close() instead.





FUNCTIONALITY MARKED AS OPTIONAL IN JMS 1.0.2

The JMS 1.0.2 specification indicates certain items that are optional-- each JMS provider (vendor) chooses whether or not to implement them. The Java Message Queue product handling of each of these optional items is indicated below:

  1. Section 3.4.3 JMSMessageID

    "Since message ID's take some effort to create and increase a message's size, some JMS providers may be able to optimize message overhead if they are given a hint that message ID is not used by an application. JMS Message Producer provides a hint to disable message ID."

    The Java Message Queue product does not support disabling Message ID generation (any setDisableMessageID() call in MessageProducer is ignored). All messages will contain a valid MessageID value.

  2. Section 3.4.12 Overriding Message Header Fields

    "JMS does not define specifically how an administrator overrides these header field values. A JMS provider is not required to support this administrative option."

    The Java Message Queue product does not support the administrative override of the values in message header fields.

  3. Section 3.5.9 JMS Defined Properties

    "JMS Reserves the 'JMSX' Property name prefix for JMS defined properties."

    "Unless noted otherwise, support for these properties is optional."

    The JMSX properties defined by the JMS 1.0.2 specification are supported in the Java Message Queue product.

  4. Section 3.5.10 Provider-specific Properties

    "JMS reserves the 'JMS_<vendor_name>' property name prefix for provider-specific properties."

    "The purpose of the provider-specific properties is to provide special features needed to support JMS use with provider-native clients. They should not be used for JMS to JMS messaging."

    Java Message Queue 1.1 does not use provider-specific properties.

  5. Section 4.4.8 Distributed Transactions

    "JMS does not require that a provider support distributed transactions."

    Distributed transactions are not supported in this release of the Java Message Queue product.

  6. Section 4.4.9 Multiple Sessions

    "For PTP <point-to-point distribution model>, JMS does not specify the semantics of concurrent QueueReceivers for the same queue; however, JMS does not prohibit a provider from supporting this."

    The Java Message Queue implementation supports only one QueueReceiver per queue. This is the case whether there is one router or a network of routers.



CLIENT PROGRAMMING GUIDANCE

Connection Close, Session Close, and Message Listeners
The Connection's close method calls the Session's close method for all sessions in the connection, one by one. When the Session's close method is called, if there are still Message Listeners executing on behalf of message consumers, the close method will wait up to double the acknowledgement timeout value (minimum 60 seconds) before sending the initial interrupt to the Message Listeners. The close method will continue sending interrupts to the Message Listeners every 10 seconds thereafter, until the Message Listeners return.

Because of the above sequence of events, you should observe the following guidelines when writing your client application:

  • If your client application requires the Message Listener to have processed all incoming messages, or if the session is transacted, wait for Message Listeners to process all your messages before you close the session or connection.


  • If your Message Listener is still processing messages when you call close() on the session or the connection, make sure your Message Listener does not ignore the InterruptedException on block calls. Similarly, if your Message Listener is in a time-consuming or infinite loop, make sure it checks Thread.interrupted() periodically. Otherwise, your connection or session close could be blocked.


  • Always wait until Senders or Publishers return from their send and publish method calls before you close the session or connection.


  • Do not close a Message Listener's connection or session from the Message Listener's onMessage method. If you call close from within a Message Listener, Java Message Queue will throw an IllegalState Exception. If this occurs, you will need to call System.exit() to exit the client application.


TECHNICAL NOTES

One Installation Per Machine
For the Java Message Queue product to work correctly, there can be only one installed copy of the software (regardless of its version) on any given machine. Multiple installed copies on a single machine are not supported.

You must uninstall any currently installed versions of the Java Message Queue product, and remove any residual files, before proceeding with the new installation.

The migration of persistent messages and customizations from one installation to another is not supported.

Synchronization Recommended
It is recommended that you synchronize the clocks on all hosts interacting with the Java Message Queue system. This is particularly important if you are using message expiration (TimeToLive). Failure to synchronize the hosts' clocks may result in TimeToLive not working as expected (messages may not be delivered).

In the Solaris operating environment, you can issue the rdate(1M) command on a local host to synchronize with remote host. (You must be superuser--that is, root--to run this command.) For example, the following command synchronizes the local host (call it Host 2) with remote host Host1:

# rdate Host1

On Windows platforms, you can issue the net command with the time subcommand to syncronize your local host with a remote host. For example, the following command synchronizes the local host (call it Host 2) with remote host Host1:

net time \\Host1 /set
Possible Exception When Running jmqconfig
When running jmqconfig on a win32 platform under JDK 1.1.x with your CLASSPATH and JAVA_HOME environment variables set, you may get a message similar to the following:

C:\ws_jmq1.0\dist\win32\bin>./jmqconfig -l
java.lang.UnsatisfiedLinkError: doPrivileged
at
javax.naming.InitialContext.<init>(InitialContext.java:202)
at
com.sun.messaging.ia.admin.JMQConfig.init(JMQConfig.java:134)
at
com.sun.messaging.ia.admin.JMQConfig.main(Compiled Code)

If this happens, unset your JAVA_HOME environment variable then retry running jmqconfig.

Administration Objects Created with Prior Releases
Java Message Queue 1.1 cannot use Administered Objects (Queues, Topics) created with earlier versions of the software. This applies both to Java Message Queue Administered Objects that were created using the APIs and to those created using the jmqconfig utility.

If you use the jmqconfig utility in Java Message Queue 1.1 and attempt to retrieve such an object, you will receive an error message similar to the following:

Error: Either this is a JMQ administered object created using jmqconfig from the Early Access release of JMQ 1.1 or it is not a JMQ administered object. If it is a JMQ administered object from the Early Access release of JMQ 1.1, please remove it as it is not compatible with this release of JMQ.

If you receive this message, delete the problem Administration Objects then create new ones with the Java Message Queue 1.1 APIs or utilities.

Maximum Size for Property String
In Java Message Queue, the maximum size for property data is exactly 7Kb. Using a property string in excess of that amount can bring the router down.

JAR Files for Client Applications
Running client applications now requires jndi.jar (JNDI), as well as jmq.jar and jms.jar, be in your classpath setting. The jndi.jar file is required even if you are not directly using JNDI because it is referenced through the Destination and ConnectionFactory classes.

If you are using JNDI, in addition to the above, you must also include providerutil.jar plus the either fscontext.jar (if you are using the filesystem context) or ldap.jar (if you are using the LDAP context).

Out of Memory Errors
If you are running a client application that deals with large messages or many small messages, it may encounter OutOfMemory errors. The Java Message Queue client does not have a memory leak--it just has insufficient memory to copy the messages off of the network and deliver them to your client.

To eliminate these OutofMemory errors, increase the maximum Java heap size. You can do this by passing the appropriate command line option to the "java" or "jre" command.

On JDK1.1.X, use the -mx option. For example:

java -mx64m MyClass

On Java2, use the -Xmx option. For example:

java -Xmx128m MyClass

In JDK1.1.X, the default maximum heap size was only 16MB. In Java2, the default was increased to 64MB. Therefore, this problem is more likely to be seen when running against JDK1.1.X than when running against Java2.

Y2K Information
For full Y2K compliance, it is necessary to run Java Message Queue 1.1 with a Y2K-compliant JDK (or JRE) and a Y2K-compliant operating system.

JDK: Up-to-date versions of JDK 1.1.8 and Java 2 (formerly code-named "JDK 1.2") are Y2K-compliant.

Operating System: On Solaris, up-to-date versions of 2.6, Solaris 7, and Solaris 8 are Y2K-compliant.

(For other operating systems, check the operating system vendor's website for information on Y2K-compliance.)

By "up-to-date" it is meant that the JDK or operating system in question is used in conjunction with the most current Y2K-patches applicable to that version. Y2K patches for Sun products can be found at:

http://www.sun.com/y2000/
JavaTM 2 SDK Guidance (Solaris)
To minimize problems, use at least Java 2 SDK 1.2.2 ("Solaris_JDK_1.2.2") when using Java Message Queue with Java 2 in the Solaris operating environment. Only the production versions (not reference versions) of the Java 2 SDK are supported.

Production versions of the Java 2 platform for the Solaris operating environment are available at:

http://www.sun.com/solaris/java/
OS-Defined Connection Limitations on Clients and Routers
The Solaris OS has a upper limit of 1024 file descriptors that any application can use at one time. In the JMQ system, each connection a client makes, or each connection a router accepts, uses one of these file descriptors. As a result, you cannot have have a router or client running with more than 1024 connections. (The number is actually slightly lower than that due to a few file descriptors that are used for other purposes.)

On the Solaris platform, the shell in which the client or router is running also places a soft limit on the number of file descriptors that a client can use. This soft limit is typically much less than 1024. It is necessary to change this soft limit if you wish to have a client or router run with a greater number of connections. To change this limit, see the unlimit man page for the csh shell and also for the sh/ksh shells. The limit needs to be changed in each shell in which a client or router will be executing.