Wednesday 13 March 2013

unsupported version 0x1. If possible, set the switch to use one of the versions [3]

This error is thrown by ryu-manager when your controller application is using current OpenFlow specification version, but the bridge doesn't. To demonstrate this, let assume you're using mininet switch on current version of Open vSwitch. You then assume this should be enough to assign flow targeted for current OpenFlow versions, but to your surprise Ryu complains.

The solution to this is pretty simple:
While mininet is still running open a new terminal and type:
ovs-vsctl show
This should show result synonymous to that shown below;
root@sdn-0l:~# ovs-vsctl show
e7fd4eea-afe3-4f9f-977c-86330374e7a5
    Bridge "s1"
        Controller "ptcp:6634"
        Controller "tcp:10.100.1.61:6633"
            is_connected: true
        fail_mode: secure
        Port "s1-eth1"
            Interface "s1-eth1"
        Port "s1"
            Interface "s1"
                type: internal
        Port "s1-eth2"
            Interface "s1-eth2"
As you can see the bridge value is "s1" in my case. Now run below to instruct the bridge to support current version protocols.
ovs-vsctl set bridge s1 protocols=OpenFlow10,OpenFlow12,OpenFlow13

Friday 18 May 2012

Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function

So who is the culprit?! I tell you who it is, you are getting below exception;
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'chmod':
The specified procedure could not be found.

 at com.sun.jna.Function.<init>(Function.java:129)
 at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:250)
 at com.sun.jna.Library$Handler.invoke(Library.java:191)
 at $Proxy0.chmod(Unknown Source)

because the native function mentioned in your exception is not found in your native library, Or your native functions are not exposed outside the premiss of your library.

To inspect your native library, for example if you have done something similar to previous post, for windows enviroment I recommed downloading Dependency Walker or .*nix users using gdb core to inspect the output library.

If you cannot see the mentioned function, chances are you compiled your native library as shown in previous post or as shown below;
gcc -o native.dll native.c
Solution
Use the -shared flag to resolve this. Now compile your library like this;
gcc -shared -mno-cygwin -Wall -o native.dll native.c
remove -mno-cygwin -Wall if you are not using cygwin on windows. Now go grab a cuppa coffee and see your natives in action. And oh, don't forget to move the library to your classpath.

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library

Again let me dive straight in to catch this culprit. So! how did it happen? You have a method call which uses or wants to use JNA to perform some native system calls. You then fired your call only to be greeted with:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'c': 
The specified module could not be found.

 at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:145)
 at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:188)
 at com.sun.jna.Library$Handler.<init>(Library.java:123)
 at com.sun.jna.Native.loadLibrary(Native.java:255)
 at com.sun.jna.Native.loadLibrary(Native.java:241)
WTH is this you asked yourself?! well I have to be honest, this is just the beginning. Let me demostrate this with a simple JNA call to illustrate where this exception came from. Let us assume below is your native functions you want to invoke. Again I will make an assumption that, your native code was compiled on windows enviroment using perhaps Cygwin gcc command.
//File Name: native.c

#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#ifdef _WIN32
#   include <io.h>

typedef signed int md_t;

int fchmod(const char * path, md_t mode)
{
 return (_chmod(path, (mode==777 ? _S_IWRITE : _S_IREAD )));
}

#else
int fchmod(const char * path, md_t mode)
{
 return(chmod(path, mode));
}

#endif
int main(int argv, char ** argvs)
{
  return 0;
}
Here again let us assume this is your Java application from which you want to call the native functions:
import com.sun.jna.Library;
import com.sun.jna.Native;

public class demoJNA
{
  public interface Natives extends Library
  {
    public int fchmod(String path, int mode);
  }

  public static void main(String[] args)
  {
    Natives posix = (Natives) Native.loadLibrary("c", Natives.class);
    posix.fchmod("c:\\somefile.txt", 777);
  }
}
Out of patience you compiled your java application, executed it and hence the exception. Ok stop here! lets revisit your application, first notice the call;
Native.loadLibrary("c", Natives.class); 
is "c" the library output name given when you compiled your native code? Let say I compile the native code above like this;
gcc -o native.dll native.c
the call then should look like this;
Natives posix = (Natives) Native.loadLibrary("native", Natives.class);
One more thing, Is the ouput library file located at your classpath? if not then please do move it there, because it from there JNA will be looking when the call Native.loadLibrary is fired.

