Skip to main content

openmq C client to glassfish jms

12 replies [Last post]
rrlangly
Offline
Joined: 2012-06-25
Points: 0

I hope this is the right place to ask.

My standalone client is the producer example from openmq-4.5.2, C on linux 64. The other endpoint is glassfish 3.1.2 which runs OpenMQ as well.

I start the glassfish server, then run the client, and it all runs, but I don't see my message-driven bean receiving anything, however, if I use a JMS standalone client, it does successfully trigger messages to my MDB.

I get no errors with the C client. But I don't see that it triggers the MDB either.

I've configured:
- JMS Resources, destination and connection factories through the glassfish console.
- added user/pass to the instance within glassfish (imqusermgr add -u -p
)

Anyone have any other ideas what might be going on? I'm sure I'm using the correct destinations, ports, etc...

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
liang.x.zhao
Offline
Joined: 2011-12-18
Points: 0

Hi,

Can you upload your glassfish domain.xml and your c client source code for review?

Thanks,
David Zhao

rrlangly
Offline
Joined: 2012-06-25
Points: 0

Here's the code which is basically the producer examples as shipped w/ openmq. What domain.xml file are you referring to in glassfish? I never added this file.

MQStatus producer(char *dname, MQDestinationType dtype)
{
    MQStatus status;
    MQSessionHandle session_handle = MQ_INVALID_HANDLE;
    MQDestinationHandle dhandle = MQ_INVALID_HANDLE;
    MQProducerHandle producer_handle = MQ_INVALID_HANDLE;
    MQMessageHandle message_handle = MQ_INVALID_HANDLE;

    MQ_ERR_CHK(MQCreateSession(g_conn_handle, MQ_FALSE,
        MQ_CLIENT_ACKNOWLEDGE, MQ_SESSION_SYNC_RECEIVE, &session_handle));
   
    MQ_ERR_CHK(MQCreateDestination(session_handle,
        dname, dtype, &dhandle));

    MQ_ERR_CHK(MQCreateMessageProducerForDestination(session_handle,
        dhandle, &producer_handle));

    MQ_ERR_CHK(MQFreeDestination(dhandle));

    MQ_ERR_CHK(MQCreateTextMessage(&message_handle));

    while(1) {
        char text[128];

        printf("Enter a message to send:\n");

        if (fgets(text, 128, stdin) == NULL) {
            break;
        }
       
        if ((strlen(text) == 0)) {
            break;
        }
       
        printf("Sending message: %s\n", text);

        MQ_ERR_CHK(MQSetTextMessageText(message_handle, text));
        MQ_ERR_CHK(MQSendMessage(producer_handle, message_handle));
    }

    MQ_ERR_CHK(MQSetTextMessageText(message_handle, "END"));
    MQ_ERR_CHK(MQSendMessage(producer_handle, message_handle));

    MQ_ERR_CHK(MQFreeMessage(message_handle));
   
    MQ_ERR_CHK(MQCloseConnection(g_conn_handle));
    MQ_ERR_CHK(MQFreeConnection(g_conn_handle));

    return status;

out:
    {
        MQString err_string = MQGetStatusString(status);
        fprintf(stderr, "producer(): Error: %s\n",
            (err_string == NULL) ? "NULL" : err_string);

        MQFreeString(err_string);
    }

    MQFreeMessage(message_handle);
    MQFreeDestination(dhandle);
    MQCloseConnection(g_conn_handle);
    MQFreeConnection(g_conn_handle);

    return status;
}

MQStatus create_connection(char *bhost, int bport) {
    MQStatus status;
    MQPropertiesHandle props_handle = MQ_INVALID_HANDLE;

    MQ_ERR_CHK(MQCreateProperties(&props_handle));

    MQ_ERR_CHK(MQSetStringProperty(props_handle,
        MQ_BROKER_HOST_PROPERTY, bhost));
    MQ_ERR_CHK(MQSetInt32Property(props_handle,
        MQ_BROKER_PORT_PROPERTY, bport));
    MQ_ERR_CHK(MQSetStringProperty(props_handle,
        MQ_CONNECTION_TYPE_PROPERTY, "TCP"));

    // Also ran ... imqusermgt add -u test -p test
    MQ_ERR_CHK(MQCreateConnection(props_handle, "test", "test", NULL,
        NULL, NULL, &g_conn_handle));

    MQ_ERR_CHK(print_version());

    return status;

out:
    {  
        MQString err_string = MQGetStatusString(status);
        fprintf(stdout, "create_connection(): Error: %s\n",
            (err_string == NULL) ? "NULL" : err_string);

        MQFreeString(err_string);
    }
   
    MQFreeProperties(props_handle);

    return status;
}

And here is where I call from my main function ...

    
    if (MQStatusIsError(create_connection(bhost, bport))) {
        return 1;
    }
   
    if (MQStatusIsError(producer(dname, dtype))) {
        return 1;
    }

And here is my MDB running in Glassfish ...

@MessageDriven( mappedName = "jms/MyTestQueue")
public class TestMessageListener implements MessageListener {
    private TextMessage txtMsg = null;

    public TestMessageListener() { }

    public void onMessage(Message msg) {
        System.out.println("TestMessageListener test");

        try {
            TextMessage tmsg = (TextMessage) msg;
           
            System.out.println("Received msg " + tmsg.getText());
           
            // i know this prop doesn't exist yet in client
            String str = msg.getStringProperty("my-type");
            System.out.println("Received msg " + msg + ", from " + str);
        }
        catch (JMSException e) {
            throw new RuntimeException(e);
        }
    }
}
nigeldeakin
Offline
Joined: 2007-10-12
Points: 0

Are you sure your C program is sending messages to the correct queue?

Undeploy your MDB and then use your JMS standalone program to send some messages to the queue. Then use the command
imqcmd lst dst
to list the queues and the count of messages in each queue.
(The imqcmd command is in glassfish3/mq/bin)

Then use your C client and run imqcmd again to see if the messages have arrived in the same queue or in a different queue.

Nigel

rrlangly
Offline
Joined: 2012-06-25
Points: 0

So I start glassfish, and my MDB's are undeployed. When trying to list the destinations, I get the following error.

glassfish3/mq/bin$ imqcmd list dst
Username: tester
Password:
Listing all the destinations on the broker specified by:

-------------------------
Host         Primary Port
-------------------------
localhost    7676

Error while connecting to the broker on host 'localhost' and port '7676'.
com.sun.messaging.jms.JMSSecurityException: [C4084]: User authentication failed:  user=tester, broker=localhost:7676(45807)
Please check your security configurations.

Listing destinations failed.

And in this log file ... glassfish3/glassfish/domains/domain1/imq/instances/imqbroker/log, I get this error ...

[10/Sep/2012:11:20:36 GMT-06:00] WARNING [B2040]: Service admin[ADMIN] access denied - [B4051]: Forbidden tester, :
java.security.AccessControlException: [B4051]: Forbidden tester,
[10/Sep/2012:11:20:36 GMT-06:00] [B1066]:   Closing: ???@127.0.0.1:0->admin:0 because "java.io.IOException: Stream closed". Count: service=0 broker=0

I did create the user 'tester' and a passwd w/ the imqusermgr command.

glassfish3/mq/bin$ imqusermgr list                   
User repository for broker instance: imqbroker
--------------------------------------
User Name    Group        Active State
--------------------------------------
admin        admin        true
guest        anonymous    true
tester        user         true

Any ideas?

nigeldeakin
Offline
Joined: 2007-10-12
Points: 0

There's little I can add to the error message: you need to supply a valid username and password. Try using the admin user/password.

rrlangly
Offline
Joined: 2012-06-25
Points: 0

So I set a passwd to admin which allows me to view these details. Thanks.

Ok, I can now see the queue count rise when I use either the C or Java standalone client and with MDBs undeployed. The difference is that w/ the Java app, the physical destination name of the queue increments the count (even though I have the MDB annotation to the JNDI name) whereas with the C client I have to use the physical destination. And thats the way I get it to work.

I was thinking I must have the factories or resources not configured properly? One thing I don't understand is that when I add a Destination Resource, it also shows up under Connection Factories. However, if I expand Connection Factories and click on that same destionation resource, it shows up with a message ...

An error has occurred.
An error occurred while processing the request. Please see the server logs for details.

And the server.log shows ...

[#|2012-09-10T14:07:12.549-0600|SEVERE|glassfish3.1.2|org.glassfish.admingui|_Th
readID=20;_ThreadName=Thread-2;|RestResponse.getResponse() gives FAILURE.  endpo
int = 'http://localhost:4848/management/domain/resources/connector-connection-po
ol/jms%2FmyQueue'; attrs = '{}'|#]

[#|2012-09-10T14:07:12.549-0600|INFO|glassfish3.1.2|org.glassfish.admingui|_Thre
adID=20;_ThreadName=Thread-2;|Exception Occurred :java.lang.RuntimeException: |#
]

[#|2012-09-10T14:07:12.551-0600|SEVERE|glassfish3.1.2|com.sun.jersey.spi.contain
er.ContainerResponse|_ThreadID=22;_ThreadName=Thread-2;|The RuntimeException cou
ld not be mapped to a response, re-throwing to the HTTP container
java.lang.NullPointerException
        at org.glassfish.admin.rest.resources.PropertiesBagResource.setParentAnd
TagName(PropertiesBagResource.java:278)
        at org.glassfish.admin.rest.resources.generatedASM.ConnectorConnectionPo
olResource.getPropertiesBagResource(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.invokeSubLocator(
SubLocatorRule.java:171)
        at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocator
Rule.java:107)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHa
ndPathRule.java:147)
        at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocator
Rule.java:134)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocatorRule.java:134)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocatorRule.java:134)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
        at com.sun.jersey.server.impl.container.grizzly.GrizzlyContainer._service(GrizzlyContainer.java:182)
        at com.sun.jersey.server.impl.container.grizzly.GrizzlyContainer.service(GrizzlyContainer.java:147)
        at org.glassfish.admin.rest.adapter.RestAdapter.service(RestAdapter.java:148)

        at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:179)
        at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
        at com.sun.enterprise.v3.services.impl.ContainerMapper$Hk2DispatcherCallable.call(ContainerMapper.java:354)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
        at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
        at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
        at java.lang.Thread.run(Thread.java:662)
|#]

