jruby/jndi/ConnectionFactoryAdapter - and casting

Hello -

I have an interesting situation where I am taking a current script
(poller) and making to work via OpenMQ/jndi/glassfish - but being that
there is no casting it seems in j/ruby - I am curious on how to make
this work.

I have a jruby class - that in the initialize method is getting the
connection setup - similar to:

@ctx = InitialContext.new
@conn_factory = @ctx.lookup(“jms/ExtQueueConnectionFactory”)
@jms_connection = @conn_factory.create_connection()

But I need to be able to set properties on the factory - such as the
imqConsumerFlowLimit - but the ‘setProperty()’ method is on the
‘ConnectionFactory’ object - and the factory returned above is a
ConnectionFactoryAdapter (via jndi).

In Java - would do something similar to:

connectionFactory =
(QueueConnectionFactory)ctx.lookup(“jms/ExtQueueConnectionFactory”);

Then I could set the property I would need:

connectionFactory.setProperty(ConnectionConfiguration.imqConsumerFlowLimit,
“1”);

Does anyone know if there is a way around this - or a way to actually
cast in ruby/jruby?

Thanks.


Robert B. Weeks

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Why do you need to cast, exactly? Jruby & Ruby are untyped, so if the
method is there, even on a java object, it’ll be called (presumably by
introspection). Are there multiple signatures for setProperty? If so,
then I’m not sure how jruby decides which method to call.

So, you should just be able to do:

conn_factory = ctx.lookup(whatever_the_key_is)
conn_factory.setProperty(key_string, value_string)

Hope that helps,
Nick

On Fri, 2010-05-07 at 08:25 -0700, Robert W. wrote:

Does anyone know if there is a way around this - or a way to actually cast in ruby/jruby?


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hello -

Why do you need to cast, exactly? Jruby & Ruby are untyped, so if the
method is there, even on a java object, it’ll be called (presumably by
introspection). Are there multiple signatures for setProperty? If so,
then I’m not sure how jruby decides which method to call.

So, you should just be able to do:

conn_factory = ctx.lookup(whatever_the_key_is)
conn_factory.setProperty(key_string, value_string)

Correct - you would think that - but with jdni - the lookup does not
pull back the actual ConnectionFactory - but a ConnectionFactoryAdapter

  • which is usually cast to the actual ConnectionFactory (Queue/Topic,
    etc.) - to call the appropriate methods upon it.

The above does not work because ‘setProperty’ is not a part of the
ConnectionFactoryAdapter - but is available when you cast it to the
specific adapter needed.

For example - the what is returned from ‘conn_factory’ call above:

conn_factory: Java::ComSunMessagingJmsRa::ConnectionFactoryAdapter

It is pretty common to cast this to get access to the Factory specific
methods:

QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory)
jndiContext.lookup(“jms/QueueConnectionFactory”);

This is where my issue is - in that I cannot set (on a per connection
basis) the flow limit (or anything else really):

@ conn_factory.setProperty(ConnectionConfiguration.imqConsumerFlowLimit,
“1”)

