Can't install any of the three WMQ gems

Hello JRuby Community!

My environment:
jruby -v
jruby 1.7.3 (1.9.3p385) 2013-02-21 dac429b on IBM J9 VM
pap6470sr4fp1-20130325_01 (SR4 FP1) +indy [AIX-ppc64]

Attempting to install any of the following gems generate basically the
same errors:

rubywmq-2.0.2.gem
ferocia-rubywmq-2.0.6.gem
ekaranto-rubywmq-2.0.2.gem

Regardless of the gem, I get basically the same errors. For instance,
here is one of them.

Any assistance will be greatly appreciated.

Thank you

jgem install ekaranto-rubywmq-2.0.2.gem
Building native extensions. This could take a while…
ERROR: Error installing ekaranto-rubywmq-2.0.2.gem:
ERROR: Failed to build gem native extension.

    /opt/jruby/bin/jruby extconf.rb

/opt/jruby/lib/ruby/shared/mkmf.rb:14: Use RbConfig instead of obsolete
and deprecated Config.
checking for cmqc.h… no
checking for main() in -lmqm… no
Errno::ENOENT: ENOENT - /opt/mqm/inc/cmqc.h
initialize at org/jruby/RubyFile.java:333
open at org/jruby/RubyIO.java:1179
extract_const at
/opt/jruby/lib/ruby/gems/shared/gems/ekaranto-rubywmq-2.0.2/ext/generate/generate_reason.rb:6
reason_case at
/opt/jruby/lib/ruby/gems/shared/gems/ekaranto-rubywmq-2.0.2/ext/generate/generate_reason.rb:26
wmq_reason at
/opt/jruby/lib/ruby/gems/shared/gems/ekaranto-rubywmq-2.0.2/ext/generate/generate_reason.rb:70
each at org/jruby/RubyArray.java:1613
wmq_reason at
/opt/jruby/lib/ruby/gems/shared/gems/ekaranto-rubywmq-2.0.2/ext/generate/generate_reason.rb:68
generate at
/opt/jruby/lib/ruby/gems/shared/gems/ekaranto-rubywmq-2.0.2/ext/generate/generate_reason.rb:224
open at org/jruby/RubyIO.java:1183
generate at
/opt/jruby/lib/ruby/gems/shared/gems/ekaranto-rubywmq-2.0.2/ext/generate/generate_reason.rb:224
(root) at extconf.rb:27
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

Provided configuration options:
–with-opt-dir
–without-opt-dir
–with-opt-include
–without-opt-include=${opt-dir}/include
–with-opt-lib
–without-opt-lib=${opt-dir}/lib
–with-make-prog
–without-make-prog
–srcdir=.
–curdir
–ruby=/opt/jruby/bin/jruby
–with-mqm-dir
–without-mqm-dir
–with-mqm-include
–without-mqm-include=${mqm-dir}/include
–with-mqm-lib
–without-mqm-lib=${mqm-dir}/lib
–with-mqmlib
–without-mqmlib

Gem files will remain installed in
/opt/jruby/lib/ruby/gems/shared/gems/ekaranto-rubywmq-2.0.2 for
inspection.
Results logged to
/opt/jruby/lib/ruby/gems/shared/gems/ekaranto-rubywmq-2.0.2/ext/gem_make.out

Ariel,

Thank you for your reply.

The mqm.base.sdk is installed

Thank you

Looks like you are missing some additional packages e.g. mqm.base.sdk.

Also, is there a jruby specific gem distribution for this gem that uses
java instead of C?

Ariel V.
e-mail: [email protected]
website: http://blog.arielvalentin.com
skype: ariel.s.valentin
twitter: arielvalentin
linkedin: Sign Up | LinkedIn

*simplicity *communication
*feedback *courage *respect

Hi Eric,

Thank you for your reply.
I was able to install jruby-jms. However, I am not sure how this will
help me to connect to our current WMQ environment. I think, if I am not
mistaken, that you need a jms queue in order to connect using jms. I
looked at the samples provided by the author of jruby-jms and it appears
that he connects to ActiveMQ and not to WMQ. ActiveMQ I think belongs to
the Apache project, while WMQ is IBM. I can’t change the target
environment.

I wish I could get rubywmq working. But I don’t have the required skills
to get it done.

Again, thank you for your posting.

it should be possible to connect to MQ with JMS -

.

and if you use jruby you always just can fall back on java - it is quite
straight forward to use java from within your ruby files !!

maybe my 2 cents help

  • christian