Monday 14 May 2012

Controlling method recursion to avoid StackOverflowError - Java RMI call as Example

There are times that you want the flexibility of your method to be able to recurse itself when an exception occurs to re-attempt without recursing too deeply. This could possibly be a call to remote Socket or RMI which has been restarted, and therefore the stub or the connector object instance needs re-allocating or other. I have opted to use an RMI call as an example due to reasons which will be clear pretty shortly. Say you are allocating and using RMI connection stub via singleton instance as shown bellow;
public class Foo
{
 private RemoteStub stub;
 public RemoteStub getRemoteConnection()
 {
  if(stub==null)
  {
    try
    {
     this.stub= ((RemoteStub) Naming.lookup(...));
    }
    catch (Exception e)
    {
      e.printStackTrace(System.out);
    }
  }
  return stub;
 }
}
Chances are when the remote server instance is restarted, your stub object will not re-allocate itself to hold the new instance. And hence an attempt to make remote calls will yeild the exception below;
java.rmi.ConnectException: Connection refused to host: 192.168.0.1; nested exception is: 
    java.net.ConnectException: Connection timed out: connect
A quick and easy way to fix this issue is to have your connection stub builder method ignore null check or simply no singleton instance for your remote calls, which means every remote call will have the connection stub re-allocated and returned. As said, this is quick and easy, but doesn't come cheap neither. And so, this is the reason why I have decided to use this example as an insight into controlling method recursion, to make it pretty easy to follow through.

An alternative and yet effective approach is to extend your connection stub builder method to re-allocate on demand. This way when above exception occurs you can recurse your method to re-attempt once and ignore. The assumption here is that if you do re-attempt and fails again, there is a high chance remote server is down or something is preventing you from connecting. Now, let us go ahead and expand on getRemoteConnection() method and introduce the techiques for re-attempting the call.
public class Foo
{
 private RemoteStub stub;
 private AtomicBoolean reconnect;
 
 public Foo()
 {
  reconnect= new AtomicBoolean(false);
 }

 public RemoteStub getRemoteConnection()
 {
  //Extended the builder to handle on demand
  if(stub==null || reconnect.get())
  {
    try
    {
     this.stub= ((RemoteStub) Naming.lookup(...));
     reconnect.set(false);
    }
    catch (Exception e)
    {
      e.printStackTrace(System.out);
    }
  }
  return stub;
 }

 protected void reconnect()
 {
  reconnect.set(true);
 }
}
As you can see above, we have expanded on the remote stub builder method to handle on demand call to re-allocate the remote stub object. This gives us the flexibility in our calling method to fire reconnect() whenever we re-attempt. One issue we have not raised so far is the fact that, there is a high chance re-attempt via recursion will fail subsequently due to assumption made above. Here we are likely to enter into deep recursion and hence StackOverflowError.
  public class FooCaller extends Foo
  {
    private static final CharSequence failedConnect = "Connection refused";
    public void callRemoteMethod()
    {
      try
      {
        int status = getRemoteConnection().doSomething();
        System.out.println("Remote call - " + (status > -1 ? "Succeeded" : "Failed"));
      }
      catch (RemoteException e)
      {
        if (e.getMessage().contains(failedConnect))
        {
         // re-attempt
         reconnect();
         callRemoteMethod();
        }
      }
    }
  }
To control this we will use a token object and a simple stack handler, which does ensure recursions are detached straight after first re-attempt call, to avoid StackOverflowError. See below for extended version of FooCaller class with method handler for issuing attempt token and generic handler method for handling re-attempt calls to avoid code verbosity.
/**
 Re-Attempt Token
*/
public class ReAttemptToken
{
  public long lastAttempted = System.currentTimeMillis();
  public String method;

  public ReAttemptToken(String method)
  {
    this.method = method;
  }
}
.. simple stack object to control the life span of ReAttemptToken held for a specific method recurse;
/**
 * Simple stack object for holding recursive method recall to avoid {@link StackOverflowError}.
 * 
 * @author Bright Dadson
 * 
 */
@SuppressWarnings("serial")
public class ReAttemptStack extends ArrayList<ReAttemptToken>
{
  /**
   * Creates an empty Stack.
   */
  public ReAttemptStack()
  {
  }

  /**
   * Pushes an item onto the top of this stack. This has exactly the same effect as: 
* *
   * add(item)
   * 
* *
* * @param item the item to be pushed onto this stack. * @return the item argument. * @see java.util.ArrayList#add */ public ReAttemptToken push(ReAttemptToken item) { add(item); return item; } /** * Tests if this stack is empty. * * @return true if and only if this stack contains no items; false otherwise. */ public boolean empty() { return size() == 0; } /** * Locate and return items in this stack. * * @param o the desired {@link ReAttemptToken}. * @return found object else null */ public synchronized ReAttemptToken locate(ReAttemptToken o) { int i = this.searchToken(o.method); return (i >= 0) ? get(i) : null; } /** * Scan this stack to search for token with method same as passed argument * * @param method - token method * @return index of the token within this stack */ public int searchToken(String method) { for (int i = 0; i < size(); i++) { if (get(i).method.equals(method)) return i; } return -1; } }
.. and finally a new extended version of FooCaller with stack control handlers;
 public class FooCaller extends Foo
 {
    private long reAttemptTTL = 3 * 1000;
    private ReAttemptStack stack;
    private static final CharSequence failedConnect = "Connection refused";

    private FooCaller()
    {
      stack = new ReAttemptStack();
    }

    /**
     * Typical remote call
     * 
     */
    public void callRemoteMethod()
    {
      try
      {
        int status = getRemoteConnection().doSomething();
        System.out.println("Remote call - " + (status > -1 ? "Succeeded" : "Failed"));
      }
      catch (RemoteException e)
      {
        if (e.getMessage().contains(failedConnect))
        {
          try
          {
            ReAttemptToken token = getReAttemptToken("callRemoteMethod");
            reAttemptRemoteCall(this.getClass().getMethod("callRemoteMethod"), new Object[] {}, token);
          }
          catch (Exception ex)
          {}
        }else e.printStackTrace();
      }
    }

    /**
     * This method issues token to calling functions. If the token is not expired and hence still exist, the method returns the same token from the
     * stack for usage.
     * 
     * @param method
     * @return
     */
    private ReAttemptToken getReAttemptToken(String method)
    {
      int tokenIndex;
      if ((tokenIndex = stack.searchToken(method)) > -1)
      {
        return stack.get(tokenIndex);
      }
      return (new ReAttemptToken(method));
    }

    /**
     * Using the method we can retry remote reconnection, obtain a fresh connection stub and re-invoke the failed method. In the aid of re-attempt
     * token passing control, we can avoid indefinite recurssion from occuring when we re-invoke. Each token is expired every 3secs to enable recall.
     * @param methodToRecurse
     * @param params
     * @param token
     */
    private void reAttemptRemoteCall(Method methodToRecurse, Object[] params, ReAttemptToken token)
    {
      try
      {
        long now = System.currentTimeMillis();
        boolean attempt = false;
        if (stack.locate(token) == null)
        {
          stack.push(token);
          attempt = true;
        }
        else if ((stack.locate(token) != null) && now > (reAttemptTTL + token.lastAttempted))
        {
          stack.remove(token);
          stack.push(getReAttemptToken(token.method));
          attempt = true;
        }
        if (attempt)
        {
          System.err.println("Re-Attempting failed remote call **");
          reconnect();
          methodToRecurse.invoke(this, params);
        }
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
    }
  }
Disclaimer
The code and technique adopted in this post has only been written to demonstrate how to control StackOverFlowError from occuring in method calls which require recursion, to re-attempt situations where an exceptions is possible to occur due to anticipated reasons. Also note that, the approach adopted here is not required for all situations.

Drop a comment if you've spotted a bug, known enhancement possible to extend the technique or any relevant comment which is helpful to other readers.