Does not work at all:

 undefined method `setProperty' for 

#Java::ComSunMessagingJmsRa::ConnectionFactoryAdapter:0x4f124609
(NoMethodError)

Thanks.

I have a jruby class - that in the initialize method is getting the connection setup - similar to:
connectionFactory = (QueueConnectionFactory)ctx.lookup(“jms/ExtQueueConnectionFactory”);
Robert B. Weeks
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

AFAIK, casting in Java doesn’t actually change the underlying object, it
just gives you assurance at runtime that you have an object of the type
you are casting to, or you get a classcastexception. A google search
later and I can’t see this setProperty method on either
QueueConnectionFactory (Java 2 Platform Ent. Ed. v1.4) or
com.sun.messaging.jms.ra: public class: ConnectionFactoryAdapter

Perhaps your JNDI lookup is returning a different type of object to the
one you expect? What type actually has this setProperty method?

Cheers,
Nick

On Fri, 2010-05-07 at 09:42 -0700, Robert W. wrote:

conn_factory.setProperty(key_string, value_string)

Thanks.

I have an interesting situation where I am taking a current script (poller) and making to work via OpenMQ/jndi/glassfish - but being that there is no casting it seems in j/ruby - I am curious on how to make this work.
In Java - would do something similar to:

http://xircles.codehaus.org/manage_email

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hello again -

Thanks for replying.

AFAIK, casting in Java doesn’t actually change the underlying object, it
just gives you assurance at runtime that you have an object of the type
you are casting to, or you get a classcastexception.

It doesn’t change it particularly - but yes - allows you to have that
object type that it fits into - this issue being the perfect example.

I can do this if I just call a new on the ConnectionFactory - but that
removes accessing the factories via a pool - so isn’t what we want. The
jndi lookup is returning the generic adapter - which we then cast to
what we need if we need to access certain methods for that particular
one.

A google search
later and I can’t see this setProperty method on either
QueueConnectionFactory (Java 2 Platform Ent. Ed. v1.4)http://java.sun.com/j2ee/1.4/docs/api/javax/jms/QueueConnectionFactory.html
or
com.sun.messaging.jms.ra: public class: ConnectionFactoryAdapterhttp://www.docjar.com/docs/api/com/sun/messaging/jms/ra/ConnectionFactoryAdapter.html

These are the casts directly - the method is in there:

http://www.docjar.com/docs/api/com/sun/messaging/ConnectionFactory.html
http://www.docjar.com/docs/api/com/sun/messaging/QueueConnectionFactory.html

Perhaps your JNDI lookup is returning a different type of object to the
one you expect? What type actually has this setProperty method?

This is returning: Java::ComSunMessagingJmsRa::ConnectionFactoryAdapter

which is:

com.sun.messaging.ConnectionFactory
com.sun.messaging.QueueConnectionFactory

which is where the method is at - to set the properties in OpenMQ. This
is a common thing to do (casting of this sort) in java - so isn’t
anything new - but I cannot get this method at all without casting the
object returned into the correct implementation.

There is no way to set the properties on the ConnectionFactory that we
get out connection from without this cast here.

Thanks.

Cheers,
Nick

On Fri, 2010-05-07 at 09:42 -0700, Robert W. wrote:
Hello -

Why do you need to cast, exactly? Jruby & Ruby are untyped, so if the
method is there, even on a java object, it’ll be called (presumably by
introspection). Are there multiple signatures for setProperty? If so,
then I’m not sure how jruby decides which method to call.

So, you should just be able to do:

conn_factory = ctx.lookup(whatever_the_key_is)
conn_factory.setProperty(key_string, value_string)

Correct - you would think that - but with jdni - the lookup does not
pull back the actual ConnectionFactory - but a ConnectionFactoryAdapter

  • which is usually cast to the actual ConnectionFactory (Queue/Topic,
    etc.) - to call the appropriate methods upon it.

The above does not work because ‘setProperty’ is not a part of the
ConnectionFactoryAdapter - but is available when you cast it to the
specific adapter needed.

For example - the what is returned from ‘conn_factory’ call above:

conn_factory: Java::ComSunMessagingJmsRa::ConnectionFactoryAdapter

It is pretty common to cast this to get access to the Factory specific
methods:

QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory)
jndiContext.lookup(“jms/QueueConnectionFactory”);

This is where my issue is - in that I cannot set (on a per connection
basis) the flow limit (or anything else really):

@ conn_factory.setProperty(ConnectionConfiguration.imqConsumerFlowLimit,
“1”)

Does not work at all:

undefined method `setProperty' for 

#Java::ComSunMessagingJmsRa::ConnectionFactoryAdapter:0x4f124609
(NoMethodError)

Thanks.

Hope that helps,
Nick

On Fri, 2010-05-07 at 08:25 -0700, Robert W. wrote:
Hello -

I have an interesting situation where I am taking a current script
(poller) and making to work via OpenMQ/jndi/glassfish - but being that
there is no casting it seems in j/ruby - I am curious on how to make
this work.

I have a jruby class - that in the initialize method is getting the
connection setup - similar to:

@ctx = InitialContext.new
@conn_factory = @ctx.lookup(“jms/ExtQueueConnectionFactory”)
@jms_connection = @conn_factory.create_connection()

But I need to be able to set properties on the factory - such as the
imqConsumerFlowLimit - but the ‘setProperty()’ method is on the
‘ConnectionFactory’ object - and the factory returned above is a
ConnectionFactoryAdapter (via jndi).

In Java - would do something similar to:

connectionFactory =
(QueueConnectionFactory)ctx.lookup(“jms/ExtQueueConnectionFactory”);

Then I could set the property I would need:

connectionFactory.setProperty(ConnectionConfiguration.imqConsumerFlowLimit,
“1”);

Does anyone know if there is a way around this - or a way to actually
cast in ruby/jruby?

Thanks.


Robert B. Weeks

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

What if you write yourself a utility method on the Java side which
looks up the same factory and returns the castes version of it? (and
then call that from ruby)

That should be enough to confirm that the interface is not on the
object (or show that it is, which would be quite mysterious.)

