jms-spec
  1. jms-spec
  2. JMS_SPEC-46

Define standard API to create and configure a ConnectionFactory

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.1
    • Fix Version/s: None
    • Labels:
      None

      Description

      This is a proposal to extend the JMS specification to define a standard way of instantiating and configuring connection factory objects.

      Background

      A connection factory is an example of an administered object. The JMS 1.1 specification establishes the convention whereby administered objects (connection factories and destinations) are not created in application code. Instead they are created by an administrator using tools specific to the JMS provider and stored in JNDI. The application code then looks up the connection factory or destination from JNDI and uses them in accordance with the JMS API.

      The purpose of this is clearly stated in the specification: it is to allow everything that is non-standard and specific to a particular JMS provider to be kept out of the code itself. (See Relevant sections of the JMS 1.1 Specification below).

      In the case of connection factories, this means that the application doesn't have to contain any information about how to connect to the JMS provider. For example, if the JMS provider is running on some remote server, the application doesn't contain any information about the location of the server or the protocol used to connect to it. All this information is defined when the connection factory is created by an administrator, separate from the application itself.

      However the JMS specification says nothing about how the connection factory itself is created or configured, other than saying that it is done by "provider-specific facilities". All it says is that:

      • it must implement javax.jms.ConnectionFactory,
      • it must implement javax.naming.Referenceable and java.io.Serializable, so it can be stored in all JNDI naming contexts (section 4.2)
      • it is recommended that implementations "follow the JavaBeans design patterns"
      • it allows client identifier to be set (section 4.3.2)

      However the specification does not define:

      • how a connection factory is instantiated
      • how the location of the server is defined
      • how client identifier is set
      • how other properties are set

      Now although this omission from the JMS 1.1 specification is no doubt deliberate, it does cause some difficulties:

      • it is not possible to develop standard tools for creating connection factories (and binding them in JNDI) which work with multiple JMS providers
      • in a Java EE environment, there is no standard way of configuring the JMS requirements of a particular application
      • it is inconsistent with way in which a JDBC DataSource objects is defined, both in a Java SE and a Java EE environment. This is discussed more in How JDBC DataSource objects are configured.

      Proposals

      It is proposed that the way that a ConnectionFactory is created and configured be partially standardised in a manner similar to JDBC DataSource objects, as follows:

      • A ConnectionFactory implementation is a JavaBean, and may be instantiated by executing the no-arg constructor of its implementation class. For example:
      ConnectionFactory cf = Class.forName("com.sun.messaging.ConnectionFactory") 
      
      • The JMS specification will define a set of properties which may be used to identify and describe a ConnectionFactory implementation.
      Property name Type Description
      description String description of this connection factory
      user String user name (may be overridden when createConnection is called)
      password String password corresponding to user name may be overridden when createConnection is called)
      networkProtocol String network protocol used to communicate with the JMS provider
      serverName String server name of the JMS provider
      portNumber String port number of the JMS provider
      networkProtocols String[] array of network protocols used to communicate with the JMS provider
      serverNames String[] array of server names of the JMS provider
      portNumbers String[] array of port numbers of the JMS provider
      url String Opaque string which defines how to connect to the JMS provider
      clientId String JMS client identifier
      • ConnectionFactory properties follow the convention specified for properties of JavaBeans components in the JavaBeans 1.01 Specification. ConnectionFactory implementations may augment this set with implementation-specific properties. If new properties are added, they must be given names that do not conflict with the
        standard property names.
      • ConnectionFactory implementations must provide "getter" and "setter" methods for each property they support. These properties typically are intended to be initialized before the object is bound in JNDI for subsequent use by an application.
      • ConnectionFactory properties are not intended to be directly accessible by JMS clients. This design is reinforced by defining the access methods on the implementation class rather than on the public DataSource interface used by applications. Furthermore, the object that the client manipulates can be a wrapper that only
        implements the ConnectionFactory interface. The setter and getter methods for the properties need not be exposed to the client.
      • Management tools that need to manipulate the properties of a ConnectionFactory implementation can access those properties using introspection.

      Note that this gives three alternative ways to define how the connection factory should communicate with the server:

      • an opaque URL string
      • a tuple of (networkProtocol, serverName, portNumber), where networkProtocol may be omitted
      • an array of such tuples, represented here as three separate arrays

      A JMS provider may support all, some or none of these alternatives.

      • If both URL and one of the other forms are supported and both are supplied, the URL is used.
      • If the single tuple (networkProtocol, serverName, portNumber) is supported, then a single-element array of tuples will also be supported

      (Much of the wording above is based on section 9.4.1 DataSource properties of the JDBC 4.0 specification.)

      Please also see the following additional information which has been added as separate notes below:

      • How JDBC DataSource objects are configured
      • Relevant sections of the JMS 1.1 Specification

        Activity

        Hide
        Nigel Deakin added a comment -

        How JDBC DataSource objects are configured

        This section describes how, although JDBC DataSource objects are similar in concept to JMS ConnectionFactory objects, the JDBC and Java EE specifications define in much more detail how DataSource objects are created and configured than the JMS specification defines for ConnectionFactory objects.

        A JMS ConnectionFactory is a factory for creating connections to a JMS provider, using the createConnection method. In JDBC, a javax.jdbc.DataSource fulfils a similar role as a factory for creating connections to a JDBC database, using the getConnection method.

        Section 9.4.2 recommends that javax.jdbc.DataSource objects are stored in JNDI to allow database-specific configuration to be kept separate from the application. This much is similar to JMS.

        However the JNDI specification differs from JMS in providing a lot of guidance on how to create a DataSource. Section 9.4.1 contains a whole list of standard data source properties which may be supported:

        • databaseName
        • dataSourceName
        • description
        • networkProtocol
        • password
        • portNumber
        • roleName
        • serverName
        • user

        Although the specification suggests that not all DataSource implementations support all properties, it does define names for these most common properties, and specifies that when supported, they must be configurable using standard JavaBeans "setters and getters".

        In addition, a DataSource may be instantiated by invoking its no-arg constructor. This isn't stated explicitly in the spec (if the DataSource were a JavaBean then a no-arg constructor would be mandatory, but the spec only states that its properties follow the conventions specified for properties of JavaBeans, not that a DataSource is itself a JavaBean) but in practice the convention that it can is well-established.

        This means that a DataSource may be instantiated, given the name of the implementation class as a String, using code of the following form:

        DataSource ds = Class.forName("oracle.jdbc.pool.OracleDataSource") 
        

        Meanwhile, the Java EE 6 specification defines a DataSourceDefinition annotation and a corresponding <data-source> element which defines the following properties of a DataSource:

        • className (required)
        • name (required)
        • databaseName
        • description
        • initialPoolSize
        • isolationLevel
        • loginTimeout
        • maxIdleTime
        • maxPoolSize
        • maxStatements
        • minPoolSize
        • password
        • portNumber
        • properties
        • serverName
        • transactional
        • url
        • user

        This is a longer list than is defined in JDBC, partly because the JDBC spec is older, but also because it also includes pooling properties. Perhaps of the most interest is the url property, which may be provided as an alternative to serverName and port.

        Show
        Nigel Deakin added a comment - How JDBC DataSource objects are configured This section describes how, although JDBC DataSource objects are similar in concept to JMS ConnectionFactory objects, the JDBC and Java EE specifications define in much more detail how DataSource objects are created and configured than the JMS specification defines for ConnectionFactory objects. A JMS ConnectionFactory is a factory for creating connections to a JMS provider, using the createConnection method. In JDBC, a javax.jdbc.DataSource fulfils a similar role as a factory for creating connections to a JDBC database, using the getConnection method. Section 9.4.2 recommends that javax.jdbc.DataSource objects are stored in JNDI to allow database-specific configuration to be kept separate from the application. This much is similar to JMS. However the JNDI specification differs from JMS in providing a lot of guidance on how to create a DataSource . Section 9.4.1 contains a whole list of standard data source properties which may be supported: databaseName dataSourceName description networkProtocol password portNumber roleName serverName user Although the specification suggests that not all DataSource implementations support all properties, it does define names for these most common properties, and specifies that when supported, they must be configurable using standard JavaBeans "setters and getters". In addition, a DataSource may be instantiated by invoking its no-arg constructor. This isn't stated explicitly in the spec (if the DataSource were a JavaBean then a no-arg constructor would be mandatory, but the spec only states that its properties follow the conventions specified for properties of JavaBeans, not that a DataSource is itself a JavaBean) but in practice the convention that it can is well-established. This means that a DataSource may be instantiated, given the name of the implementation class as a String, using code of the following form: DataSource ds = Class.forName("oracle.jdbc.pool.OracleDataSource") Meanwhile, the Java EE 6 specification defines a DataSourceDefinition annotation and a corresponding <data-source> element which defines the following properties of a DataSource: className (required) name (required) databaseName description initialPoolSize isolationLevel loginTimeout maxIdleTime maxPoolSize maxStatements minPoolSize password portNumber properties serverName transactional url user This is a longer list than is defined in JDBC, partly because the JDBC spec is older, but also because it also includes pooling properties. Perhaps of the most interest is the url property, which may be provided as an alternative to serverName and port .
        Hide
        Nigel Deakin added a comment -

        Relevant sections of the JMS 1.1 Specification

        The relevant sections of the JMS specification are given below:

        Section 2.3 Administration

        It is expected that JMS providers will differ significantly in their underlying messaging technology. It is also expected there will be major differences in how a provider’s system is installed and administered.

        If JMS clients are to be portable, they must be isolated from these proprietary aspects of a provider. This is done by defining JMS administered objects that are created and customized by a provider's administrator and later used by clients. The client uses them through JMS interfaces that are portable. The administrator creates them using provider-specific facilities.

        There are two types of JMS administered objects:

        • ConnectionFactory - This is the object a client uses to create a connection with a provider.
        • Destination - This is the object a client uses to specify the destination of messages it is sending and the source of messages it receives.

        Administered objects are placed in a JNDI namespace by an administrator. A JMS client typically notes in its documentation the JMS administered objects it requires and how the JNDI names of these objects should be provided to it.

        Section 4.2 Administered Objects

        JMS administered objects are objects containing JMS configuration information that are created by a JMS administrator and later used by JMS clients. They make it practical to administer JMS applications in the enterprise.

        Although the interfaces for administered objects do not explicitly depend on JNDI, JMS establishes the convention that JMS clients find them by looking them up in a namespace using JNDI.

        An administrator can place an administered object anywhere in a namespace. JMS does not define a naming policy.

        This strategy of partitioning JMS and administration provides several benefits:

        • It hides provider-specific configuration details from JMS clients.
        • It abstracts JMS administrative information into Java objects that are easily organized and administered from a common management console.
        • Since there will be JNDI providers for all popular naming services, this means JMS providers can deliver one implementation of administered objects that will run everywhere.

        An administered object should not hold on to any remote resources. Its lookup should not use remote resources other than those used by JNDI itself.

        Clients should think of administered objects as local Java objects. Looking them up should not have any hidden side effects or use surprising amounts of local resources.

        JMS defines two administered objects, Destination and ConnectionFactory.

        It is expected that JMS providers will provide the tools an administrator needs to create and configure administered objects in a JNDI namespace. JMS provider implementations of administered objects should be both javax.naming.Referenceable and java.io.Serializable so that they can be stored in all JNDI naming contexts. In addition, it is recommended that these implementations follow the JavaBeans design patterns.

        Section 1.4.6 Java Naming and Directory InterfaceTM (JNDI) API

        JMS clients look up configured JMS objects using the JNDI API. JMS administrators use provider-specific facilities for creating and configuring these objects.

        This division of work maximizes the portability of clients by delegating provider-specific work to the administrator. It also leads to more administrable applications because clients do not need to embed administrative values in
        their code.

        Section 4.3.2 Client Identifier

        The preferred way to assign a client’s client identifier is for it to be configured in a client-specific ConnectionFactory and transparently assigned to the connection it creates.

        Show
        Nigel Deakin added a comment - Relevant sections of the JMS 1.1 Specification The relevant sections of the JMS specification are given below: Section 2.3 Administration It is expected that JMS providers will differ significantly in their underlying messaging technology. It is also expected there will be major differences in how a provider’s system is installed and administered. If JMS clients are to be portable, they must be isolated from these proprietary aspects of a provider. This is done by defining JMS administered objects that are created and customized by a provider's administrator and later used by clients. The client uses them through JMS interfaces that are portable. The administrator creates them using provider-specific facilities. There are two types of JMS administered objects: • ConnectionFactory - This is the object a client uses to create a connection with a provider. • Destination - This is the object a client uses to specify the destination of messages it is sending and the source of messages it receives. Administered objects are placed in a JNDI namespace by an administrator. A JMS client typically notes in its documentation the JMS administered objects it requires and how the JNDI names of these objects should be provided to it. Section 4.2 Administered Objects JMS administered objects are objects containing JMS configuration information that are created by a JMS administrator and later used by JMS clients. They make it practical to administer JMS applications in the enterprise. Although the interfaces for administered objects do not explicitly depend on JNDI, JMS establishes the convention that JMS clients find them by looking them up in a namespace using JNDI. An administrator can place an administered object anywhere in a namespace. JMS does not define a naming policy. This strategy of partitioning JMS and administration provides several benefits: • It hides provider-specific configuration details from JMS clients. • It abstracts JMS administrative information into Java objects that are easily organized and administered from a common management console. • Since there will be JNDI providers for all popular naming services, this means JMS providers can deliver one implementation of administered objects that will run everywhere. An administered object should not hold on to any remote resources. Its lookup should not use remote resources other than those used by JNDI itself. Clients should think of administered objects as local Java objects. Looking them up should not have any hidden side effects or use surprising amounts of local resources. JMS defines two administered objects, Destination and ConnectionFactory . It is expected that JMS providers will provide the tools an administrator needs to create and configure administered objects in a JNDI namespace. JMS provider implementations of administered objects should be both javax.naming.Referenceable and java.io.Serializable so that they can be stored in all JNDI naming contexts. In addition, it is recommended that these implementations follow the JavaBeans design patterns. Section 1.4.6 Java Naming and Directory InterfaceTM (JNDI) API JMS clients look up configured JMS objects using the JNDI API. JMS administrators use provider-specific facilities for creating and configuring these objects. This division of work maximizes the portability of clients by delegating provider-specific work to the administrator. It also leads to more administrable applications because clients do not need to embed administrative values in their code. Section 4.3.2 Client Identifier The preferred way to assign a client’s client identifier is for it to be configured in a client-specific ConnectionFactory and transparently assigned to the connection it creates.
        Hide
        Nigel Deakin added a comment -

        I am withdrawing this proposal in favour of a simpler alternative. To avoid confusion I have logged this as a separate issue, JMS_SPEC-89

        Show
        Nigel Deakin added a comment - I am withdrawing this proposal in favour of a simpler alternative. To avoid confusion I have logged this as a separate issue, JMS_SPEC-89

          People

          • Assignee:
            Unassigned
            Reporter:
            Nigel Deakin
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: