Subscribe
by Brendan Whelan, Monday 6th June 2011

Here's one of those obsure problems I came across in Torquebox that might help some other developer; it sure would have saved me some time!

One of the things I like about using the Java flavour of Ruby (JRuby) is that it's pretty easy to invoke and access EJBs. Here's an example:

require 'java'
require '~/Applications/torquebox-1.0.1/jboss/lib/jboss-common-core.jar'
require '~/Applications/torquebox-1.0.1/jboss/client/jbossall-client.jar'
require '~/ExampleEAR/ExampleEAR-ejb/dist/ExampleEAR-ejb.jar'
require '~/Applications/netbeans/enterprise/modules/ext/javaee-api-6.0.jar'

include_class 'java.util.Properties'
include_class 'javax.naming.InitialContext'
include_class 'com.hypermatix.session.ExampleSessionBean';
include_class 'com.hypermatix.session.ExampleSessionBeanRemote';

class EJBExampleController < ApplicationController
  
  def index
    properties = Properties.new
    properties.put(Context::INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory")
    properties.put(Context::PROVIDER_URL, "jnp://localhost:1099")
    properties.put(Context::URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");

    context = InitialContext.new(properties)

    sessionBean = context.lookup("ExampleEAR/ExampleSessionBean/remote")

    result = sessionBean.someBusinessMethod(parameters)
  end
end

Torquebox is a great platform that combines JBoss AS 6 and JRuby into one server, and adds a lot of very powerful integration additions too. However, when I deploy this JRuby test app and the EJB on the same Torquebox JBoss instance, I get a name not bound message with the JNDI context.lookup for the EJB. Looking further down the stack trace (getting a stack trace from a JRuby NativeException is another issue!):

Can not find interface declared by Proxy in our CL + org.jboss.web.tomcat.serice.WebCtxLoader

Further again down the stack trace, it turned out that a ClassNotFoundException was causing this. My own ExampleSessionBean EJB class was not being located by the Torquebox JBoss instance. When I tried to invoke it in a standalone Java app, it worked fine. I couldn't find any similar problem reported for JRuby, however a similar error can occur in Apache web apps. It turns out to be the way the JBoss class loading mechanism works. The solution is to ensure that the web app uses the same class loading domain as the EJB. To do this, just add a jboss-classloading.xml file into the config directory of the JRuby app and into the EAR you use to deploy the EJBs:

<?xml version="1.0" encoding="UTF-8"?>
<classloading xmlns="urn:jboss:classloading:1.0"
              domain="DefaultDomain"
              parent-domain="Ignored"  
              export-all="NON_EMPTY"   
              import-all="true">
</classloading>