Skip to main content

Overloaded methods within Interface exposed via Cajo

  7 posts   Feedicon  
Replies: 6 - Last Post: May 06, 2011 15:26
by: livonthedge
showing 1 - 7 of 7
Posted: April 27, 2011 19:37 by livonthedge
I have an interface that I want to expose via Cajo and this interface contains several overloaded methods.

My implementation to this interface is exported via the
 cajo.export
call just fine.

However, when I use the
 cajo.lookup 
command to find my interface the returned object array is always empty.

I looked more closely at the
 cajo.java 
source via SVN and found the invoke method where the validation is performed to determine if the requested interface matches an interface exposed via the running cajo server.

This call does a method by method comparison and upon finding a match it then drops down to the parameters to determine a match.

If there are two methods with different parameters this comparison with fail and break out of the for-loop.

I believe the break should be a continue, allowing the search to continue on until the matching parameter set is found or you hit the end of the list.

Here is the code snippet:
Cajo.jar

public Object invoke(String method, Object args) throws Exception {
         if (method == null) { // special case signal
            Class  ireturns[] = (Class[])((Object[])args)[0];
            String inames[]   = (String[])((Object[])args)[1];
            Class  iargs[][]  = (Class[][])((Object[])args)[2];
            Method methods[]  = object.getClass().getMethods();
            String mnames[]   = new String[methods.length];
            Class  mreturns[] = new Class[methods.length];
            for (int i = 0; i < methods.length; i++) {
               mreturns[i] = methods[i].getReturnType();
               mnames[i]   = methods[i].getName();
            }
            searching: for (int i = 0; i < inames.length; i++) {
               for (int j = 0; j < mnames.length; j++) {
                   if (mnames[j].equals(inames[i]) && (ireturns[i].equals(Void.TYPE) || Remote.autobox(ireturns[i]).isAssignableFrom(Remote.autobox(mreturns[j])))) {
                       Class  margs[] = methods[j].getParameterTypes();
                       if (margs.length != iargs[i].length) break;
                       for (int k = 0; k < margs.length; k++)
                           if (!Remote.autobox(margs[k]).isAssignableFrom(iargs[i][k]))
                               break;
                           continue searching;
                   }
               }
               return null;
            }
            return Boolean.TRUE; // all methods were successfully matched
         } else return Remote.invoke(object, method, args);
      }


I believe the
 break 
found on this line
 if (margs.length != iargs[i].length) break; 
should be a
 continue 

If the algorithm is allowed to continue, the lookup of my interface succeeds.

Am I correct that this is a bug in the validation step or does RMI not handle overloaded methods at a lower level?

Thank you
Posted: April 28, 2011 02:13 by John Catherino
Very nice find, thank-you, on behalf of all the community.

I have re-worked the lookup mechanism to address the problem you have discovered.

Unfortunately, I am still trying to adapt to the involuntary repository migration. Until then, I keep the latest version of the source on the downloads page.

Thanks so much again,

John
Posted: April 29, 2011 19:53 by livonthedge
Glad I could help.

That was only the second time I had ever posted anything so it was encouraging for it to be an unknown bug.
You rarely need to these days with so much information online.

I have pulled down the source and have recompiled the cajo.jar file.

One issue...and this could be to me misunderstading cajo a bit but I will throw this out there.

I have a small test Interface
public interface myInterface {
    
    public String getTestString();
    
}

and a another interface the extends the first
public interface myService extends myInterface {
 
    public boolean echoBooleanTest(boolean bool);
    
}
[code]
and finally an implementation
[code]
public class myImplementation implements myService {
    
    public String getTestString() {
        return "My Test String";
    }
    
    public boolean echoBooleanTest(boolean newBool) {
        return newBool;
    }
    
}

if I I export the myImplementation and then lookup myInterface cajo is able to find it.

If I export myImplementation and then lookup myService is DOES NOT find it.

Now when I was using the older cajo it worked in both instances but with the newer compiled on it did not.

Did the other fix introduce a different bug or does the new cajo work differently in regards to extended interfaces?

Cheers!

Tim


Posted: April 30, 2011 01:00 by John Catherino
Hi Tim!

Interesting, I don't seem to have the problem, here is the test code I am using:

CajoServer.java:

import gnu.cajo.Cajo;

class CajoService {
   public static String getMessage(String name) { return "Hello " + name; }
   public void emit(Object o) { System.out.println(o.toString()); }
}

public class CajoServer {
   public static void main(String[] args) throws Exception {
      Cajo cajo = new Cajo();
      cajo.export(new CajoService());
      System.out.println("Server running");
   }
}


CajoClient.java:

import gnu.cajo.Cajo;

interface Base {
   void emit(String string);
}

interface Service extends Base {
   Object getMessage(String id);
}

public class CajoClient {
    public static void main(String[] args) throws Exception {
        Cajo cajo = new Cajo();
        Thread.currentThread().sleep(500); // allow some discovery time
        Object results[] = cajo.lookup(Base.class); // test one way
//        Object results[] = cajo.lookup(Service.class); // or the other
        System.out.println("Objects found: " + results.length);
        if (results.length > 0) {
           Service service = (Service)cajo.proxy(results[0], Service.class);
           System.out.println("Message = " + service.getMessage("client"));
           service.emit("hello server!");
        }
        System.exit(0);
    }
}


Does this work for you?

John
Posted: May 03, 2011 14:31 by livonthedge
I was able to successfully run yours but not mine.

I recreated mine from scratch and it ran fine.

It is a mystery but all seems to be working.

just odd.

Thank you for the help.
Posted: May 05, 2011 19:39 by livonthedge
Like I said before I got yours to run fine and recreated mine and it ran.

I am have an issue when running the client mulitple times and am unsure what is going on.

If I am doing something wrong or don't understand fully what is going on under the covers.

1) I start the cajo server

2) I then run the client. java and see the expected output.

3) I then stop the client.java and leave the server.java running.

4) now if I run the client.java again (changing nothing) the lookup will return 0 and the remote class will not be found.

What is going on here?
Posted: May 06, 2011 15:26 by livonthedge
Please disregard my last post and question.

I updated to the most recent version of Cajo and am no longer seeing that behavior.
showing 1 - 7 of 7
Replies: 6 - Last Post: May 06, 2011 15:26
by: livonthedge
 
 
Close
loading
Please Confirm
Close