Archive

Archive for the ‘java’ Category

Deploying a pre-existing bundle on OSGi OBR

September 15th, 2014

Using the maven-bundle-plugin, you can deploy a preexisting jar bundle from your local maven repository to your remote OBR. For this you use the deploy-file target of the maven-bundle-plugin directly, with a command line like:

mvn org.apache.felix:maven-bundle-plugin:2.4.0:deploy-file
-DrepositoryId=my-repository-id
-Durl=scp://url/to/my/repository
-DpomFile=C:\Users\myuser\.m2\repository\com\...\the-bundle-to-deploy-1.0.0.pom

where my-repository-id is the id you also use in your settings.xml for storing the access data (username, private key, passphrase etc).

In my case, this simple command failed with the error:


[ERROR] Failed to execute goal org.apache.felix:maven-bundle-plugin:2.4.0:deploy-file (default-cli) on project standalone-pom: Unsupported protocol: 'scp': Cannot find wagon which supports the requested protocol: scp: java.util.NoSuchElementException
[ERROR] role: org.apache.maven.wagon.Wagon
[ERROR] roleHint: scp

and later

Error injecting: org.apache.maven.wagon.providers.ssh.jsch.ScpWagon

and even later
Error injecting: org.apache.maven.wagon.providers.ssh.jsch.interactive.PrompterUIKeyboardInteractive

To resolve this, I had to add the following jars to the %M2_HOME/lib directory (so they are added to the classpath).

  • wagon-ssh-2.5.jar
  • wagon-ssh-common-2.5.jar
  • jsch-0.1.51.jar
  • plexus-interactivity-api-1.0-alpha-6.jar

M2_HOME is where the maven executable are located, in my case C:\springsource\apache-maven-3.0.3\lib and which can be found (on windows) by executing:
where mvn

java, maven, osgi

Getting the number of dimensions of a multidimensional array in Java

January 21st, 2009

Based on my previous post about cloning multidimensional arrays, I have come up with a short static function to get the number of dimensions which a multidimensional array has.

Note that this method only returns the number of dimensions of the original object passed as argument. It does not expand into the contained objects themselves. Example:

Object[] a = new Object[3][0];
System.out.println(getNumberOfDimensions(a));

prints 2.

Object[] a = new Object[1];
a[0] = new float[2][5][1];
System.out.println(getNumberOfDimensions(a));

prints 1.

Here’s the code:

/** 
 * Returns the number of dimensions which a multidimensional 
 * array has as a positive integer. For example, returns 3 
 * when passed a <code>float[][][]</code> 
 * @param src the multidimensional array 
 * @return the number of dimensions of src 
 * @author Philipp Buluschek bulu@romandie.com 
 */  
public static int getNumberOfDimensions(Object[] src){  
  int dim = 1;  
  Class cl = src.getClass().getComponentType();  
  while(cl.isArray()){  
    dim++;  
    cl = cl.getComponentType(); // will not return null as we tested isArray() above  
  }  
  return dim;  
}  

java , , , ,

Cloning multidimensional arrays in Java

January 13th, 2009

In Java, calling the clone() method on an array returns a copy of the array, that is a new array containing references to the same objects as the source array. In particular, the objects themselves are not copied. As multidimensional arrays are just arrays of arrays, cloning a multidimensional array result in only the first dimension being copied, the array of the second and following dimensions are the same in the source and the destination array.

Below I present a static method to get a real clone of a multidimensional array, meaning one where all dimensions are copied, but not the objects. I use it for example, if I have a private multidimensional array in a class, and want to provide an accessor for it. To assure that the array which is returned by the accessor is totally independant of the one inside the class, all dimensions must be copied correctly (defensive copy).

Note that this implementation does not support arrays containing themselves. This will result in an infinite recursion and eventually a stack overflow.

So without further discussion, here’s the code (compatible JRE 1.3)

/** 
 * Makes a copy of all dimensions of a multidimensional 
 * array. This function does not copy the actual objects, but 
 * only the references. The behavior is the same as {@link #clone()} 
 * but extends to all dimensions of an array.<br> 
 * Note that this implementation does not handle arrays which 
 * contain themselves correctly. It results in a infinite recursion
 * ending in a {@link StackOverflowError}.
 * 
 * @param src a multidimensional array, either of {@link Object}s 
 * or of a primitive type 
 * @return a copy of src, so that each dimension is copied, but 
 * the objects are not cloned 
 * @author Philipp Buluschek bulu@romandie.com 
 */  
public static Object[] deepClone(Object[] src){
  if(src == null){
    return null;
  }
  Object[] dest = (Object[])src.clone();
  for (int i = 0; i < dest.length; i++) {
    Object e = dest[i];
    if (e != null &amp;amp;&amp;amp; e.getClass().isArray()) { 
      // if it is null or not an array, it was taken care of by the clone()
      if (e instanceof Object[]) {
        // using recursion to reach all dimensions
        dest[i] = deepClone((Object[])e);
      }
      else {
        // primitive arr
        if(e instanceof byte[])   dest[i] = ((byte[]) e).clone();
        else if(e instanceof short[])  dest[i] = ((short[]) e).clone();
        else if(e instanceof int[])    dest[i] = ((int[]) e).clone();
        else if(e instanceof long[])   dest[i] = ((long[]) e).clone();
        else if(e instanceof float[])  dest[i] = ((float[]) e).clone();
        else if(e instanceof double[]) dest[i] = ((double[]) e).clone();
        else if(e instanceof boolean[])dest[i] = ((boolean[]) e).clone();
      }
    }
  }
  return dest;
}

The same code using generics for JRE >= 1.5

/** 
 * Makes a copy of all dimensions of a multidimensional 
 * array. This function does not copy the actual objects, but 
 * only the references. The behavior is the same as {@link #clone()} 
 * but extends to all dimensions of an array.<br> 
 * Note that this implementation does not handle arrays which 
 * contain themselves correctly. It results in a infinite recursion
 * ending in a {@link StackOverflowError}.
 * 
 * @param src a multidimensional array, either of {@link Object}s 
 * or of a primitive type 
 * @return a copy of src, so that each dimension is copied, but 
 * the objects are not cloned 
 * @author Philipp Buluschek bulu@romandie.com 
 */  

@SuppressWarnings("unchecked")
public static <T> T[] deepClone(T[] src){
  if(src == null){
    return null;
  }
  T[] dest = src.clone();
  for (int i = 0; i < dest.length; i++) {
    Object e = dest[i];
    if (e != null &amp;amp;&amp;amp; e.getClass().isArray()) { 
      // if it is null or not an array, it was taken care of by the clone()
      if (e instanceof Object[]) {
        // using recursion to reach all dimensions
        dest[i] = (T)(deepClone((Object[])e));
      }
      else {
        // primitive arr
        if(e instanceof byte[])        dest[i] = (T)((byte[]) e).clone();
        else if(e instanceof short[])  dest[i] = (T)((short[]) e).clone();
        else if(e instanceof int[])    dest[i] = (T)((int[]) e).clone();
        else if(e instanceof long[])   dest[i] = (T)((long[]) e).clone();
        else if(e instanceof float[])  dest[i] = (T)((float[]) e).clone();
        else if(e instanceof double[]) dest[i] = (T)((double[]) e).clone();
        else if(e instanceof boolean[])dest[i] = (T)((boolean[]) e).clone();
      }
    }
  }
  return dest;
}

java , , ,