[#|2012-09-10T14:07:12.554-0600|SEVERE|glassfish3.1.2|org.glassfish.admingui|_ThreadID=20;_ThreadName=Thread-2;|RestResponse.getResponse() gives FAILURE.  endpoint = 'http://localhost:4848/management/domain/resources/connector-connection-pool/jms%2FmyQueue/property.json'; attrs = '{}'|#]
mgainty
Offline
Joined: 2004-05-21
Points: 0

the c client manipulates resources on the OS (files, sockets whatever resource on OS) directly ..that is why you have direct control..also the reason why its prone to errror
Java Factories will create stub clients to extend abstract classes and implement interfaces based on those same attributes that you use to directly access those OS resources
JNDI is a JDNIname to RealNameResource set of mappings which appservers use to lookup the RealNameResource (based on the JNDIname)
so..
what does the message in the server.log say?

Martin Gainty
______________________________________________
Verzicht und Vertraulichkeitanmerkung/Note de déni et de confidentialité

Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht dient lediglich dem Austausch von Informationen und entfaltet keine rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.
Ce message est confidentiel et peut être privilégié. Si vous n'êtes pas le destinataire prévu, nous te demandons avec bonté que pour satisfaire informez l'expéditeur. N'importe quelle diffusion non autorisée ou la copie de ceci est interdite. Ce message sert à l'information seulement et n'aura pas n'importe quel effet légalement obligatoire. Étant donné que les email peuvent facilement être sujets à la manipulation, nous ne pouvons accepter aucune responsabilité pour le contenu fourni.

> To: users@glassfish.java.net
> Subject: Re: openmq C client to glassfish jms
> From: forums@java.net
> Date: Mon, 10 Sep 2012 15:33:26 -0500
>
> So I set a passwd to admin which allows me to view these details. Thanks. Ok,
> I can now see the queue count rise when I use either the C or Java standalone
> client and with MDBs undeployed. The difference is that w/ the Java app, the
> physical destination name of the queue increments the count (even though I
> have the MDB annotation to the JNDI name) whereas with the C client I have to
> use the physical destination. And thats the way I get it to work. I was
> thinking I must have the factories or resources not configured properly? One
> thing I don't understand is that when I add a Destination Resource, it also
> shows up under Connection Factories. However, if I expand Connection
> Factories and click on that same destionation resource, it shows up with a
> message ... An error has occurred. An error occurred while processing the
> request. Please see the server logs for details.
>
> --
>
> [Message sent by forum member 'rrlangly']
>
> View Post: http://forums.java.net/node/889973
>
>

nigeldeakin
Offline
Joined: 2007-10-12
Points: 0

rrlangly wrote:

Ok, I can now see the queue count rise when I use either the C or Java standalone client and with MDBs undeployed. The difference is that w/ the Java app, the physical destination name of the queue increments the count (even though I have the MDB annotation to the JNDI name) whereas with the C client I have to use the physical destination. And thats the way I get it to work.

I don't completely follow. Have you confirmed that the C client and the Java standalone client are writing to the same queue?

You reported earlier that the Java standalone client will correctly trigger the MDB, so this is presumably correctly configured. You need to configure the C client to send to the same queue. Note that the C client uses the "physical destination name" of the queue, not the JNDI name.

rrlangly wrote:

I was thinking I must have the factories or resources not configured properly? One thing I don't understand is that when I add a Destination Resource, it also shows up under Connection Factories. However, if I expand Connection Factories and click on that same destination resource, it shows up with a message ...

If your JMS standalone client is able to trigger the MDB then it sounds as if the JNDI resources are configured correctly.

When you create a destination resource it is added under "Destination Resources", not "Connection Factories", which is what you would expect. I can't comment on what you are seeing or that error you get.

rrlangly
Offline
Joined: 2012-06-25
Points: 0

nigeldeakin wrote:

I don't completely follow. Have you confirmed that the C client and the Java standalone client are writing to the same queue?

Yes, I've confirmed that the C client and the Java standalone client are writing to the same queue.

nigeldeakin wrote:

You reported earlier that the Java standalone client will correctly trigger the MDB, so this is presumably correctly configured. You need to configure the C client to send to the same queue. Note that the C client uses the "physical destination name" of the queue, not the JNDI name.

It would seem that it is correctly configured because it works, yet when I click on the JNDI name under Connection Factories (which appeared after I configured it under Destination Resources), I see the yellow error panel message "An error has occured ...".

nigeldeakin wrote:

If your JMS standalone client is able to trigger the MDB then it sounds as if the JNDI resources are configured correctly.

Again, yes, it seems to be correctly configured because it works. Both my C and Java clients are not sending messages to my MDB. The problem now however is that I'm seeing something strange that I don't understand. When I click on the JNDI name under Connection Factories (which appeared after I configured it under Destination Resources), I see the yellow error panel message "An error has occured ...".

nigeldeakin wrote:

When you create a destination resource it is added under "Destination Resources", not "Connection Factories", which is what you would expect. I can't comment on what you are seeing or that error you get.

When I create the Destination Resources, it does appear under "Destination Resources", *and* a few seconds later it *also* appears under "Connection Factories" (aside from the connection factory that I also eventually create).

I take it this is not normal behavior?

nigeldeakin
Offline
Joined: 2007-10-12
Points: 0

rrlangly wrote:

I've confirmed that the C client and the Java standalone client are writing to the same queue.

rrlangly wrote:

Again, yes, it seems to be correctly configured because it works. Both my C and Java clients are not sending messages to my MDB.

This sounds contradictory. Earlier you said that your Java client was correctly triggering the MDB but now you say it doesn't. Please clarify! And what do you mean by "it works"?

I can't really help with the admin console errors you are seeing. But they key thing is making sure that your client, and your MDB, are using the same physical destination name. With the MDB you can't define the physical destination name directly - you define a JNDI "destination resource" which itself defines the physical destination name. Whereas with the C client you need to specify the physical destination name directly. And you can use imqcmd to see exactly what physical destination your messages are getting written to.

Nigel

rrlangly
Offline
Joined: 2012-06-25
Points: 0

Apologies, big typo from all the editing. That should read, "Again, yes, it seems to be correctly configured because it works. Both my C and Java clients *ARE* sending messages to my MDB."

By "it works", I mean that both clients (java and C) are sending to a queue. GF is receiving off the queue and the MDB is triggering.

I follow you with the rest of your reply, and all that makes sense. I don't understand the console error, but I'm sure something will eventually come out of it. But for now, it all works.

Thanks for the help.

nigeldeakin
Offline
Joined: 2007-10-12
Points: 0

(post deleted)