9

I can't get javax.jms.ConnectionFactory injected into my standalone JMS client. I get a java.lang.NullPointerException at connectionFactory.createConnection() in the code below.

JmsClient.java

public class JmsClient {

    @Resource(mappedName="jms/QueueConnectionFactory")
    private static ConnectionFactory connectionFactory;    

    @Resource(mappedName="jms/ShippingRequestQueue")
    private static Destination destination;

    public static void main(String[] args) {        
        try {
            Connection connection = connectionFactory.createConnection();
            connection.start();

            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = session.createProducer(destination);
            ObjectMessage message = session.createObjectMessage();

            ShippingRequestQueue shippingRequest = new ShippingRequestQueue(1, "107, Old Street");

            message.setObject(shippingRequest);
            producer.send(message);
            session.close();
            connection.close();

            System.out.println("Shipping request message sent ..");
        } catch (Throwable ex) {
            ex.printStackTrace();
        }        
    }

}

I have created the corresponding Connection Factory and Destination Resource at Open MQ (MoM) using Glassfish 3.1 Admin Console.

Could someone help me understand what am I missing?

MaDa
  • 10,511
  • 9
  • 46
  • 84
skip
  • 12,193
  • 32
  • 113
  • 153
  • 2
    `@Resource` doesn't work but looking up using JNDI name does. `Context jndiContext = new InitialContext(); ConnectionFactory connectionFactory = (ConnectionFactory) jndiContext.lookup("jms/QueueConnectionFactory"); Queue destination = (Queue) jndiContext.lookup("jms/ShippingRequestQueue");` – skip Sep 07 '11 at 08:11

2 Answers2

7

Resource injection works only in a managed environment, such as a Java EE application server, or a Spring container, for instance. In a standalone application JNDI is your only choice.

Annotations in general are meant to be processed by some tool/framework, and plain JVM that executes your main() method simply does not contain such. The only annotations I know of that are processed by JVM out of the box are compile-time @Deprecated, @Override and @SuppressWarnings.

Replying to your comment: I don't have access to the book, so I'll only guess that they probably describe running an application client component and not standalone application client. It's not the same — check Glassfish EJB FAQ. ACCs are normally deployed into an application server and can be executed via Java Web Start or without it, but in an AS-specific way. See Glassfish example (you didn't say what AS your EJB executes in).

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
MaDa
  • 10,511
  • 9
  • 46
  • 84
  • `public class ShippingRequestJMSProducer { @Resource(name = "jms/ShippingRequestQueue", mappedName = "ShippingRequestQueue") private static Destination destination; @Resource(name = "jms/QueueConnectionFactory") private static ConnectionFactory connectionFactory; public static void main(String[] args) { // rest of the code } } `. This is a part of the code from chapter 4 from the book **EJB 3 in Action**. Dependency injection of resources are being done in this standalone client. How does it work? – skip Oct 03 '11 at 07:05
  • Right. With **gf-client.jar** in build path you could only use the `lookup` method with JNDI name to get to resources. But for dependency injection to work in a standalone client it needs to be deployed to an EJB container to get that extra JavaEE juice. http://www.ensode.net/glassfish_rich_ejb_clients.html was useful. With Glassfish 3.1 `appclient -client myappclient.jar` works. Thanks. – skip Oct 03 '11 at 22:08
1

@skip: try @Resource(name="jms/QueueConnectionFactory") instead of @Resource(mappedName="jms/QueueConnectionFactory")

name=JNDI name as per javax.annotation.Resource java doc.

ag112
  • 5,537
  • 2
  • 23
  • 42
  • I tried `@Resource(lookup="jms/QueueConnectionFactory")` as well but still I am getting the same error as mentioned above as I am not able to get the resources injected. – skip Sep 19 '11 at 21:18
  • @skip, this is strange. Because if you look at link:- http://java.sun.com/javaee/5/docs/api/javax/annotation/Resource.html attribute name related to JNDI name. Did you try to resolve this JNDI name explicitly through NamingContext API? – ag112 Sep 20 '11 at 04:57
  • 1
    @ag112- I've tried server specific `mappedName`, portable `name` and the new 'lookup' from JavaEE 6 but I am not able to get the resource injected. Only way it worked was when I did the following: `Context jndiContext = new InitialContext(); ConnectionFactory connectionFactory = (ConnectionFactory) jndiContext.lookup("jms/QueueConnectionFactory"); Queue destination = (Queue) jndiContext.lookup("jms/ShippingRequestQueue");`. I've tried appending `java:comp/env` appended explicitly with the JNDI names above as well, which I shouldn't, but that doesn't work either. What am I missing here? – skip Sep 20 '11 at 14:08