7 Replies Latest reply on Feb 5, 2005 5:29 PM by Bela Ban

    unable to call getKeys using JNDI

    kkalmbach Newbie

      I an unable to call getKeys on a TreeCache. I get the Cache by doing a JNDI lookup. Once I get it I can do a put and get with no problem. When I call getKeys I get an NotSerializableException on java.util.HashMap$KeySet.
      Here is my JUnit test and results..

      package com.cexp.common.enterprise;
      
      import java.util.Set;
      import java.util.Collection;
      import java.util.Iterator;
      
      import junit.framework.TestCase;
      
      import org.apache.commons.logging.Log;
      import org.apache.commons.logging.LogFactory;
      import org.jboss.cache.TreeCacheMBean;
      import javax.naming.NameNotFoundException;
      import javax.naming.InitialContext;
      import javax.naming.NameParser;
      import javax.naming.NamingException;
      import javax.naming.Context;
      import javax.naming.Name;
      
      
      /** Simple tests for the ContextFramework.
       * @author kkalmbac
       *
       */
      public class TestCache extends TestCase {
       /** the logger. */
       private static Log log = LogFactory.getLog(TestCache.class);
       private InitialContext context;
       private TreeCacheMBean theCache;
       public static Object lookup(Context context, Name name)
       throws NamingException
       {
       // Try the lookup twice because, if the naming server has gone down,
       // the jndi connection in the context is stale and doesn't seem to
       // get recreated until after the first lookup attempt. The second
       // lookup attempt will then succeed.
      
       int lookupCount = 0;
       int lookupAttempts = 2;
      
       while (lookupCount++ < lookupAttempts)
       {
       try
       {
       if(log.isDebugEnabled()){
       log.debug("lookup() name=" + name);
       }
       return context.lookup(name);
       }
       catch (NamingException e)
       {
       if(log.isDebugEnabled()){
       log.debug("lookup() NamingException", e);
       }
       if (lookupCount == lookupAttempts)
       throw e;
       }
       }
      
       return null;
       }
       public static Object lookup(Context context, String name)
       throws NamingException
       {
       NameParser parser = context.getNameParser(context.getNameInNamespace());
       return lookup(context, parser.parse(name));
       }
      
       protected InitialContext getContext() {
       if (context == null) {
       try {
       context = new InitialContext();
       } catch (Exception e) {
       log.error("could not get initial context", e);
       }
       }
      
       return context;
       }
      
       private TreeCacheMBean getCache() {
       if (log.isDebugEnabled())
       {
       log.debug("getCache()");
       }
      
       if (theCache == null)
       {
       try
       {
       theCache = (TreeCacheMBean)lookup(getContext(), "MyTreeCache");
       if (log.isDebugEnabled())
       {
       log.debug("cache found " + theCache);
       }
       }
       catch (NameNotFoundException e)
       {
       }
       catch (Exception e)
       {
       }
       }
      
       return theCache;
       }
       /** Constructor.
       * @param s the test name
       */
       public TestCache(String s) {
       super(s);
      
       System.setProperty(
       "java.naming.factory.initial",
       "org.jnp.interfaces.NamingContextFactory");
       System.setProperty(
       "java.naming.factory.url.pkgs",
       "org.jboss.naming:org.jnp.interfaces");
       System.setProperty(
       "jnp.socketFactory",
       "org.jnp.interfaces.TimedSocketFactory");
       System.setProperty("java.naming.provider.url", "jnp://localhost:1099");
       System.setProperty("jnp.timeout", "0");
       System.setProperty("jnp.sotimeout", "0");
      
      
       }
      
       /** Simple tests for the UserContext. */
       public void testGetKeys() {
       TreeCacheMBean cache = getCache();
       try {
       cache.put("/","Test","value");
       Object o = cache.get("/", "Test");
       System.out.println("We got " + o);
       Set s = cache.getKeys("/");
       } catch (Exception e) {
       e.printStackTrace();
       }
       }
      }
      


      Here is the results..
      We got value
      java.lang.reflect.UndeclaredThrowableException
       at $Proxy0.getKeys(Unknown Source)
       at com.cexp.common.enterprise.TestCache.testGetKeys(TestCache.java:135)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:324)
       at junit.framework.TestCase.runTest(TestCase.java:154)
       at junit.framework.TestCase.runBare(TestCase.java:127)
       at junit.framework.TestResult$1.protect(TestResult.java:106)
       at junit.framework.TestResult.runProtected(TestResult.java:124)
       at junit.framework.TestResult.run(TestResult.java:109)
       at junit.framework.TestCase.run(TestCase.java:118)
       at junit.framework.TestSuite.runTest(TestSuite.java:208)
       at junit.framework.TestSuite.run(TestSuite.java:203)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)
      Caused by: java.io.NotSerializableException: java.util.HashMap$KeySet
       at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1054)
       at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1332)
       at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1304)
       at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1247)
       at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278)
       at org.jboss.remoting.RemoteMethodInvocationResult.<init>(RemoteMethodInvocationResult.java:47)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:284)
       at org.jboss.remoting.transport.socket.SocketServerInvoker$Client.run(SocketServerInvoker.java:208)
      


      Any help at all would be appreciated.

      Thanks
      -Kevin

        • 1. Re: unable to call getKeys using JNDI
          kkalmbach Newbie

          A couple more things I should have mentioned.
          I am using jboss-cache 1.2
          The same error happens if I call getChildrenNames

          • 2. Re: unable to call getKeys using JNDI
            Bela Ban Master

            fixed in JBossCache CVS head. Will be in JBossCache 1.2.1 (due in 1-2 weeks)

            • 3. Re: unable to call getKeys using JNDI
              kkalmbach Newbie

              I got the latestest code and I have a question.

              Is jndi not supported anymore?
              If not, am I supposed to always use the MBean lookup?
              If jndi is still supported, how do I bind the cache into jndi?

              Thanks
              -Kevin

              • 4. Re: unable to call getKeys using JNDI
                Bela Ban Master

                 

                "kkalmbach" wrote:
                I got the latestest code and I have a question.

                Is jndi not supported anymore?
                If not, am I supposed to always use the MBean lookup?
                If jndi is still supported, how do I bind the cache into jndi?

                Thanks
                -Kevin


                Yes, JNDI is not supported anymore, sorry about that. We felt this was outside the scope of JBossCache. So you can use JMX access, or you can bind JBossCache into JNDI yourself using the JrmpProxyFactory MBean (I'll update the docu):


                jboss:service=invoker,type=jrmp
                mydomain:service=MyMBean
                blah/MyClientInterface
                my.beans.MyClientInterface


                org.jboss.proxy.ClientMethodInterceptor
                org.jboss.proxy.SecurityInterceptor
                org.jboss.invocation.InvokerInterceptor


                jboss:service=invoker,type=jrmp
                mydomain:service=MyMBean


                • 5. Re: unable to call getKeys using JNDI
                  Bela Ban Master

                  The XML code didn't look to good, but take a look at jboss-head/docs/TreeCache.xml (at the very end), that's the docbook documentation on this. Otherwise, search for JrmpProxyFactory on jboss.com (there's an explanation on the wiki)

                  • 6. Re: unable to call getKeys using JNDI
                    kkalmbach Newbie

                    This is probably a question for another forum, but I'll give it a try here. I added the code you have in the latest doc and when I try to deploy it I get this message.

                    10:51:51,266 ERROR [URLDeploymentScanner] Incomplete Deployment listing:
                    Packages waiting for a deployer:
                    org.jboss.deployment.DeploymentInfo@56c362e5 { url=file:/C:/tools/jboss/jboss-4.
                    0.1RC2/server/default/deploy/cachejndi.xml }
                     deployer: null
                     status: null
                     state: INIT_WAITING_DEPLOYER
                     watch: file:/C:/tools/jboss/jboss-4.0.1RC2/server/default/deploy/cachejndi.xml
                    
                     altDD: null
                     lastDeployed: 1106927946795
                     lastModified: 1106927946795
                     mbeans:
                    


                    The xml is in a seperate file in my deploy directory and it looks like this.
                    <?xml version="1.0" encoding="UTF-8"?>
                    
                    <server>
                     <classpath codebase="./lib" archives="jboss-cache.jar, jgroups.jar, jboss.jar"/>
                     <mbean
                     code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
                     name="jboss:service=proxyFactory,type=jrmp,target=factory">
                     <attribute
                     name="InvokerName">jboss:service=invoker,type=jrmp</attribute>
                     <attribute
                     name="TargetName">jboss.cache:service=TreeCache</attribute>
                     <attribute name="JndiName">MyCache</attribute> <attribute
                     name="InvokeTargetMethod">true</attribute> <attribute
                     name="ExportedInterface">org.jboss.cache.TreeCacheMBean</attribute>
                     <attribute name="ClientInterceptors"> <iterceptors>
                     <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
                     <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
                     <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
                     </iterceptors> </attribute>
                     <depends>jboss:service=invoker,type=jrmp</depends>
                     <depends>jboss.cache:service=TreeCache</depends>
                     </mbean>
                    
                    
                    
                    </server>
                    
                    


                    the jnmp service is deployed and running. Any ideas on what is going on?

                    -Kevin

                    • 7. Re: unable to call getKeys using JNDI
                      Bela Ban Master

                      A dependency was not added correctly, e.g. the dep to JBossCache or an invoker: check

                      jboss:service=invoker,type=jrmp
                      jboss.cache:service=TreeCache

                      for existence