Hello,

I changed the glue-java.xsl file in the sources and compiled VBox on my own. The resulting Java XPCOM binding fixed the problem for me.

I created a patch file of the changes so that you can include it into the official sources. The patch works with 4.1.18 and should also work with svn head.

The patch is licensed under the MIT license.

Regards,
Matthias

On 09.07.2012 10:19, Matthias Jahn wrote:
Hello,

I have a problem using the Java XPCOM API to import an ova file. The
import itself is working, but I get an exception, if I try to read the
description values.

My code snippet:

public static void importAppliance(String path, String name) {
    IAppliance appliance = virtualBox.createAppliance();

    IProgress progress = appliance.read(path);
    progress.waitForCompletion(-1);

    appliance.interpret();

    readDescription(appliance);

    progress = appliance.importMachines(new LinkedList<ImportOptions>());
    progress.waitForCompletion(-1);
}
        
private static void readDescription(IAppliance appliance) {
    IVirtualSystemDescription description =
appliance.getVirtualSystemDescriptions().get(0); //list size == 1
                
    Holder<List<VirtualSystemDescriptionType>> typesHolder = new
Holder<List<VirtualSystemDescriptionType>>();
    Holder<List<String>> refsHolder = new Holder<List<String>>();
    Holder<List<String>> ovfValuesHolder = new Holder<List<String>>();
    Holder<List<String>> vboxValuesHolder = new Holder<List<String>>();
    Holder<List<String>> extraConfigValuesValuesHolder = new
Holder<List<String>>();
        
    // the problematic call
    description.getDescription(typesHolder, refsHolder, ovfValuesHolder,
vboxValuesHolder, extraConfigValuesValuesHolder);

    System.out.println(typesHolder.value);
    System.out.println(refsHolder.value);
    System.out.println(ovfValuesHolder.value);
    System.out.println(vboxValuesHolder.value);
    System.out.println(extraConfigValuesValuesHolder.value);
}


The resulting stack trace:

Exception in thread "main" java.lang.AssertionError:
java.lang.NoSuchMethodException:
org.virtualbox_4_1.VirtualSystemDescriptionType.<init>(int)
        at org.virtualbox_4_1.xpcom.Helper.wrapEnum(Helper.java:101)
        at
org.virtualbox_4_1.IVirtualSystemDescription.getDescription(IVirtualSystemDescription.java:58)
        at
vdi.node.management.VirtualMachine.readDescription(VirtualMachine.java:229)
        at
vdi.node.management.VirtualMachine.importAppliance(VirtualMachine.java:213)
        at de.tud.cs.rbg.vdi.test.vbox.App.main(App.java:12)
Caused by: java.lang.NoSuchMethodException:
org.virtualbox_4_1.VirtualSystemDescriptionType.<init>(int)
        at java.lang.Class.getConstructor0(Class.java:2723)
        at java.lang.Class.getConstructor(Class.java:1674)
        at org.virtualbox_4_1.xpcom.Helper.wrapEnum(Helper.java:94)
        ... 4 more

To be clear, if I comment out the call to readDescription() the import
works fine. And if I use the GUI to import the ova, I can view and edit
the appliance settings.

I could not find the direct java sources for the API binding, but I
found the file src/VBox/Main/glue/glue-java.xsl in the current
VirtualBox sources, which contains the Helper class. I think the problem
is, that Helper.wrapEnum() tries to call a constructor on an enum type.
But in java enums are singletons.

There seems to be an static method fromValue(long) in all enum types of
the API. One solution could be, to use this static method instead of the
constructor.

Regards,
Matthias


P.S.:
my environment:
- Ubuntu 12.04 64bit
- VirtualBox 4.1.18


_______________________________________________
vbox-dev mailing list
[email protected]
https://www.virtualbox.org/mailman/listinfo/vbox-dev




--- glue-java_old.xsl	2012-06-20 15:17:32.000000000 +0200
+++ glue-java.xsl	2012-07-16 09:33:51.318518942 +0200
@@ -2595,6 +2595,7 @@
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 
 public class Helper {
     public static List<Short> wrap(byte[] vals) {
@@ -2655,16 +2656,16 @@
         try {
             if (values==null)
                  return null;
-            Constructor<T> c = wrapperClass.getConstructor(int.class);
+            Method m = wrapperClass.getMethod("fromValue", long.class);
             List<T> ret = new ArrayList<T>(values.length);
             for (long v : values) {
-                ret.add(c.newInstance(v));
+                @SuppressWarnings("unchecked")
+                T obj = (T) m.invoke(wrapperClass, v);
+                ret.add(obj);
             }
             return ret;
         } catch (NoSuchMethodException e) {
             throw new AssertionError(e);
-        } catch (InstantiationException e) {
-            throw new AssertionError(e);
         } catch (IllegalAccessException e) {
             throw new AssertionError(e);
         } catch (InvocationTargetException e) {

_______________________________________________
vbox-dev mailing list
[email protected]
https://www.virtualbox.org/mailman/listinfo/vbox-dev

Reply via email to