Hi Ruby S… These WMQ libraries appear to be using the Native C
extension API of MRI, which is not supported in jruby. See
herehttps://github.com/reidmorrison/rubywmq#compatibilityThe author
appears to recommend
jruby-jms http://github.com/reidmorrison/jruby-jms as a JRuby Native
Java
alternative:

The example posted by Charles generates the following:

NameError: missing class or uppercase package name
(`com.ibm.mq.MQQueueManager’)
get_proxy_or_package_under_package at
org/jruby/javasupport/JavaUtilities.java:54
method_missing at
file:/opt/jruby/lib/jruby.jar!/jruby/java/java_package_module_template.rb:14
(root) at tmq01.rb:11

Any thought?

Thank you

right, I found some code below, however, have not yet been able t test
it

require ‘java’ # Optional on JRuby

define the name of the QueueManager

qmgr_name = “REID”

and define the name of the Queue

q_name = “SYSTEM.DEFAULT.LOCAL.QUEUE”

Create a connection to the QueueManager

puts "Connecting to queue manager: "+qmgr_name
qmgr = Java.com.ibm.mq.MQQueueManager.new qmgr_name
MQC = Java::com.ibm.mq.MQC # Reference (Shortcut) to MQC Constants Class

Set up the options on the queue we wish to open

openOptions = MQC::MQOO_INPUT_AS_Q_DEF | MQC::MQOO_OUTPUT

Now specify the queue that we wish to open and the open options

puts "Accessing queue: "+q_name
queue = qmgr.access_queue(q_name, openOptions)

Define a simple WebSphere MQ Message …

msg = Java::com.ibm.mq.MQMessage.new

… and write some text in UTF8 format

msg.writeUTF(“Hello, World!”)

Specify the default put message options

pmo = Java::com.ibm.mq.MQPutMessageOptions.new

Put the message to the queue

puts “Sending a message…”
queue.put(msg, pmo);

Now get the message back again. First define a WebSphere MQ message

to receive the data

rcvMessage = Java::com.ibm.mq.MQMessage.new

Specify default get message options

gmo = Java::com.ibm.mq.MQGetMessageOptions.new

Get the message off the queue.

puts “…and getting the message back again”
queue.get(rcvMessage, gmo)

And display the message text…

msgText = rcvMessage.readUTF
puts "The message is: " + msgText

Close the queue

puts “Closing the queue”
queue.close

Disconnect from the QueueManager

puts “Disconnecting from the Queue Manager”
qmgr.disconnect
puts “Done!”

Charles M.
[email protected]

Charles,

Thank you for your post. I truly appreciate it.
I still can’t get the damn thing to work. I am getting the same errors
as before.

I don’t know of the direct link to the JAR and SDK. Sorry about that.

I really wanted to get one of the three (rubywmq-2.0.2.gem,
ferocia-rubywmq-2.0.6.gem, ekaranto-rubywmq-2.0.2.gem) WMQ rapper
working because they appear to be kind of cleaner, simpler. But if the
only way to get to talk to WMQ is via the Java API, I guess I’ll try
that, although it is not working for me right now.

There must be someone using one of those three gems under jruby.
Hopefully, someone will see this post and will lend a hand. I really
would like to get this working.

Thank you

it might be that I believe that in current versions of Jruby one
specifies a Java fully qualified name as the following illustrates:

Java::javafx::scene::control::cell::MapValueFactory

i.e the :: ?

Hopefully, that’s it. Let me know how you do.

I actually have to get MQ running on Jruby ASAP, we now have an
immediate need . We usually go in via C. I need to download the JAR
file and try first thing in the morn.
BTW, if you know the “direct” link to that JAR and SDK I would
appreciate it.

thanks

Charles

Charles,

Could you give me the exact name of the files you need? You mentioned
IBM jar files and SDK, but if you give me the exact name I could look
around.

[email protected]

Thank you

well I’m on the same boat, I have to make it work soon, just having a
hard time getting my hands on the IBM jars, there registration site is
not functioning I even called IBM. I’ll try again.

If I figure it out, I’ll certainly share.

Charles

OK, I am able to at least load the code , that required having the IBM
jars including connector.jar in the Jruby load path which I simply did
by putting said jars in the jruby/lib folder. I have attached pic
listing those jars,see here:

http://www.screencast.com/t/LmWtqcLO

I’m also using the double colon semantics for referencing the MQ
entities e.g.

Java::com::ibm::mq::MQQueueManager

I’ll try exercising the code on Monday when I have a mq server
available.

Charles

Very kind.

I was able to secure at least some of the jars from our partners and I
believe I got past your load error. They did not give me all the jars
but just what I thought I needed , long story , I’m whittling myself
thru the jar dependencies i.e. with JRuby’s help i.e. as I try to load
my test source its kind enough to let me know what it think its missing.

Anyhow, once I get past the jar dependencies I’ll try to connect and do
a put and I’ll share my results. Bear with me, wont’ be able to test
connection until Monday.

Charles

Charles,

I’m glad it works for you. At least that shows that something really
works and it gives me the hope that I’ll get mine working in the near
future.

Just like you, I also copied all the com.ibm.mq.* to where jruby is
located.
Now I am getting a different error but very similar to the last one:

jruby tmq01.rb
NameError: wrong constant name ComIbmMq*
const_set at org/jruby/RubyModule.java:2621
get_proxy_or_package_under_package at
org/jruby/javasupport/JavaUtilities.java:54
method_missing at
file:/opt/jruby/lib/jruby.jar!/jruby/java/java_package_module_template.rb:14
(root) at tmq01.rb:3

Multiple google search uncovered nothing.
This is soooooooooooooo frustrating.

Anyway, good luck with your project. I’ll continue playing with this
until I get tired, which is very soon, I think.

but what does your code look like ?

What in your code is driving to that ?

If you don’t mind put up your code and I’ll try to run it under my setup

Charles M.
[email protected]

Charles,

I am trying a piece of sample code from the web. I have not even tried
anything else. I just want to see the damn thing connecting.

require ‘java’

define the name of the QueueManager

qmgr_name = “WMQPRDA1”

and define the name of the Queue

q_name = “SYSTEM.DEFAULT.LOCAL.QUEUE”

q_name = “TESTQ”

Create a connection to the QueueManager

puts "Connecting to queue manager: "+qmgr_name
qmgr = Java::com.ibm.mq.MQQueueManager.new qmgr_name
MQC = Java::com.ibm.mq.MQC # Reference (Shortcut) to MQC Constants Class

I ALSO TRIED:
require ‘java’ # Optional on JRuby

import com.ibm.mq.*

define the name of the QueueManager

qmgr_name = “WMQPRDA1”

and define the name of the Queue

q_name = “SYSTEM.DEFAULT.LOCAL.QUEUE”

q_name = “TESTQ”

Create a connection to the QueueManager

puts "Connecting to queue manager: "+qmgr_name
qmgr = Java::com.ibm.mq.MQQueueManager.new qmgr_name
MQC = Java::com.ibm.mq.MQC # Reference (Shortcut) to MQC Constants Class

I also tried:
import com.ibm.mq.commonservices.jar
import com.ibm.mq.defaultconfig.jar
import com.ibm.mq.headers.jar
import com.ibm.mq.jar
import com.ibm.mq.jmqi.jar
import com.ibm.mq.jms.Nojndi.jar
import com.ibm.mq.pcf.jar
import com.ibm.mq.postcard.jar
import com.ibm.mq.soap.jar
import com.ibm.mq.tools.ras.jar

MQEnvironment.hostname = “the.host.name”;
MQEnvironment.port = -1;

MQEnvironment.channel = “channel.name”;

MQQueueManager qMgr = new MQQueueManager(“TESTQ”);

I does not matter what I do, I get the errors I posted before.

Thank you

There must be someone using one of those three gems under jruby.

RubyStudent,

Unfortunately, its not currently possible. At least not easily. Those
three gems use MRIs C-Extension API, meaning some of the code in those
gems is written in Native C, instead of in Ruby, and uses the C
Extension
API to call functions in the C-code.

JRuby does not currently implement the C Extension API. JRuby has an
FFI
api that it uses for interacting with Native C libs, but this is not the
same thing. In the past there was an experimental support for
C-Extensions
in jruby but it has been removed because it had poor compatibility., and
was a lot of work to maintain.

Just as MRI (Matzs Ruby implementation) , which is written primarily in
C,
would not be able to integrate with Java libraries without using
something
to get the two talking to each other, JRuby, written in Java, cannot so
easily integrate with code written in C.

If you are using JRuby, you will need to find a Java way to interact
with
WMQ. It might be possible to fork one of those gems, write an FFI
wrapper
around the C-Extension, and get it working that way. Because the
C-Extension API and the FFI API are completely different, you will
probably
need to rewrite both the C code and the Ruby code. That sounds like a
good
deal of work

You should definitely be able to use the previously mentioned jruby-jms
gem
to interact with it though, as ibm definitely seems to provide a means
to
interact with jms on their
endhttp://pic.dhe.ibm.com/infocenter/wmqv7/v7r1/topic/com.ibm.mq.doc/zd00070_.htm.
If It were me, Id write a nice ruby wrapper around the IBM java
classes,
and wrap them in a way which would compose cleanly with the jruby-jms
gem.
If you do that, you should be able to write application code which is
just
as clean and simple as what rubywmq provides . To begin with, you
wouldnt
even need to write wrappers for every class, just the ones you needed to
work with for your application. This should certainly be easier than
trying
to write FFI layers for all those C files in the C-Extension gems.

There is also a second, non-JMS java
APIhttp://pic.dhe.ibm.com/infocenter/wmqv7/v7r1/topic/com.ibm.mq.doc/zd00050_.htmthat
IBM appears to provide, which seems to be what the above example
script is using. You may also find the following information useful:
WebSphere
MQ Using Java
http://www-05.ibm.com/e-business/linkweb/publications/servlet/pbi.wss?CTY=US&FNC=SRX&PBL=SC34659102

If you havent much experience interacting with Java from JRuby, I
recommend taking a look at Calling Java from
JRubyhttps://github.com/jruby/jruby/wiki/CallingJavaFromJRuby. Or
even better, reading the book Using
JRuby http://pragprog.com/book/jruby/using-jruby.

I hope this helps and that you now understand why you will probably not
find anyone using those gems from jruby.

The example posted by Charles generates the following:

NameError: missing class or uppercase package name

That indicates that com.ibm.mq.MQQueueManager, referenced in the code is
not on the classpath. You will need a jar containing the java class
MQQueueManager, from ibm, and you will need to either add it to the
classpath at the command line, or by requiring the jar in your code.
The information
herehttp://pic.dhe.ibm.com/infocenter/wmqv7/v7r1/topic/com.ibm.mq.doc/ja10320_.htmand
herehttp://pic.dhe.ibm.com/infocenter/wmqv7/v7r1/topic/com.ibm.mq.doc/ja10340_.htmshould
help you figure out where those jars are located in your system.
Then you can add them to your classpath either via the command line.
Also,
in order to get any of this to work, you also have to pass the library
path which the wmq classes
needhttp://pic.dhe.ibm.com/infocenter/wmqv7/v7r1/topic/com.ibm.mq.doc/ja10340_.htm.
This library path is different from the classpath, and tells java where
to
find the native libraries it needs which have been wrapped via JNI by
the
IBM java classes. You can get both classloader and java.library.path in
one
go by starting your script like this:

$ jruby -J-cp ‘.:/opt/mqm/java/lib/*:/opt/mqm/java/lib64’
-J-Djava.library.path=/opt/mqm/java/lib64 wmq.rb

Its also possible to use JRubys require to add jars to the Java
classpath. Unfortunately, there is no decent way to change the
java.library.path property programatically. The JVM essentially sets
this
property in stone on startup and even if you make changes to it, it wont
pick them up. (Trust me, Ive wasted hours on this in the past). You can
either pass it at the command line, as before, or set an ENV var (
LD_LIBRARY_PATHS) before running the script (yes, Ive tried setting the
ENV from the ruby code. Doesnt work.) So, heres how Id do it:

$ export LD_LIBRARY_PATH=“/opt/mqm/java/lib64/”
$ jruby wmq.rb

Then, in your ruby script, require the jars you need like this:

require ‘java’ # Optional on JRuby
require “pathname”
MQM_JAVA_PATH = "/opt/mqm/java"MQM_JAVA_JAR =
“#{MQM_JAVA_PATH}/lib/com.ibm.mq.jar”
require “#{MQM_JAVA_JAR}”

define the name of the QueueManager

qmgr_name = “QM_edub”# and define the name of the Queue
q_name = “SYSTEM.DEFAULT.LOCAL.QUEUE”

… the rest of the script

If you really need to figure out where those library classes are
dynamically, your best bet is to write a short script that finds them,
sets
the LD_LIBRARY_PATH ENV var, and then launches your real script either
in a
subprocess of some sort, or as a new process. Fairly easy in Bash.

Notice I changed the name of the QueuManager from what was referenced in
the script. This was another gotcha I found. The QueuManager in your
script
must be named for a running QueuManager instance.

I ran into a couple of other gotchas, just getting wmq installed and
running (Ubuntu 12.04 here). Ill describe below.

well Im on the same boat, I have to make it work soon, just having a
hard
time getting my hands on the IBM jars, there registration site is not
functioning I even called IBM. Ill try again.

Charles, I was able to register with IBM and download the WebSphere MQ
tarball via this link
http://www.ibm.com/developerworks/downloads/ws/wmq/. If you are
still having trouble with registration, the problem may be on
your end. I had to download the entire installation tarball, convert
them
from .rpm archives to .deb archives and install them with dpkg to get
them
working on Ubuntu (they seem to only have rpm installers available for
linux) (instructions were found
herehttp://www.howtogeek.com/howto/ubuntu/install-an-rpm-package-on-ubuntu-linux/
):

$ sudo apt-get install alien dpkg-dev debhelper build-essential

$ sudo alien --scripts MQSeriesRuntime-.rpm MQSeriesServer-.rpm
mqseriesruntime_7.5.0-3_amd64.deb generated
mqseriesserver_7.5.0-3_amd64.deb generated

$ sudo alien --scripts MQSeriesSDK-.rpm MQSeriesJava-.rpm
MQSeriesJRE-.rpm MQSeriesExplorer-.rpm MQSeriesMan-.rpm
MQSeriesGSKit-
.rpm MQSeriesSamples-*.rpm
mqseriessdk_7.5.0-3_amd64.deb generated
mqseriesjava_7.5.0-3_amd64.deb generated
mqseriesjre_7.5.0-3_amd64.deb generated
mqseriesexplorer_7.5.0-3_amd64.deb generated
mqseriesman_7.5.0-3_amd64.deb generated
mqseriesgskit_7.5.0-3_amd64.deb generated
mqseriessamples_7.5.0-3_amd64.deb generated

$ sudo dpkg -i mqseries*.deb

but once I did, the jar files were installed to /opt/mqm/java/lib.

You will need to add your user to the access group mqm. This differs
from
system to system, of course. On Ubuntu (likely all linuxs), its done
withhttp://www.cyberciti.biz/faq/ubuntu-add-user-to-group/
:

$ sudo usermod -a -G mqm edub

Dont leave out that -a or youll add yourself to mqm but simultaneously
remove yourself from every other group. This process will be totally
different on Windows and maybe OSX.
I think, for pretty much every OS
from
what I read, you will need to log out or reboot and log back in for WMQ
to
pick up this change. Wasted a bunch of time on that, personally.

I, personally, ran into this
issuehttp://www.mqseries.net/phpBB2/viewtopic.php?p=341321#341321,
so I will point it out to save you trouble. Only, I never saw anything
work, like some users in the thread. I just couldnt get anything running
at all, just saw that error in the log file (which are stored in
/var/mqm/errors on my machine, generally Ive found everything in either
/opt/mqm/ or /var/mqm/). The fix
suggestedhttp://www.mqseries.net/phpBB2/viewtopic.php?p=341324&sid=6849f10fb465eb496c1b7e346f537436#341324here
got me working.

One tricky point: if the computer being used has a dynamic ip, there are
issues related to the default cluster. If/when the ip changes, the
default
clusters repository cant be found by other queues in the cluster and
they
will need to be reconfigured with the new ip information. I found I had
to
delete the earlier cluster/queumanager and just try again.

@RubyStudent, @Charles:

So, I set out to try to quickly get the example script Charles shared
working, so I could set the two of you on the right path, and ended up
learning far more about QMG than I ever wanted and bruising my forehead
from banging it so much. The QMG documentation is very thorough, and yet
occasionally leaves out crucial details, QMGs error messages are often *
atrocious*, and quite difficult to google for, and the installation is
ridiculously complicated. QMG causes the user to configure it in
multiple
places, the environment, at the command line, in config files, and
programatically, as well as via GUI, and both during installation and at
runtime. In fact, I spent an initial hour or so on this out of goodwill.
I
want users to have a good experience with jruby and to be helpful. But I
only completed this and got it working out of sheer stubborness and
refusal
to quit. Note, my difficulties had little or nothing to do with java or
ruby or jruby, and were almost entirely related to QMG itself. It may be
an
awesome queuing system. I dont know much about it, really. But I think
getting comfortable enough with it to write code for it would require
very
careful and thorough reading of the
documentationhttp://pic.dhe.ibm.com/infocenter/wmqv7/v7r1/topic/com.ibm.mq.doc/help_home_wmq.htm.

Figuring out how to use the java api via jruby (whether you decide to
use
the jms api and use jruby-jms or the other), thats going to be the least
hardest part of the job you have ahead of you.

I hope that this is useful and that I saved you both some knee scrapes.

sorry, just thought of one more piece of advice, and then I will quit
spamming the mailinglist. though I complained about all the
configuration
options, including the GUI, the GUI tool WebSphere MQ Explorer, which
should be accessible as an app on your machine after you install all the
WMQ components, was super useful for figuring out a lot of stuff, and
would
probably be a very nice tool for learning more about WMQ and its API.
Especially the little postman app, which is a bit like a WMQ, GUI
netcat,
would be quite handy for testing out little scripts and stuff against.
postman can also be started via command line.

I should mention that all filepaths referenced in my examples are
specific
to my machine, and setup.