9 Replies Latest reply on Jun 28, 2006 1:44 PM by starksm64

    Basics: binding object instance/factory to JNDI name

    gunark

      First off I'm very new to J2EE/JBoss so please excuse my ignorance...

      I'm trying to do something that (I think) ought to be very simple. I need to bind an object instance (or perhaps more appropriately, a factory method that returns an object instance) to a global JNDI name.

      Just using Tomcat, I could do something like this:

      <Resource name="example/MyExample"
       type="com.example.MyExample"
       factory="org.apache.naming.factory.BeanFactory" />


      And then in the context config:

      <ResourceLink name="security/CASConfig"
       global="security/CASConfig"
       type="com.discursive.cas.extend.client.CASConfig"/>


      Easy enough...

      How do I do something like this in JBoss? Preferably using some EJB 3.0 pattern?

      Thanks!

        • 1. Re: Basics: binding object instance/factory to JNDI name
          gunark

          Oops, second code block should be:

          <ResourceLink name="example/MyExample"
           global="example/MyExample"
           type="com.example.MyExample"/>


          (not that it really matters)

          • 2. Re: Basics: binding object instance/factory to JNDI name
            jaikiran

            Have a look ath env-entry in ejb-jar.xml dtd:

            http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd


            Here's an brief extract:



            <!--
            The env-entry element contains the declaration of an enterprise bean's
            environment entries. The declaration consists of an optional
            description, the name of the environment entry, and an optional value.

            Used in: entity and session
            -->
            <!ELEMENT env-entry (description?, env-entry-name, env-entry-type,
            env-entry-value?)>




            • 3. Re: Basics: binding object instance/factory to JNDI name
              gunark

              From what I understand, env-entry only lets you reference instances of Integers, Floats, and other primitive wrappers.

              I don't think this is what I'm looking for.

              Once again, all I want is for an instance of some arbitrary class to be available under a global jndi name. So that when the app is loaded, and "somethig/MyObject" is looked up, an instance of MyObject is returned.

              Specifically, I have a filter in my web.xml file that looks for its configuration info (info stored as a POJO) under a given jndi name. i.e.:

              <filter>
               <filter-name>CAS Filter</filter-name>
               <filter-class>com.discursive.cas.extend.client.filter.CASFilter</filter-class>
              
               <init-param>
               <param-name>com.discursive.cas.extend.client.config.jndi</param-name>
               <param-value>config/CASConfig</param-value>
               </init-param>
              
               ...
              


              (note the param-value)

              How do I make an instance of my object available under "config/CASConfig" in JBoss? Preferably I'd like to set th is up as an EJB 3.0 entitity bean, but I can figure out that part. I just have no idea how to bind an object/object factory to a global jndi name like "config/CASConfig".

              • 4. Re: Basics: binding object instance/factory to JNDI name
                gunark

                For anyone interested, the answer turned out to be manual JNDI binding via JMX service MBeans.

                Basically I have a JMX MBean that manually binds the object I needed bound to JNDI in its create() method.

                • 6. Re: Basics: binding object instance/factory to JNDI name
                  gunark

                   

                  "scott.stark@jboss.org" wrote:
                  http://wiki.jboss.org/wiki/Wiki.jsp?page=JNDIBindingServiceMgr


                  So I been trying to do it this way (the MBean JMX crap I mentioned above is kind of a mess), but I can't figure out how to bind an object (just a POJO with some properties set).

                  The examples in the wiki show how to bind a URL or a String or whatever, but they don't show how to bind an arbitrary POJO, which is what I need.

                  • 7. Re: Basics: binding object instance/factory to JNDI name
                    gunark

                    Okay so looks like something like this works:

                    <jndi:binding name="config/CASConfig">
                     <jndi:value editor="org.jboss.util.propertyeditor.PropertiesEditor">
                     casLogin=https://localhost:8443/cas/login
                     casValidate=https://localhost:8443/cas/proxyValidate
                     casServerName=localhost:8080
                     </jndi:value>
                     </jndi:binding>


                    But I guess what I really want is a way to bind an object factory to a jndiName, so that looking up "something/MyObject" will call an object factory method and return an instance of MyObject... I'm not sure if JNDIBindingServiceMgr is really the right way to go about this. I suppose I would have to write my own custom propertyeditor to behave like a factory class?

                    • 8. Re: Basics: binding object instance/factory to JNDI name
                      gunark

                      Okay, so my final solution for programmatically setting up CAS via JNDI in JBoss:

                      web.xml config for the application with the CAS filter looks like this:

                      <filter>
                       <filter-name>CAS Filter</filter-name>
                       <filter-class>com.discursive.cas.extend.client.filter.CASFilter</filter-class>
                       <init-param>
                       <param-name>com.discursive.cas.extend.client.config.jndi</param-name>
                       <param-value>config/CASConfig</param-value>
                       </init-param>
                      </filter>
                      
                      <filter-mapping>
                       <filter-name>CAS Filter</filter-name>
                       <url-pattern>/*</url-pattern>
                      </filter-mapping>
                      
                      ...
                      
                      <resource-ref>
                       <res-ref-name>config/CASConfig</res-ref-name>
                       <res-type>com.discursive.cas.extend.client.CASConfig</res-type>
                       <res-auth>Container</res-auth>
                      </resource-ref>


                      jboss-web.xml config:

                      <resource-ref>
                       <res-ref-name>config/CASConfig</res-ref-name>
                       <jndi-name>config/CASConfig</jndi-name>
                      </resource-ref>


                      Now, set up a casconfig.sar with jboss-service.xml:

                      <?xml version="1.0" encoding="UTF-8"?>
                      <!DOCTYPE server PUBLIC "-//JBoss//DTD MBean Service 4.0//EN"
                       "http://www.jboss.org/j2ee/dtd/jboss-service_4_0.dtd">
                      <server>
                      
                       <mbean code="org.jboss.naming.JNDIBindingServiceMgr"
                       name="com.example:service=CASConfig">
                       <attribute name="BindingsConfig" serialDataType="jbxb">
                       <jndi:bindings
                       xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
                       xmlns:jndi="urn:jboss:jndi-binding-service:1.0"
                       xs:schemaLocation="urn:jboss:jndi-binding-service:1.0 resource:jndi-binding-service_1_0.xsd"
                       >
                      
                       <jndi:binding name="config/CASConfig">
                       <jndi:value editor="com.example.CASConfigLoader">
                       config
                       </jndi:value>
                       </jndi:binding>
                      
                      
                       </jndi:bindings>
                       </attribute>
                       </mbean>
                      
                      
                      </server>
                      


                      and create two classes:

                      package com.example;
                      
                      import org.jboss.util.propertyeditor.TextPropertyEditorSupport;
                      
                      
                      public class CASConfigLoader extends TextPropertyEditorSupport {
                      
                       public Object getValue() {
                       SerializableCASConfig config = new SerializableCASConfig();
                       config.setCasLogin("https://localhost:8443/cas/login");
                       config.setCasValidate("https://localhost:8443/cas/proxyValidate");
                       config.setCasServerName("localhost:8080");
                       config.setDummyTrust(true);
                      
                       return config;
                       }
                      
                      }
                      


                      and:

                      package com.example;
                      
                      import java.io.Serializable;
                      
                      import com.discursive.cas.extend.client.CASConfig;
                      
                      public class SerializableCASConfig extends CASConfig implements Serializable { }
                      


                      Deploy the sar and your protected application and everything should be working.

                      In the getValue() method of your CASConfigLoader class you should be able to write more fancy code to pull configuration values from elsewhere .

                      • 9. Re: Basics: binding object instance/factory to JNDI name
                        starksm64

                         

                        "Gunark" wrote:
                        Okay so looks like something like this works:

                        <jndi:binding name="config/CASConfig">
                         <jndi:value editor="org.jboss.util.propertyeditor.PropertiesEditor">
                         casLogin=https://localhost:8443/cas/login
                         casValidate=https://localhost:8443/cas/proxyValidate
                         casServerName=localhost:8080
                         </jndi:value>
                         </jndi:binding>


                        But I guess what I really want is a way to bind an object factory to a jndiName, so that looking up "something/MyObject" will call an object factory method and return an instance of MyObject... I'm not sure if JNDIBindingServiceMgr is really the right way to go about this. I suppose I would have to write my own custom propertyeditor to behave like a factory class?


                        You can use any mechanism JBossXB supports. A propertyeditor is one way, a custom schema with annotations is another.
                        http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossXB