Show TOC

Procedure documentationAccessing JMS Resources Locate this document in the navigation structure

 

In Java Message Service (JMS) there are two types of JMS resources: connection factories and destinations. To use the Java Message Service in Java EE applications such as application clients, enterprise beans or Web components, you need an access to these resources. That is why the Java EE application clients, enterprise beans and Web components have access to a JNDI naming environment. For each application component type there is a container that provides the naming environment, that is, it supplies the resources needed for the applications.

The application components' naming environment is a mechanism that allows you to customize the application components' business logic during deployment. In this way you do not need to access or change the application components' source code each time you want to customize the application component.

The container provides the application components' environment to the application components instance as a JNDI naming context. All JMS resources (including connection factories and destinations) are organized in the java:comp/env/ subcontext of the application component's environment. You have to append the name of the resource in the <name> tag in the jms-resources.xml to the java:comp/env in the source code of the application. For example, if you have specified <name>jms/test_connection_factory</name> in the jms-resources.xml, in the source code you have:

Syntax Syntax

  1. ConnectonFactory ConnectionFactory = (ConnectionFactory) 
    
    context.lookup("java:comp/env/jms/test_connection_factory");
    
End of the code.

You can access the required resources:

  • using injection (via the @Resource annotation or via deployment descriptors of the component (ejb-jar.xml, web.xml, application-client.xml))

  • using a JNDI lookup in the source code of the application.

Recommendation Recommendation

  • We recommend that you use the @Resource annotation to inject JMS resources in your application. This way the container takes care of supplying the resources.

  • We recommend that you do not use the mappedName attribute because it is SAP-specific.

End of the recommendation.

Procedure

Accessing JMS Resources Using the @Resource Annotation

Using the @Resource annotation on a field or method level, you directly inject the JMS resources into the component, avoiding the need for a JNDI lookup. If you use this annotation on a class level, you only check in the naming if the resource that you want to use exists. The container injects the resource specified by the @Resource annotation into the component when the component is being initialized. If you use the @Resource annotation on a field/method level, the container injects the resource when the application is being initialized. If you use the @Resource annotation on a class level, the resource is looked up by the application at runtime.

The @Resource annotation has the following properties:

  • name: this is the JNDI name of the connection factory or destination (without the "java:comp/env" prefix).

  • type: this is the Java language type of the resource, for connection factories the types are: javax.jms.QueueConnectionFactory and javax.jms.TopicConnectionFactory, for destinations the types are: javax.jms.Queue and javax.jms.Topic.

    Note Note

    SAP NetWeaver AS Java does not support the javax.jms.Destination type.

    End of the note.
  • autheticationType: this property is valid only for connection factories and specifies the authentication type of the connection factory. By default it is CONTAINER.

  • shareable: this property is valid only for connection factories and indicates whether the connection factory can be shared. By default it is SHAREABLE.

  • mappedName: this is the implementation-specific JNDI name to which the resource should be mapped.

  • description: this is a description of the resource.

In the following example the @Resource annotation is used on a field level, which means that the resources are injected without a preliminary check in the naming.

Syntax Syntax

  1. package com.sap.examples.jms.annotation;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.annotation.Resource;
    import javax.jms.Topic;
    import javax.jms.ConnectionFactory;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class AnnotationExampleServlet extends HttpServlet implements javax.servlet.Servlet {
    
    	@Resource(name = "jms/AnnotationConnectionFactory")
    	private ConnectionFactory topicCF;
    
    	@Resource(name = "jms/AnnotationTopic")
    	private Topic topic;
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    		throws ServletException, IOException {
    		doIt(request, response);
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    		throws ServletException, IOException {
    		doIt(request, response);
    	}
    
    	private void doIt(HttpServletRequest request, HttpServletResponse response)
    		throws ServletException, IOException {
    		final PrintWriter out = response.getWriter();
    		out.println("TCF: " + topicCF);
    		out.println("<br />Topic: " + topic);
    	}
    }
    
End of the code.
Accessing JMS Resources Using a JNDI Lookup
1. Obtain the initial context

Specify the initial context factory. You need a provider URL and the security properties required to obtain the initial JNDI context.

Syntax Syntax

  1. java.util.Properties properties = new Properties();
    
    // set the properties of the connection
    properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sap.engine.services.jndi.InitialContextFactoryImpl");
    properties.put(Context.PROVIDER_URL, "localhost:50004");
    properties.put(Context.SECURITY_PRINCIPAL, "Administrator");
    properties.put(Context SECURITY_CREDENTIALS, "administrator_access_password");
    
    // start the initial context with the specified properties
    InitialContext context = new InitialContext(properties);
    
End of the code.

The properties that have to be set may differ depending on the client type. For example, internal clients of the server (in other words, clients deployed on it) do not need to specify any properties, while external (remote) clients have to specify additional properties.

2. Look up a connection factory

The JMS Provider has predefined the following (default) connection factories:

  • ConnectionFactory

    A generic factory, introduced in JMS 1.1 as part of the domain unification. Enables you to create generic connections that can work with both queues and topics.

  • TopicConnectionFactory

    Enables you to create topic connections.

  • QueueConnectionFactory

    Enables you to create queue connection.

  • XAConnectionFactory

    A generic factory for XA transactions enabled connections. Introduced in JMS 1.1 as part of the domain unification. Enables you to create generic XA-enabled connections that can work with both queues and topics.

  • XATopicConnectionFactory

    Enables you to create XA transaction-enabled topic connections.

  • XAQueueConnectionFactory

    Enables you to create XA transaction-enabled queue connections.

To perform a lookup operation, you also need a resource reference entry for the relevant administered object in the deployment descriptor of the component that looks up the object:

  • Declare a JMS connection factory in the <res-ref-name>jms/AnnotationConnectionFactory</res-ref-name> element of the standard deployment descriptor for the relevant application component. The name that you specify in the <res-ref-name> tag is the name used for the lookup operation.

    More information about the additional deployment descriptors:

  • Declare a JMS Destination resource in the <res-env-ref-name> element of the standard deployment descriptor of the application component (ejb-jar.xml, web.xml, application-client.xml). The name that you specify in the <res-env-ref-name> tag is the name used for the lookup operation.

To look up a connection factory, use the following code:

Syntax Syntax

  1. ConnectonFactory ConnectionFactory = (ConnectionFactory) context.lookup("java:comp/env/<res-ref-name>");
    
End of the code.
3. Look up a destination

To look up a destination, for example a queue, use the following code:

Syntax Syntax

  1. Queue queue = (Queue) context.lookup("java:comp/env/<res-env-ref-name>");
    
End of the code.