I know I’m doing this kind of hack on other APIs, and have so far just
called the method without doing anything special.

TX


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hi all,
the method is there,
You just call it wrong,
try to puts all your arguments to verify that they are of correct type
and order.
As far as i remember there are more helper methods in jruby 1.5 for
such scenarios where one need to pass class as a argument.
In order to confirm this theory try to call some kind of zero argument
method from this class.
Casting in java does absolutely nothing with the object beeing casted.

Best greetings,
Paweł Wielgus.

2010/5/8 Trejkaz [email protected]:

TX


To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hello -

Hi all,
the method is there,
You just call it wrong,

I don’t understand how this is true? That method does not exist in the
object that is returned from the JNDI call - at all - as it is not
either in straight java - thus the cast - which is ver* common to do.

So how am I calling it wrong?

### Get the connection/session for JMS
@conn_factory = @ctx.lookup("jms/ExtQueueConnectionFactory")

# Set the flow to this listener to 1 - equiv to 

activemq.prefetchSize
@
conn_factory.setProperty(ConnectionConfiguration.imqConsumerFlowLimit,
“1”)

This will not work in ruby (as either ‘setProperty’ or ‘set_property’).
Works great in straight java implementation.

If I said:
@conn_factory = QueueConnectionFactory.new

then this would work fine, because I would be instantiating the exact
factory I needed

So how would I be calling it wrong? What is the correct way to call it
then? Is there another way I am missing here?

try to puts all your arguments to verify that they are of correct type
and order.

Again - this method does not exist in the Adapter class - only in the
specific ConnectionFactory class itself.

As far as i remember there are more helper methods in jruby 1.5 for
such scenarios where one need to pass class as a argument.

Hmm - that is what I am using, and I have been looking at the source -
and am not sure I see what you are talking about here.

In order to confirm this theory try to call some kind of zero argument
method from this class.
Casting in java does absolutely nothing with the object beeing casted.

It does nothing to the actual object - but it can add methods that are
available to the reference to that object - so this is where my issue
was here. So yes, casting can make a huge difference in the behavior of
the object that has been casted.

For now, to get past this - I have had to depend on setting this
property at the creating of the destination instead of on the connection
basis (where I would rather set it) - because I have not been able to
see how to get past this. I can easily just call a new on the actual
specific ConnectionFactory, but that would overstep the pool - which I
want to utilize here.

Thanks.


Robert B. Weeks


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hi again

I’m no expert on the JVM, so I could be wrong, but the thing is that the
cast operation, checkcast, in Java doesn’t add methods to types. It
checks the type of the object, and if; it is; implements; or extends the
given type, it succeeds. If it doesn’t, it throws a ClassCastException.
So unless you are doing some Java magic such as AOP, I can’t see how it
is adding methods to the object.

Like Paweł said, it might be failing because of the types of the
parameters you are supplying not matching the setProperty method
signature, or because the method actually isn’t there - I looked at the
api docs for Java::ComSunMessagingJmsRa::ConnectionFactoryAdapter
(com.sun.messaging.jms.ra: public class: ConnectionFactoryAdapter)
and unless you have a different version to the one I found on google, it
doesn’t have a setProperty method.

Cheers,
Nick

On Mon, 2010-05-10 at 08:11 -0700, Robert W. wrote:

### Get the connection/session for JMS

then this would work fine, because I would be instantiating the exact factory I needed

As far as i remember there are more helper methods in jruby 1.5 for
For now, to get past this - I have had to depend on setting this property at the creating of the destination instead of on the connection basis (where I would rather set it) - because I have not been able to see how to get past this. I can easily just call a new on the actual specific ConnectionFactory, but that would overstep the pool - which I want to utilize here.
http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On May 10, 2010, at 12:43 PM, Nick G. wrote:

Hi again

I’m no expert on the JVM, so I could be wrong, but the thing is that the
cast operation, checkcast, in Java doesn’t add methods to types. It
checks the type of the object, and if; it is; implements; or extends the
given type, it succeeds. If it doesn’t, it throws a ClassCastException.
So unless you are doing some Java magic such as AOP, I can’t see how it
is adding methods to the object.

Like Paweł said, it might be failing because of the types of the
parameters you are supplying not matching the setProperty method
signature, or because the method actually isn’t there - I looked at the
api docs for Java::ComSunMessagingJmsRa::ConnectionFactoryAdapter
(com.sun.messaging.jms.ra: public class: ConnectionFactoryAdapterhttp://www.docjar.com/docs/api/com/sun/messaging/jms/ra/ConnectionFactoryAdapter.html)
and unless you have a different version to the one I found on google, it
doesn’t have a setProperty method.

Sigh -

Yes - that is the reason you cast it is to get that method. There is
no magic here - it is basic common casting.

This is how I would do this in java:

connectionFactory =
(QueueConnectionFactory)ctx.lookup(“jms/ExtQueueConnectionFactory”);

Here they are:

http://www.docjar.com/docs/api/com/sun/messaging/ConnectionFactory.html
http://www.docjar.com/docs/api/com/sun/messaging/QueueConnectionFactory.html

This is how I have always done it in java - and it has always worked -
it works today - the method is in:

http://www.docjar.com/docs/api/com/sun/messaging/QueueConnectionFactory.html

It is part of the AdministeredObject:

http://www.docjar.com/docs/api/com/sun/messaging/AdministeredObject.html#setProperty(String,%20String)

No worries - I will figure this out - I just figured someone has ran
across this. There seems to be some issues trying to get the point about
casting across - it wasn’t meant to be a discussion about that - just
how to get past this in jruby - which I know doesn’t support this in
it’s dynamic way.

Thanks for your time.


Robert B. Weeks

hello,

I followed this thread and became curious. I created a little gist:

does this match your scenario ?

and have a look at the irb session where I call the setName method on
an “Adapter” interface which does not have that very same method but
the adapter object does have that method, so you can call it.

regards Kristian

On Mon, May 10, 2010 at 10:38 PM, Robert W. [email protected]
wrote:

is adding methods to the object.
Yes - that is the reason you cast it is to get that method. There is no
It is part of the AdministeredObject:


Kristian Meier + Saumya Sharma + Sanuka Meier
Vadakkethu House,
Edayanmula West PO - 689532,
Pathanamthitta District, Kerala, INDIA

tel: +91 468 2319577

protect your privacy while searching the net: www.ixquick.com

         _=_
       q(-_-)p
        '_) (_`
        /__/  \
     _(<_   / )_
  (__\_\_|_/__)

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hi Robert,

Did you get to the bottom of this?

Cheers,
Nick

On Mon, 2010-05-10 at 14:18 -0700, Robert W. wrote:

‘getQueueConnectionFactory()’) this would work great.


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hi Kristian -

Thanks for replying -

I followed this thread and became curious. I created a little gist:

does this match your scenario ?

and have a look at the irb session where I call the setName method on
an “Adapter” interface which does not have that very same method but
the adapter object does have that method, so you can call it.

Sure - this is close. Not quite tho - since you are returning a new
instance of that object with that call - it is not quite the same. If I
could have that in the ConnectionFactoryAdapter (like
‘getQueueConnectionFactory()’) this would work great.

The QueueConnectionFactory that I am trying to cast to and the
ConnectionFactoryAdapter are both ‘IS-A’ javax.jms.ConnectionFactory -
so can be cast legally. The ConnectionFactoryAdapter does not have the
method ‘setProperty’ - the QueueConnectionFactory does. So to access
the ‘setProperty(String, String)’ call I need to be able to cast the
original object to a QueueConnectionFactory object.

Thanks a lot for doing your post - I am going to experiment with what
Trejkaz replied with - and create a small utility that will be able to
return the casted object back to me (passing in the original
ConnectionFactoryAdapter) and see if that helps so I don’t have to do
this on a destination wide basis.

Thanks again.

Robert B. Weeks

On Mon, May 10, 2010 at 5:08 PM, Robert W. [email protected]
wrote:

Yes - that is the reason you cast it is to get that method. There is no
magic here - it is basic common casting.
This is how I would do this in java:
connectionFactory =
(QueueConnectionFactory)ctx.lookup(“jms/ExtQueueConnectionFactory”);

This code in Java:

qcf =
(QueueConnectionFactory)ctx.lookup(“jms/ExtQueueConnectionFactory”);

will be this code in Ruby (note that no cast is necessary):

qcf = ctx.lookup(“jms/ExtQueueConnectionFactory”)

As others have mentioned, a cast in Java only exposes a class or
interface that’s already there…in other words, the result of the
ctx.lookup call already implements the QueueConnectionFactory
interface, and casting just gives you a reference to the same object
using that type instead. Because JRuby always uses the actual type of
an object at runtime to expose methods to Ruby, it will see the
QueueConnectionFactory type and its methods on the target object
without needing a cast.

If it’s not working for you, please post the actual error, but I’m 99%
sure that you should be able to call setProperty without doing
anything like a cast.

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Fri, May 7, 2010 at 3:25 PM, Robert W. [email protected] wrote:

Does anyone know if there is a way around this - or a way to actually cast in ruby/jruby?
You don’t need to cast; just call the method you expect to be there,
and it will work. If it doesn’t, then the object you got back wasn’t
of the appropriate type anyway.

Just try it…it should work without a cast.

@ctx = InitialContext.new
@conn_factory = @ctx.lookup(“jms/ExtQueueConnectionFactory”)
@conn_factory.setProperty(ConnectionConfiguration.imqConsumerFlowLimit,
“1”)
@jms_connection = @conn_factory.create_connection()

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

A final post responding to your most recent mail…

On Mon, May 10, 2010 at 9:18 PM, Robert W. [email protected]
wrote:

The QueueConnectionFactory that I am trying to cast to and the
ConnectionFactoryAdapter are both ‘IS-A’ javax.jms.ConnectionFactory - so
can be cast legally. The ConnectionFactoryAdapter does not have the method
‘setProperty’ - the QueueConnectionFactory does. Â So to access the
‘setProperty(String, String)’ call I need to be able to cast the original
object to a QueueConnectionFactory object.

You need to cast in Java, but since the object at runtime will already
be “is-a” QueueConnectionFactory, JRuby will see that and expose those
methods as well. You won’t need to cast, since if the cast would
succeed at runtime for Java, JRuby will see that type and its methods
at runtime and map them to Ruby.

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Wed, May 12, 2010 at 3:31 PM, Robert W. [email protected]
wrote:

  # Set the flow to this listener to 1 - equiv to activemq.prefetchSize
  @conn_factory.setProperty(ConnectionConfiguration.imqConsumerFlowLimit, “1”)

  ^^^  Error occurs here. Method not found.

Please provide the exact error. A method can be “not found” for
reasons other than it not being there. The lack of a cast is not the
problem, I guarantee it.

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hello -

You don’t need to cast; just call the method you expect to be there,
and it will work. If it doesn’t, then the object you got back wasn’t
of the appropriate type anyway.

Just try it…it should work without a cast.

@ctx = InitialContext.new
@conn_factory = @ctx.lookup(“jms/ExtQueueConnectionFactory”)
@conn_factory.setProperty(ConnectionConfiguration.imqConsumerFlowLimit, “1”)
@jms_connection = @conn_factory.create_connection()

This is exactly what I had tried originally - which got me to the point
I was at. This does not find that method at all. If you look at the
sources of the original files - you will see where the casting had to
come in.

My code inside the external jruby script (which I am currently calling
via a MDB - which is embedding ruby and calling this):

# Get the initial context to grab our JNDI resources
@ctx = InitialContext.new

### Get the connection/session for JMS
#@conn_factory = ConnectionFactory.new <-= If I use this - works 

fine…
@conn_factory = @ctx.lookup(“jms/ExtQueueConnectionFactory”)

# Set the flow to this listener to 1 - equiv to 

activemq.prefetchSize
@conn_factory.setProperty(ConnectionConfiguration.imqConsumerFlowLimit,
“1”)

 ^^^  Error occurs here. Method not found.

# Create a connection to the Sun Message Queue Message service
@jms_connection = @conn_factory.createConnection()

# Create a session within the connection
@jms_session = @jms_connection.createSession(false, 

Session::CLIENT_ACKNOWLEDGE)

Thanks.


Robert B. Weeks


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On May 12, 2010, at 9:56 AM, Nick G. wrote:

Hi Robert,

Did you get to the bottom of this?

Hi Nick -

Not necessarily - but I did get the call to return me a different object
(DirectConnectionFactory) - which has a ‘setConfigurationProperty’
method applied to it - which I am experimenting with now to determine if
that gets me what I need.

I had started down the path of a simple java utility class that took
what I was given from the jndi call (ConnectionFactoryAdapter) and
returned me with the correct one - but haven’t finished that trail yet.

This has all spawned from me trying to recreate the way that the
ActiveMessaging pollers are created - as separate processes, but to make
them still run, but in the same VM as the main rails app (all of this in
Glassfish) - and have it working (mostly) with RedBridge (1.5) via MDBs
(to start, stop, etc. on the separate scripts). This has been a bear to
begin with. :slight_smile:

I am re-creating the original errors to send to the list for Charles to
see as well, since it isn’t behaving the way that it seems it should be.

Thanks for asking.


Robert B. Weeks

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hey Charles -

Thanks for the reply -

Please provide the exact error. A method can be “not found” for
reasons other than it not being there. The lack of a cast is not the
problem, I guarantee it.

OK - I am working on that. :wink: Will send soon.

Thanks again.


Robert B. Weeks


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email